LlamaIndex 中的 LanceDB 多模态托管索引:LanceDBMultiModalIndex 全解析

LlamaIndex 中的 LanceDB 多模态托管索引:LanceDBMultiModalIndex 全解析
LlamaIndex 中的 LanceDB 多模态托管索引LanceDBMultiModalIndex 全解析【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index本文基于 LlamaIndex 仓库中的 LanceDB 托管索引 API 文档及其对应集成包源码完整讲解LanceDBMultiModalIndex这一核心类如何以本地目录或远程数据库 URI 建立文本与图像多模态向量索引、如何从Document/ImageDocument或 DataFrame 数据建索引、如何选择嵌入模型与索引策略以及如何通过配套的LanceDBRetriever与LanceDBRetrieverQueryEngine完成检索与问答。读完本文你可以直接复制代码在 LlamaIndex 应用中落地 LanceDB 的文本与图像检索。包的安装与定位该功能位于 LlamaIndex 的托管索引managed indices集成包中对应文档入口为 indices/lancedb.md包源码与说明位于 llama-index-indices-managed-lancedb。安装方式为pip install llama-index-indices-managed-lancedb从 pyproject.toml 可以看到其关键依赖与运行环境约束要求 Python3.10,4.0核心依赖包括lancedb0.24.0,1、pylance0.30.0,1、tantivy0.24.0,1、pyarrow20.0.0,21、polars1.31.0,2、llama-index-core0.13.0,0.15以及内置的open-clip-torch多模态嵌入与sentence-transformers文本嵌入。包的init.py 对外导出三个类LanceDBMultiModalIndex索引主体负责建连、建表、写入与删除LanceDBRetriever检索器支持文本与图像两种查询形态LanceDBRetrieverQueryEngine查询引擎在检索之上做响应合成。核心类LanceDBMultiModalIndex 的构造参数LanceDBMultiModalIndex继承自llama_index.core.indices.managed.base.BaseManagedIndex其构造函数见 base.py参数如下参数说明默认值connection直接传入已有的 LanceDBDBConnection/AsyncConnection对象需与use_async匹配同步连接配use_asyncFalse异步连接配True否则抛出断言错误Noneuri数据库地址。以db://开头走云端连接否则视为本地目录路径Noneregion云端实例区域仅在uri为db://时生效Noneapi_key云端实例 API Key也可通过环境变量LANCEDB_API_KEY提供Nonetext_embedding_model文本嵌入模型可选bedrock-text、cohere、gemini-text、instructor、ollama、openai、sentence-transformers、gte-text、huggingface、colbert、jina、watsonx、voyageaiNonemultimodal_embedding_model多模态嵌入模型可选open-clip、colpali、jina、imagebindNoneembedding_model_kwargs传给嵌入模型的初始化参数例如{name: all-MiniLM-L6-v2}{}table_nameLanceDB 表名default_tableindexing向量/标量索引策略可选IVF_PQ、IVF_HNSW_PQ、IVF_HNSW_SQ、FTS、BTREE、BITMAP、LABEL_LIST、NO_INDEXINGIVF_PQindexing_kwargs传给索引构建的额外参数{}rerankerLanceDB 的Reranker对象Noneuse_async是否使用异步连接与异步 API注意两者互斥详见后文Falsetable_exists为True时不新建表而是open_table打开已存在的表False两个关键约束来自源码的校验逻辑连接方式二选一构造函数要求要么传入connection要么给出uriuri以db://开头时构建CloudConnectionConfig否则构建LocalConnectionConfigbase.py 构造函数。嵌入模型二选一且互斥EmbeddingConfig的校验器utils.py要求必须且只能指定文本模型或多模态模型之一。此外从 utils.py 中的 CloudConnectionConfig 可以看出云端场景下若未显式传api_key会回退读取环境变量LANCEDB_API_KEY二者都缺失则抛出ValueError未指定region时默认为us-east-1。建索引create_index 的完整流程实例化后必须显式建索引即建立连接、创建表、构建向量索引。同步调用create_index()异步调用await acreate_index()。从 create_index 实现 看其内部流程为若已存在连接则直接返回若use_asyncTrue却调用同步方法或反之抛出ValueError本地 URI 调用lancedb.connect(uri...)云端则额外带上region与api_key根据指定的是文本模型还是多模态模型动态生成 Pydantic 表结构LanceModel文本表结构class TextSchema(LanceModel): id: str metadata: str # deserializableJSON 序列化的元数据 text: str # 嵌入模型的源字段SourceField vector: Vector # 向量列维度取自模型的 ndims()其中text字段标记为SourceField()由嵌入模型自动生成vector列向量维度自动取自self._embedding_model.embedding_model.ndims()无需手工指定。多模态表结构class MultiModalSchema(LanceModel): id: str metadata: str # deserializable label: str image_uri: str # 图像 URI作为嵌入源字段 image_bytes: bytes # 图像字节作为嵌入源字段 vector: Vector # 主向量列 vec_from_bytes: Vector # 另一向量列仅以 bytes 为源若table_existsFalse调用connection.create_table(table_name, schema...)建表并在indexing ! NO_INDEXING时执行table.create_index(index_type...)若table_existsTrue则open_table打开既有表并直接采用其 schema。异步路径acreate_index中索引创建会显式指定columnvectorbase.py。indexing参数对应 LanceDB 的索引类型。从 IndexingConfig 的校验器 可确认IVF_PQ映射为IvfPqIVF_HNSW_PQ/IVF_HNSW_SQ映射为HnswPq/HnswSqFTS、BTREE、BITMAP、LABEL_LIST分别映射到 LanceDB 的同名索引类型NO_INDEXING则不建任何索引。indexing_kwargs会透传给这些索引配置对象。文本索引实战本地与远程数据库的最小示例来自 包 READMEfrom llama_index.indices.managed.lancedb import LanceDBMultiModalIndex # 本地数据库 local_index LanceDBMultiModalIndex( urilancedb/data, text_embedding_modelsentence-transformers, embedding_model_kwargs{name: all-MiniLM-L6-v2}, table_namedocuments, ) # 云端远程连接 remote_index LanceDBMultiModalIndex( uridb://***, regionus-east-1, api_key***, text_embedding_modelsentence-transformers, embedding_model_kwargs{name: all-MiniLM-L6-v2}, table_nameremote_documents, )建索引同步/异步二选一# use_async True 时 async def connect_lancedb_index(): await documents_index.acreate_index() # use_async False默认时 local_index.create_index()从Document列表建索引from llama_index.core.schema import Document document_data [ Document(textThis is an example document), Document(textThis is an example document 1), ] documents_index await LanceDBMultiModalIndex.from_documents( documentsdocument_data, urilancedb/documents, text_embedding_modelsentence-transformers, embedding_model_kwargs{name: all-MiniLM-L6-v2}, table_namefrom_documents, indexingNO_INDEXING, use_asyncTrue, )from_documents的参数与构造函数完全一致base.py。对文本文档源码会逐条把Document转为{id, text, metadata}字典写入表中metadata以json.dumps序列化不含文本的文档会被跳过并触发UserWarning。同样可以用from_data直接写入 PyArrow Table、Pandas/Polars DataFrame 或字典列表base.py例如带预计算向量列的 DataFrameimport pandas as pd import numpy as np data pd.DataFrame( { text: [## Hello world, This is a test], id: [1, 2], metadata: [{type: text/markdown}, {type: text/plain}], vector: [ np.random.random(384).tolist(), np.random.random(384).tolist(), ], } ) data_index await LanceDBMultiModalIndex.from_data( datadata, urilancedb/documents, text_embedding_modelsentence-transformers, embedding_model_kwargs{name: all-MiniLM-L6-v2}, table_namefrom_data, indexingHNSW_PQ, use_asyncTrue, )需要强调的是文本表要求所有传入的Document均为纯文本Document源码中有assert all(isinstance(document, Document))多模态表则要求全部为ImageDocument。图像多模态索引实战多模态索引使用multimodal_embedding_model如open-clipfrom llama_index.core.schema import ImageDocument # 从 ImageDocument 列表初始化 images_index await LanceDBMultiModalIndex.from_documents( documents[ ImageDocument( image_urlhttp://farm1.staticflickr.com/53/167798175_7c7845bbbd_z.jpg, metadata{label: cat}, ), ImageDocument( image_urlhttp://farm1.staticflickr.com/134/332220238_da527d8140_z.jpg, metadata{label: cat}, ), ImageDocument( image_urlhttp://farm9.staticflickr.com/8387/8602747737_2e5c2a45d4_z.jpg, metadata{label: dog}, ), ], urilancedb/images, multimodal_embedding_modelopen-clip, table_nameimages, )也可以从包含id、label、image_uri、image_bytes、metadata列的 DataFrame 直接建索引from_data参见 README。从 from_documents 的图像分支源码 可以看出其取值优先级优先使用ImageDocument.image内存字节否则若有image_url用httpx.get拉取字节再否则若有image_path通过resolve_image().read()读取本地文件label取自metadata[image_label]缺省为空串三者都没有的图像文档会被跳过并告警。写入与删除索引建立后支持节点级与数据级写入# 从 Document 写入 local_index.insert_nodes( documents[ Document(textHello world, id_1), Document(textHow are you?, id_2), ], ) # 从数据写入 local_index.insert_data( datapd.DataFrame( { text: [Hello world, How are you?], id: [1, 2], metadata: [ {type: text/markdown}, {type: text/plain}, ], } ), ) # 按 id 删除 local_index.delete_nodes([1, 2])从源码看删除操作底层是 SQL 风格的where条件delete_nodes拼接id IN (1, 2)delete_ref_doc单条删除拼接id ...并对单引号做转义base.py。此外还有单文档写入便捷方法insert(document)及异步版ainsert、ainsert_nodes、ainsert_data、adelete_nodes、adelete_ref_doc。同步/异步互斥是本包最重要的使用约束use_asyncTrue时同步方法会抛出ValueError例如 insert_nodes 中检测到异步连接即报错反之亦然。另外update、update_ref_doc、refresh等BaseManagedIndex接口在该实现中抛出NotImplementedError尚不支持原地更新。检索与查询索引实例可通过as_retriever()与as_query_engine()派生出检索器与查询引擎。as_retriever会根据嵌入模型类型自动设置multimodal标志base.py指定了文本模型即为纯文本模式否则为多模态模式。文本检索retriever local_index.as_retriever() nodes retriever.retrieve(query_strHello world!) query_engine local_index.as_query_engine() response query_engine.query(query_strHello world!) print(response.response)图像检索LanceDBRetriever.retrieve与LanceDBRetrieverQueryEngine.query额外接受query_image与query_image_path两个参数retriever.py、query_engine.pyquery_engine images_index.as_query_engine() # query_image 可以是 URL 字符串、PIL Image、ImageBlock 或 ImageDocument response query_engine.query( query_imagehttp://farm6.staticflickr.com/5142/5835678453_4f3a4edb45_z.jpg ) # 也可以传本地路径 response query_engine.query( query_image_path/Users/user/images/hello_world.jpg )从 utils.py 的 query_multimodal 实现可以看到查询图片的解析规则ImageBlock/ImageDocument会resolve_image()成字节流再经 PIL 打开PIL.Image直接使用字符串则按 URL 用httpx.get下载后打开其他类型抛ValueError。检索结果统一映射为NodeWithScore文本表返回Document(text, id_)节点多模态表返回携带image_url、image_bytes与label元数据的ImageDocument分数取自 LanceDB 的_distance字段。查询引擎LanceDBRetrieverQueryEngine继承自RetrieverQueryEngine其_query方法在CBEventType.QUERY回调事件与 instrumentation dispatcher 的 span 内完成“检索 → 节点后处理 → 响应合成”的完整链路query_engine.py并会派发QueryStartEvent/QueryEndEvent事件因此在 LlamaIndex 的可观测性体系callbacks/instrumentation中可以直接追踪其查询行为。测试用例佐证包自带的 tests/test_index.py 覆盖了两条关键路径可作为正确用法的参考test_init验证了三种构造方式后的内部状态同步构造函数得到use_asyncFalse的连接配置from_documents(..., use_asyncTrue)得到AsyncConnectionAsyncTableLanceDBTextModelfrom_data(..., use_asyncFalse)得到DBConnectionTableLanceDBMultiModalModel。这印证了前文所述的同步/异步双轨设计。test_retriever_qe使用MockLLM完成端到端验证as_retriever()返回LanceDBRetrieveraretrieve(query_strHello)返回非空NodeWithScore列表as_query_engine()返回LanceDBRetrieverQueryEngineaquery返回带response字符串的结果。小结与使用要点LanceDBMultiModalIndex用同一个类覆盖了 LanceDB 的文本向量检索与图像多模态检索区别只在于指定text_embedding_model还是multimodal_embedding_model以及表 schema 自动随之切换嵌入模型由 LanceDB 自身的嵌入注册表get_registry()创建embedding_model_kwargs直接透传如{name: all-MiniLM-L6-v2}向量维度自动取模型ndims()无需手工对齐云端连接需要db://URI api_key或LANCEDB_API_KEY环境变量region缺省为us-east-1use_async一旦设定全链路建索引、写入、删除、检索都必须使用对应的a*异步方法混用会抛ValueError索引策略默认IVF_PQ小规模或测试场景可用NO_INDEXING跳过向量索引构建已存在表可复用table_existsTrue时直接open_table而不重建 schema。核心实现文件均可在仓库中查阅base.py、retriever.py、query_engine.py、utils.py完整示例见 集成包 README。【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

最新新闻

日新闻

周新闻

月新闻