资讯详情

资讯详情

LlamaIndex 索引(Indexing)模块深入指南:从 Document 到可检索数据结构的完整解析

LlamaIndex 索引Indexing模块深入指南从 Document 到可检索数据结构的完整解析【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_indexLlamaIndex 将Index索引定义为一种允许我们快速检索用户查询所需上下文的数据结构它是检索增强生成RAG用例的核心基础。本文以官方 Indexing 模块指南为主线结合llama-index-core源码实现系统讲解 Index 的概念与架构、各类索引Vector Store Index、Summary Index、Tree Index、Keyword Table Index、Property Graph Index的构建与查询原理以及索引的增删改刷新、持久化加载和 Query/Chat Engine 装配帮助你根据真实业务场景做出正确的索引选型与工程落地。Index 是什么RAG 检索的核心数据结构根据官方文档的定义Index是一种允许我们快速检索用户查询所需上下文的数据结构对于 LlamaIndex 而言它是检索增强生成RAG用例的核心基础。在高层次上索引由 Documents 构建并被用来搭建 Query Engines 和 Chat Engines从而实现对数据内容的问答与聊天。在底层Index 将数据存储在Node对象中Node 代表原始文档切分后的文本块并对外暴露一个支持额外配置与自动化的 Retriever 接口。从源码结构看llama_index.core.indices.base中的BaseIndex是所有索引类型的抽象基类它通过模板方法模式统一了从文档构建索引插入/删除/更新/刷新节点转换为 Retriever/Query Engine/Chat Engine等全套生命周期操作base.py。关键概念链条Document → Node → Index → Retriever这一条数据流是理解整个 Indexing 模块的钥匙Document原始数据载体如SimpleDirectoryReader加载的文件。NodeDocument 经解析/切分chunking后得到的文本块携带元数据metadata与节点间关系。Index对 Nodes 进行组织的数据结构列表、向量表、树、关键词表、属性图等。RetrieverIndex 暴露的检索接口负责在查询时取回最相关的 Node 集合。构建索引的两种入口from_documents与构造函数BaseIndex.from_documents是文档驱动的标准入口。从源码看它内部会先将每个文档的哈希写入 docstore用于后续的 refresh 增量更新判断再调用run_transformations把 Documents 通过变换管线默认是文本切分转换为 Nodes最后调用索引构造函数完成构建base.pyfrom llama_index.core import VectorStoreIndex, SimpleDirectoryReader documents SimpleDirectoryReader( ../../examples/data/paul_graham ).load_data() index VectorStoreIndex.from_documents(documents)需要特别注意的是构造函数本身只接受Node 对象列表。源码中有显式校验如果传入的是Document列表会直接抛出ValueError提示构造函数现在接收 Node 列表若要传入 Document 请使用from_documentsbase.py。因此两种入口的适用场景是入口输入适用场景Index.from_documents(documents)原始文档列表快速起步默认切分逻辑Index(nodes)手动构造的 Node 列表需要完全控制切分、元数据与节点关系索引类型全景内置 10 种索引llama-index-core中的索引注册表INDEX_STRUCT_TYPE_TO_INDEX_CLASS定义了全部内置索引类型registry.py索引类型类索引结构特点VectorStoreIndex向量存储索引为每个 Node 生成 embedding 并存入向量库按相似度检索SummaryIndex原 List Index顺序链式列表将 Nodes 存为顺序链TreeIndex层次化树从 Nodes 构建层级树叶子节点自根向下遍历KeywordTableIndex关键词表提取关键词并建立关键词到 Nodes 的映射PropertyGraphIndex属性图LPG构建带标签节点与关系的知识图谱KnowledgeGraphIndex知识图谱基于三元组的知识图谱索引SQLStructStoreIndexSQL 结构化索引面向结构化 SQL 查询PandasIndexPandas 数据框索引面向表格数据分析DocumentSummaryIndex文档摘要索引为每个文档建立摘要并检索MultiModalVectorStoreIndex多模态向量索引同时支持文本与图像节点EmptyIndex空索引无存储结构的占位索引其中VectorStoreIndex是目前使用最广泛的索引官方文档也明确推荐从 VectorStoreIndex 使用指南 开始学习。更多索引类型的完整清单可参见 modules.md。VectorStoreIndex 深度实践最常用的 RAG 索引向量存储是 RAG 的关键组件因此你在几乎每个 LlamaIndex 应用中都会直接或间接用到它。向量存储接收一组Node对象并基于它们构建索引。下面按官方指南的脉络从数据加载、自定义构建到存储与组合检索逐步展开。方式一from_documents快速构建最简单的用法是加载文档集合并通过from_documents构建索引vector_store_index.mdxfrom llama_index.core import VectorStoreIndex, SimpleDirectoryReader documents SimpleDirectoryReader( ../../examples/data/paul_graham ).load_data() index VectorStoreIndex.from_documents(documents)使用from_documents时你的 Documents 会被切分并解析为Node对象——它们是文本字符串上的轻量抽象同时跟踪元数据与节点间关系。两个实用提示在命令行中构建索引时可传入show_progressTrue显示进度条。默认情况下VectorStoreIndex会以2048 个节点为一批批量生成并插入向量。如果内存受限或内存充裕可以通过insert_batch_size参数调整批大小这在向远端托管的向量数据库插入时尤其有用vector_store/base.py。从源码看批量插入逻辑位于_add_nodes_to_index先用embed_nodes分批计算 embedding再调用vector_store.add()写入若向量库本身不存储文本stores_textFalse还会将去 embedding 后的 Node 同步进 docstore 与 index_struct保证后续能按ref_doc_id追溯原始文档vector_store/base.py。方式二使用 Ingestion Pipeline 精细控制如果想对文档如何被索引拥有更多控制权官方推荐使用 ingestion pipeline它允许自定义切分chunking、元数据与 embeddingvector_store_index.mdxfrom llama_index.core import Document from llama_index.embeddings.openai import OpenAIEmbedding from llama_index.core.node_parser import SentenceSplitter from llama_index.core.extractors import TitleExtractor from llama_index.core.ingestion import IngestionPipeline, IngestionCache pipeline IngestionPipeline( transformations[ SentenceSplitter(chunk_size25, chunk_overlap0), TitleExtractor(), OpenAIEmbedding(), ] ) nodes pipeline.run(documents[Document.example()])这里的SentenceSplitter(chunk_size25, chunk_overlap0)定义了文本切分粒度与重叠窗口TitleExtractor负责抽取标题元数据OpenAIEmbedding负责向量化——管线产出的nodes可直接喂给索引构造函数。方式三手动创建与管理 Node如果你希望完全掌控索引可以手动创建TextNode并直接传给索引构造函数vector_store_index.mdxfrom llama_index.core.schema import TextNode node1 TextNode(texttext_chunk, id_node_id) node2 TextNode(texttext_chunk, id_node_id) nodes [node1, node2] index VectorStoreIndex(nodes)当数据源随时间变化时Index类还提供插入insertion、删除deletion、更新update、刷新refresh四类操作详见后文文档管理章节及 document_management.md、metadata_extraction.md。存储从内存到持久化向量库默认情况下VectorStoreIndex将一切保存在内存中。LlamaIndex 支持数十种向量存储通过传入StorageContext并指定vector_store参数即可切换到持久化后端vector_store_index.mdximport pinecone from llama_index.core import ( VectorStoreIndex, SimpleDirectoryReader, StorageContext, ) from llama_index.vector_stores.pinecone import PineconeVectorStore pinecone.init(api_keyapi_key, environmentenvironment) pinecone.create_index( quickstart, dimension1536, metriceuclidean, pod_typep1 ) storage_context StorageContext.from_defaults( vector_storePineconeVectorStore(pinecone.Index(quickstart)) ) documents SimpleDirectoryReader( ../../examples/data/paul_graham ).load_data() index VectorStoreIndex.from_documents( documents, storage_contextstorage_context )对应的向量库实现均位于llama-index-integrations/vector_stores/目录下如llama-index-vector-stores-pinecone各集成包的用法示例可参考 vector_store_guide.ipynb。组合式检索Composable RetrievalVectorStoreIndex以及任何索引/检索器都具备检索通用对象的能力包括节点引用references to nodes查询引擎query engines检索器retrievers查询管线query pipelines当这些对象被检索到时它们会自动使用提供的查询语句执行vector_store_index.mdxfrom llama_index.core.schema import IndexNode query_engine other_index.as_query_engine obj IndexNode( textA query engine describing X, Y, and Z., objquery_engine, index_idmy_query_engine, ) index VectorStoreIndex(nodesnodes, objects[obj]) retriever index.as_retriever(verboseTrue)如果包含该查询引擎的 IndexNode 被检索命中查询引擎会被自动执行其结果作为节点返回。源码中BaseIndex通过_object_map维护index_id → 对象的映射并在序列化前将obj置空以避免序列化问题base.py。各类索引的工作原理与查询流程index_guide.md系统讲解了各索引类型的构建与查询机制index_guide.md。核心术语Node对应 Document 中的文本块Response Synthesis负责根据检索到的 Node 合成回答。Vector Store Index向量存储索引将每个 Node 及其对应的 embedding 存储在向量存储中其构建流程如下图所示查询时它会获取最相似的 top-k 个 Node并将其传入 Response Synthesis 模块合成答案Summary Index原 List Index摘要索引将 Nodes 存储为顺序链这是最简单的索引结构查询时如果未指定其他查询参数LlamaIndex 会把列表中的所有 Nodes 全部加载进 Response Synthesis 模块。它同时支持多种查询方式基于 embedding 的查询取回 top-k 近邻、叠加关键词过滤器、或基于 LLM 的查询——对应源码中SummaryIndex.as_retriever的三种模式ListRetrieverMode.DEFAULT / EMBEDDING / LLMlist/base.py。Tree Index树索引从一组 Nodes 构建层次树这些 Nodes 成为树的叶子节点查询树索引时从根节点向下遍历到叶子节点。默认情况下child_branch_factor1查询在给定父节点时只选择一个子节点若child_branch_factor2则每层选择两个子节点。对应的检索器实现位于llama-index-core/llama_index/core/indices/tree/目录含select_leaf_retriever.py、tree_root_retriever.py、all_leaf_retriever.py等。Keyword Table Index关键词表索引从每个 Node 中提取关键词并建立关键词 → 对应 Nodes的映射查询时从查询语句中提取相关关键词与预提取的 Node 关键词匹配取回对应 Nodes 后交给 Response Synthesis 模块。其实现位于llama-index-core/llama_index/core/indices/keyword_table/支持简单关键词提取simple_base.py与 RAKE 算法rake_base.py两种底层提取策略。Property Graph Index属性图索引通过首先构建包含带标签节点与关系的知识图谱来工作其构建过程高度可定制从让 LLM 自由抽取到按严格 schema 抽取甚至实现你自己的抽取模块。可选项包括为节点生成 embedding 以便后续向量检索也可以跳过图构建直接通过 Neo4j 等集成连接已有知识图谱。查询属性图索引同样高度灵活检索通过多个子检索器组合结果实现。默认使用关键词 同义词扩展以及在图谱已嵌入时的向量检索来取回相关三元组还可以选择在检索结果中包含源文本对于在 LlamaIndex 之外创建的图谱则不可用。完整的子检索器与变换器实现参见 llama-index-core/llama_index/core/indices/property_graph/深入指南见 lpg_index_guide.md。文档管理索引的插入、删除、更新与刷新大多数 LlamaIndex 索引结构都支持insertion、deletion、update、refresh四类操作document_management.md。这些操作在BaseIndex中均有同步与异步a前缀两套实现base.py。插入Insertion构建索引后可以随时将新 Document 插入任意索引结构该文档会被切分为 Nodes 并摄入索引。底层机制取决于索引类型对 Summary Index新 Document 作为额外节点追加进列表对 Vector Store Index新 Document及其 embeddings被插入底层文档/向量存储from llama_index.core import SummaryIndex, Document index SummaryIndex([]) text_chunks [text_chunk_1, text_chunk_2, text_chunk_3] doc_chunks [] for i, text in enumerate(text_chunks): doc Document(texttext, id_fdoc_id_{i}) doc_chunks.append(doc) for doc_chunk in doc_chunks: index.insert(doc_chunk)从源码看insert(document)会先对文档执行变换管线生成 Nodes然后调用insert_nodes写入 docstore 与索引结构并记录文档哈希base.py。删除Deletion通过指定document_id即可从大多数索引结构中删除 Document注意Tree Index 当前不支持删除该文档对应的所有节点都会被删除index.delete_ref_doc(doc_id_0, delete_from_docstoreTrue)delete_from_docstore默认为False——当你使用同一个 docstore 在多个索引间共享节点时节点会被从索引的index_struct中移除index_struct记录了可用于查询的节点从而在查询时不再使用True则会进一步清理 docstore。从源码看delete_ref_doc通过 docstore 中的RefDocInfo找到该文档的所有node_ids再逐个删除base.py。更新Update如果某个 Document 已存在于索引中可以通过相同id_更新它例如文档内容发生变化时doc_chunks[0].text Brand new document text index.update_ref_doc(doc_chunks[0])源码实现update_ref_doc本质上等价于先删除、再插入先以delete_from_docstoreTrue删除旧文档及其节点再重新插入新文档base.py。刷新Refresh如果加载数据时为每个文档设置了id_可以自动刷新索引。refresh()只会更新相同id_但文本内容不同的文档完全不在索引中的文档也会被插入。它返回一个布尔列表指示输入文档中哪些已被刷新doc_chunks[0] Document(textSuper new document text, id_doc_id_0) doc_chunks.append( Document( textThis isnt in the index yet, but it will be soon!, id_doc_id_3, ) ) refreshed_docs index.refresh_ref_docs(doc_chunks) # refreshed_docs[0] 和 refreshed_docs[-1] 应为 True print(refreshed_docs) # [True, False, False, True]这一功能最适合目录不断更新新信息的场景。其原理是利用from_documents时写入 docstore 的文档哈希refresh_ref_docs逐个比较existing_doc_hash与document.hash——哈希不存在则插入、哈希不一致则更新base.py。若使用SimpleDirectoryReader可设置filename_as_id标志自动为文档设置id_。文档追踪Document Tracking任何使用 docstore 的索引即除大多数向量存储集成之外的所有索引都可以查看已摄入的文档print(index.ref_doc_info) # {doc_id_1: RefDocInfo(node_ids[071a66a8-3c47-49ad-84fa-7010c6277479], metadata{}), # doc_id_2: RefDocInfo(node_ids[9563e84b-f934-41c3-acfd-22e88492c869], metadata{}), # doc_id_0: RefDocInfo(node_ids[b53e6c2f-16f7-4024-af4c-42890e945f36], metadata{}), # doc_id_3: RefDocInfo(node_ids[6bedb29f-15db-4c7c-9885-7490e10aa33f], metadata{})}输出以摄入文档的id_为键值为其切分后对应的node_ids列表同时保留每个输入文档的原始metadata字典。索引的持久化与重新加载索引构建后可通过StorageContext持久化并通过load_index_from_storage重新加载。源码实现从 index store 读取IndexStruct依据其类型从注册表反查出对应索引类并重建实例loading.pyfrom llama_index.core import StorageContext, load_index_from_storage storage_context StorageContext.from_defaults(persist_dir./storage) index load_index_from_storage(storage_context)若 index store 中存在多个索引需显式传入index_id否则会因无法确定加载目标而抛出ValueError。从索引到 Retriever、Query Engine 与 Chat Engine索引的最终目的是支撑检索与生成。BaseIndex提供三个标准转换入口base.pyas_retriever(**kwargs)返回BaseRetriever。以VectorStoreIndex为例它返回VectorIndexRetriever并注入索引结构中的全部节点 ID 与对象映射vector_store/base.py。as_query_engine(llmNone, **kwargs)内部先调用as_retriever获取检索器再包装为RetrieverQueryEngine将检索与响应合成串联起来实现基于你的数据问答。as_chat_engine(chat_mode..., **kwargs)在查询引擎基础上包装多轮对话能力。支持ChatMode.BEST默认使用带查询引擎工具的 Agent、CONTEXT检索上下文、CONDENSE_QUESTION问题压缩、CONDENSE_PLUS_CONTEXT、SIMPLE等模式。小结如何选择合适的索引官方文档给出了明确的选型指引modules.md通用 RAG 场景首选VectorStoreIndex语义相似度检索 向量数据库持久化生态支持最完善。文档级摘要检索SummaryIndex适合需要遍历/汇总全部内容的场景或DocumentSummaryIndex做文档粒度摘要。层级化推理TreeIndex适合需要自顶向下逐层筛选的查询。关键词精确匹配KeywordTableIndex适合关键词驱动、对语义向量不敏感的场景。实体与关系推理PropertyGraphIndex/KnowledgeGraphIndex适合知识图谱类应用支持 LLM 抽取、严格 schema 或自定义抽取模块并能对接 Neo4j 等已有图谱。结构化数据SQLStructStoreIndex、PandasIndex面向数据库与表格分析。完整的模块索引与示例入口可参考 modules.md各索引的构建与查询图示汇总于 index_guide.md而所有索引类型的统一生命周期实现可深入阅读 llama-index-core/llama_index/core/indices/ 下的源码。【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →