5.5 LlamaIndex实战:文档加载、分块、嵌入与索引构建

1 阅读5分钟

5.5 LlamaIndex实战:文档加载、分块、嵌入与索引构建

一、LlamaIndex概述

LlamaIndex专注于数据索引与检索,与LangChain配合可快速构建RAG系统。支持PDF、TXT、Markdown等多种格式。


二、文档加载

from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader("./docs").load_data()

三、分块与嵌入

LlamaIndex默认按节点分块,可配置chunk_size、chunk_overlap等。嵌入使用OpenAI text-embedding-ada-002或自定义模型。


四、索引构建

from llama_index.core import VectorStoreIndex, Settings
from llama_index.embeddings.openai import OpenAIEmbedding

Settings.embed_model = OpenAIEmbedding(model="text-embedding-ada-002")
index = VectorStoreIndex.from_documents(documents)
index.storage_context.persist(persist_dir="./index")  # 持久化

五、支持的文档格式

格式加载器说明
PDFPyPDFReader需pypdf
TXT/MDSimpleDirectoryReader默认支持
WordDocxReader需python-docx
网页BeautifulSoupWebReader需beautifulsoup4

5.1 自定义加载器

可继承BaseReader实现自定义格式,实现load_data返回Document列表。


六、索引类型

类型说明
VectorStoreIndex向量检索,最常用
ListIndex顺序遍历,适合短文档
TreeIndex层级结构,适合长文档摘要

多数场景使用VectorStoreIndex即可。


六(代码示例)、分块与嵌入的代码配置

除默认分块外,可显式指定 NodeParser 与嵌入模型,便于与 5.4 节的分块参数对齐:

from llama_index.core import SimpleDirectoryReader, VectorStoreIndex, Settings
from llama_index.core.node_parser import SentenceSplitter
from llama_index.embeddings.openai import OpenAIEmbedding

Settings.embed_model = OpenAIEmbedding(model="text-embedding-ada-002")
parser = SentenceSplitter(chunk_size=512, chunk_overlap=50)
documents = SimpleDirectoryReader("./docs").load_data()
nodes = parser.get_nodes_from_documents(documents)
index = VectorStoreIndex.from_documents(documents)  # 或 from_nodes(nodes)

若已有一批 Node 且希望复用已有解析结果,可用 VectorStoreIndex.from_nodes(nodes)。嵌入维度需与后续检索时使用的 embed_model 一致,否则向量不可比。


七、与《大模型应用开发极简入门》5.3 节的对应

本书第5章「构建RAG系统」明确提到 LlamaIndex 实战文档加载、分块、嵌入、索引、检索、生成 完整流程,并给出企业知识库问答、文档智能检索的搭建思路。本节与之一一对应:文档加载对应「文档加载」;分块与嵌入对应「分块、嵌入」;索引构建与持久化对应「索引、检索」;下一节 RAG 检索+生成对应「生成」。书中代码模板中的 build_rag_indexrag_query 即基于 LlamaIndex,本节是理解与扩展该模板的基础。


八、分块策略详解

8.1 chunk_size 与 chunk_overlap

  • chunk_size:每块字符或 Token 数,常见 256–1024;过小则上下文碎片化,过大则单块超长、检索不精。
  • chunk_overlap:块间重叠长度,避免句子在边界被截断导致语义丢失。通常为 chunk_size 的 10%–20%。

8.2 按段落与按句子

可按段落、按固定长度或按语义(如句子)分块。LlamaIndex 支持多种 NodeParser,可按文档类型选择。

8.3 元数据保留

分块时可保留来源文件、页码、标题等元数据,检索结果返回时可展示来源,便于用户核实(与书中 RAG 来源标注一致)。


九、检索与查询流程

索引构建完成后,通过 index.as_query_engine() 创建查询引擎;用户问题会先转为向量,在索引中检索 Top-K 相似块,再将块与问题一起送入 LLM 生成答案。该流程与 5.4 节 RAG 原理一致,LlamaIndex 封装了检索与生成的衔接逻辑。


