【学习记录】LlamaIndex 核心模块详解:从数据连接到智能代理,构建生产级 RAG 系统
LlamaIndex 是当前最流行的 RAG(检索增强生成)框架之一。本文系统梳理了它的四大核心模块:数据连接器、数据索引、查询引擎、数据代理,并提供了大量代码示例、策略对比和实战经验。读完这篇,你就能独立搭建一套完整的 RAG 应用。
📌 为什么需要 LlamaIndex?
RAG 的本质是:先检索相关文档片段,再让 LLM 基于这些片段生成答案。传统做法需要自己处理文档加载、文本切分、向量化、存储、检索、Prompt 组装......重复且易错。
LlamaIndex 将这些步骤抽象为四个可插拔的模块,让你专注于业务逻辑而非底层胶水代码。
一、Data Connectors(数据连接器)
职责 :从各种数据源读取原始数据,转换成统一的 Document 对象(包含文本和元数据)。
1. 本地文件
python
from llama_index.core import SimpleDirectoryReader
# 读取整个目录(支持 .txt, .pdf, .csv, .md, .json 等)
documents = SimpleDirectoryReader(input_dir="./data", recursive=True).load_data()
# 只读取 PDF
documents = SimpleDirectoryReader(input_dir="./data", required_exts=[".pdf"]).load_data()
2. 数据库(自然语言查询 SQL)
python
from llama_index.core import SQLDatabase
from sqlalchemy import create_engine
engine = create_engine("postgresql://user:pass@localhost/db")
sql_database = SQLDatabase(engine)
# 后续可使用 NLSQLTableQueryEngine 直接写自然语言查询
3. Web 爬取
python
from llama_index.readers.web import BeautifulSoupWebReader
reader = BeautifulSoupWebReader()
documents = reader.load_data(urls=["https://example.com"])
4. API 数据
python
import requests
from llama_index.core import Document
response = requests.get("https://api.example.com/data")
doc = Document(text=response.text, metadata={"source": "api"})
5. Llama Hub(官方集成中心)
提供上百种现成连接器(Notion、Google Drive、Slack、Twitter 等)。
python
from llama_index.core import download_loader
GoogleDocsReader = download_loader("GoogleDocsReader")
loader = GoogleDocsReader()
documents = loader.load_data(document_ids=["..."])
6. Llama Cloud(高级 PDF 解析)
尤其擅长扫描件、表格、多栏、跨页表格 等复杂 PDF。使用前需安装 llama-parse。
python
from llama_parse import LlamaParse
parser = LlamaParse(api_key="your_key", result_type="markdown")
documents = parser.load_data("./paper.pdf")
| PDF 痛点 | LlamaIndex / LlamaParse 处理方式 |
|---|---|
| OCR 识别图片文字 | LlamaParse 云端自动 OCR;本地可用 PDFReader + pytesseract |
| 图表提取 | 解析为 Markdown 表格或结构化文本 |
| 跨越断行(hyphenation) | 自动合并被连字符分割的单词 |
| 多栏文本 | 按阅读顺序重组,而非简单按坐标切分 |
| 表格跨页 | 自动拼接跨页表格 |
本地简易 PDF 读取:
python
from llama_index.readers.file import PDFReader
loader = PDFReader()
documents = loader.load_data(file=open("doc.pdf", "rb"))
二、Data Indexes(数据索引模块)
职责 :将 Document 列表转换为可检索的向量索引。核心三步:文本切分 → 向量化 → 存储到向量数据库。
1. 文本切分策略(Node Parser)
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 固定长度 | 按字符/token 数切分,可设置重叠(chunk_overlap) |
通用,简单高效 |
| 段落 | 按 \n\n 切分 |
文章、报告 |
| 滑动窗口 | 相邻 chunk 包含重叠内容 | 防止信息割裂 |
| 语义切分 | 使用嵌入模型计算相邻句子相似度,低相似处切分 | 技术文档、法律条文 |
| 实体关系保留 | 尽量不切断命名实体(如"机器学习") | 中文、专有名词多的文本 |
代码示例:
python
from llama_index.core.node_parser import SimpleNodeParser
from llama_index.core import Settings
parser = SimpleNodeParser.from_defaults(
chunk_size=512, # 每个 chunk 最大字符数
chunk_overlap=20 # 相邻 chunk 重叠字符数
)
nodes = parser.get_nodes_from_documents(documents)
2. 模型设置
LlamaIndex 需要两个模型:嵌入模型 (将文本转为向量)和 LLM(生成答案)。
python
from llama_index.core import Settings
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.openai import OpenAI
# 嵌入模型(本地运行,免费)
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")
# LLM(可换为本地模型如 Ollama 或 Cloud API)
Settings.llm = OpenAI(model="gpt-3.5-turbo", temperature=0.1)
3. 向量数据库设置
支持 FAISS、Chroma、Pinecone、Weaviate 等。以 FAISS 为例:
python
from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.faiss import FaissVectorStore
import faiss
# FAISS 索引维度必须与嵌入模型输出维度一致(bge-small-en-v1.5 为 384)
faiss_index = faiss.IndexFlatL2(384)
vector_store = FaissVectorStore(faiss_index=faiss_index)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# 构建索引
index = VectorStoreIndex.from_documents(
documents, storage_context=storage_context
)
# 创建检索器(只返回节点,不生成答案)
retriever = index.as_retriever(similarity_top_k=3)
retrieved_nodes = retriever.retrieve("你的问题")
for node in retrieved_nodes:
print(node.text[:100], node.score)
4. 查询引擎与检索器的区别
index.as_query_engine():检索 + 生成,直接返回答案。index.as_retriever():只返回检索到的节点,便于调试或自定义 Prompt。
三、Engines(查询引擎)
职责:接收问题 → 执行检索 → 将检索结果与问题一起提交给 LLM → 返回答案。
1. Query Routing(查询路由)
根据问题类型分发到不同子引擎(如政策文档引擎 vs 福利文档引擎)。
python
from llama_index.core.tools import QueryEngineTool
from llama_index.core.query_engine import RouterQueryEngine
tool1 = QueryEngineTool.from_defaults(query_engine=engine1, name="policy", description="公司政策")
tool2 = QueryEngineTool.from_defaults(query_engine=engine2, name="benefits", description="员工福利")
router = RouterQueryEngine.from_defaults(tools=[tool1, tool2])
response = router.query("年假怎么计算?")
2. Query Rewriting(查询重写)
将用户原始问题改写成更适合检索的形式。例如:"它什么时候发布?" → "iPhone 15 发布日期"。
3. Query Planning(查询规划)
对于多步骤复杂问题,自动拆解并按序查询。例如:"比较去年和今年的销售额" → 先查去年,再查今年,最后比较。
4. 自定义回答格式 -- chat_engine
支持对话历史,实现多轮聊天。
python
chat_engine = index.as_chat_engine()
response = chat_engine.chat("介绍一下自己")
print(response)
# 流式输出
response = chat_engine.stream_chat("那你的优点呢?")
for token in response.response_gen:
print(token, end="")
5. summary_index(全文摘要)
对整个文档集合进行摘要生成,而非按片段检索。
python
from llama_index.core.indices.summary import SummaryIndex
summary_index = SummaryIndex.from_documents(documents)
summary_engine = summary_index.as_query_engine()
summary = summary_engine.query("总结这篇文章")
四、Data Agents(数据代理)
Agent 是比 Query Engine 更智能的实体,它可以使用多个工具,并自主决定调用顺序。
1. 将 query_engine 包装为工具
python
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core.agent import ReActAgent
tool = QueryEngineTool(
query_engine=index.as_query_engine(),
metadata=ToolMetadata(name="search_docs", description="在文档中搜索信息")
)
agent = ReActAgent.from_tools([tool], llm=Settings.llm)
response = agent.chat("总结文档中关于深度学习的部分")
2. predict_and_call(自动工具选择)
Agent 可以根据用户需求自动选择并调用合适的工具。例如:用户问"天气如何,然后发邮件给老板",Agent 会依次调用天气查询和邮件发送工具。
python
# 假设已定义 weather_tool, email_tool, search_tool
agent = ReActAgent.from_tools([weather_tool, email_tool, search_tool])
agent.chat("今天北京天气怎么样?顺便把这个信息发给 boss@example.com")
Agent 的工作流程
- 解析用户意图
- 规划步骤(选择工具及顺序)
- 执行工具并获取结果
- 综合结果并生成最终回答
🎯 总结对照表
| 模块 | 核心职责 | 常用类/方法 |
|---|---|---|
| Data Connectors | 从各种源读取数据 → Document |
SimpleDirectoryReader, LlamaParse, 各类 Reader |
| Data Indexes | 切分、向量化、存储 | NodeParser, Settings.embed_model, VectorStoreIndex, FaissVectorStore |
| Engines | 检索 + 生成答案 | as_query_engine(), as_chat_engine(), RouterQueryEngine |
| Data Agents | 多工具自主决策 | ReActAgent, OpenAIAgent, QueryEngineTool |
💡 学习心得
LlamaIndex 的设计哲学是 "每个环节都可插拔、可定制"。不需要从零搭建 RAG 流水线,只需要根据数据源、检索策略、生成模型去替换对应的组件。
- 起步阶段 :直接用
SimpleDirectoryReader+VectorStoreIndex+as_query_engine()就能跑通。 - 优化阶段:调整切分策略(语义切分)、换用更好的嵌入模型、加入路由或重写。
- 进阶阶段:构建 Agent,让系统自主调用多个工具,完成复杂任务。