十、完整可运行示例(与书中 build_rag_index / rag_query 对应)

书中第 5 章代码模板给出了 build_rag_indexrag_query 的完整实现,以下为基于 LlamaIndex 的等价写法,便于对照与扩展:

"""
LlamaIndex RAG 完整示例(对应书中 build_rag_index、rag_query)
运行: pip install llama-index llama-index-llms-openai python-dotenv
将文档放入 ./docs 目录,配置 OPENAI_API_KEY
"""

import os
from dotenv import load_dotenv
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex, Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

load_dotenv()
Settings.llm = OpenAI(model="gpt-3.5-turbo", temperature=0.1)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-ada-002")

def build_rag_index(doc_dir: str = "./docs"):
    documents = SimpleDirectoryReader(doc_dir).load_data()
    index = VectorStoreIndex.from_documents(documents)
    index.storage_context.persist(persist_dir="./rag_index")
    return index

def rag_query(index, query: str):
    query_engine = index.as_query_engine(similarity_top_k=5)
    response = query_engine.query(query)
    return response.response

if __name__ == "__main__":
    index = build_rag_index()
    answer = rag_query(index, "文档中提到的核心概念有哪些?")
    print(answer)

与书中模板一致:先配置 LLM 与 Embedding(Settings),再加载文档、建索引、持久化;查询时创建 query_engine 并传入问题即可。similarity_top_k 对应 5.4 节的 Top-K 检索数量,通常 3–5 为宜。


十一、与 LangChain 的联合使用

在实际项目中,常采用 LlamaIndex 建索引 + LangChain 做编排:用 LlamaIndex 的 SimpleDirectoryReader、分块、VectorStoreIndex 完成文档到索引的流程,再通过 LangChain 的 LlamaIndex 集成(如 LlamaIndexRetriever)将检索结果接入 LangChain 的 Chain 或 Agent,实现「检索 → 拼进提示 → 调用 LLM → 输出」的完整 RAG 或 Agent 流程。书中 5.2、5.3 的链与 RAG 示例中,检索部分即可由 LlamaIndex 提供,本节是理解该联合使用方式的前提。


十三、文档格式与编码注意

加载 PDF、Word 等格式时,需安装对应依赖(如 pypdf、python-docx),并注意文件编码:中文文档建议统一为 UTF-8,避免乱码。若文档含大量表格或图片,LlamaIndex 的默认解析可能只提取文字,表格结构可能丢失,可考虑使用支持表格抽取的加载器或预处理步骤。索引持久化目录(如 persist_dir)需有写权限,且首次构建后若文档更新,需重新建索引或做增量更新(见 5.4 节),否则检索到的仍是旧内容。书中 5.3 节「构建 RAG 系统」中的「文档加载、分块、嵌入、索引」在本节已逐项展开,实现时按本节顺序配置即可。


十四、查询引擎参数与提示定制

as_query_engine() 可传入 similarity_top_k(检索条数)、response_mode(如 "compact" 或 "tree_summarize")等。若希望检索结果严格按「仅基于以下内容回答」生成,可在创建 index 时传入自定义的 PromptHelper 或在使用前通过 query_engine.update_prompts() 覆盖默认的 QA 模板,加入与 4.5 节防御性提示一致的「仅根据检索内容回答、无法确定时说明」等约束,与书中 RAG 提示设计保持一致。


十二、小结

LlamaIndex 简化了文档加载、分块、嵌入与索引的流程。掌握支持的格式、分块配置与索引类型,即可构建企业知识库 RAG 系统。下一节将介绍 AI Agent 与 ReAct 框架。建议先在本节用少量本地文档跑通「加载 → 分块 → 建索引 → 查询」全流程,再在 5.4 与 6.3 等节中接入业务提示与对话逻辑,形成完整知识库问答应用。


下一节预告:5.6 AI Agent智能体架构:ReAct框架与工具调用实现