第 7 篇:LlamaIndex 实现 RAG——专为 RAG 而生的框架实战

本文为「从零到落地:RAG 检索增强生成实战系列」第 7 篇,完整系列持续更新中。


前言

本篇聚焦 LlamaIndex 完整实战,从核心概念到基础 RAG、进阶配置(混合检索 + Rerank)、多轮对话、Agent 工具调用,全部代码逐行讲解。末尾与 LangGraph 做框架选型对比,帮你决定下一个项目该用谁。

在第 6 篇里,你用 LangGraph 的状态机搭建了一个可深度定制的 RAG 流程——条件路由、Query 改写、Agent 融合,灵活度拉满。但你可能也感受到了:写一个基础 RAG 就要定义 State、写节点函数、配置边,代码量不少。 如果你只是想快速搭一个”文档问答”应用,LangGraph 的流程编排有点”杀鸡用牛刀”。

LlamaIndex 就是为这种场景而生的。

LlamaIndex 是一个专门为 RAG 设计的主流框架,API 极其简洁——4 行代码就能跑通一个完整的 RAG 系统。它把文档加载、节点切分、索引构建、查询引擎全部封装好了,同时保留了充分的自定义空间:自定义分块策略、混合检索、Reranker、多轮对话、Agent 工具调用,想深入随时可以深入。

本篇学完你将掌握

  • LlamaIndex 的核心概念:Documents、Nodes、Index、QueryEngine、ChatEngine
  • 4 行代码搭建基础 RAG,然后逐层拆解理解原理
  • 自定义分块策略:SentenceSplitter、按语义分块
  • 混合检索(向量 + BM25)+ Reranker 提升检索精度
  • ChatEngine 多轮对话 RAG
  • Agent 工具调用 + 结构化数据查询(CSV/SQL)
  • LlamaIndex vs LangGraph 框架选型对比

一、LlamaIndex 是什么

1.1 核心定位

LlamaIndex(原名 GPT Index)是一个专注于数据连接和 RAG 的开源框架。它的核心目标是:让你用自己的数据和大模型对话,而不需要关心底层的数据管道细节。

和前面几篇工具的对比:

工具 定位 一句话概括
原生 Python(第 4 篇) 教学向,理解底层 每一步手写,知道框架在封装什么
Dify(第 5 篇) 低代码平台,快速上线 点鼠标搞定,但深度定制受限
LangGraph(第 6 篇) 状态机编排,深度定制 流程自由度最高,但代码量也最多
LlamaIndex(本篇) RAG 专用框架,开箱即用 API 最简洁,RAG 场景效率最高

1.2 五个核心概念

LlamaIndex 的 RAG 管道由五个核心概念构成:

概念 说明 类比
Documents 原始文档对象,包含文本和元数据 一本书
Nodes 文档切分后的最小单元,是索引和检索的基本单位 书里的每一段
Index 数据索引结构,存储 Nodes 的向量和组织方式 书的目录和索引
QueryEngine 查询引擎,处理”提问 → 检索 → 生成回答”的完整流程 帮你翻书找答案的助手
ChatEngine 在 QueryEngine 基础上加入对话记忆,支持多轮对话 能记住上下文的助手
1
2
3
4
5
6
7
Documents(原始文档)
↓ NodeParser(切分)
Nodes(文本块)
↓ Embedding(向量化)
Index(向量索引)
↓ Retriever(检索)
QueryEngine / ChatEngine(查询 + 生成)

💡 提示:和 LangGraph 的”状态-节点-边”范式不同,LlamaIndex 是管道式的——数据从文档流入,经过切分、索引、检索,最终输出回答。你只需要配置每个环节的参数,不需要手写流程编排代码。


二、环境准备

2.1 技术栈

组件 选择 理由
Python 3.11 系列统一版本
RAG 框架 LlamaIndex RAG 专用,API 最简洁
LLM DeepSeek API 性价比最高,兼容 OpenAI SDK
Embedding 模型 bge-large-zh-v1.5(本地) 中文效果最好的开源模型
向量数据库 Chroma 零配置启动,与 LlamaIndex 深度集成

2.2 安装依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建虚拟环境
python -m venv llamaindex-rag
llamaindex-rag\Scripts\activate # Windows

# 核心依赖
pip install llama-index
pip install llama-index-llms-openai-like
pip install llama-index-embeddings-huggingface
pip install llama-index-vector-stores-chroma
pip install llama-index-postprocessor-flag-embedding-reranker # Reranker(可选)

# 文档加载扩展(按需安装)
pip install llama-index-readers-file # PDF、Word 等文件格式

💡 提示:LlamaIndex 采用模块化设计,核心包 llama-index 包含基础功能,LLM 接入、Embedding 模型、向量库等通过独立的集成包安装。这样做的好处是不会安装你用不到的依赖。

2.3 准备测试文档

复用系列统一的测试文档 docs/company_faq.md(内容与第 4 篇相同)。


三、4 行代码搭建基础 RAG

LlamaIndex 最让人惊艳的地方就是:一个完整的 RAG 系统,4 行代码就能跑通。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.llms.openai_like import OpenAILike
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

# 1. 配置 LLM 和 Embedding
llm = OpenAILike(model="deepseek-chat", api_base="https://api.deepseek.com/v1",
api_key="sk-xxx", is_chat_model=True)
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-large-zh-v1.5")

# 2. 加载文档并构建索引(自动完成:读取 → 切分 → 向量化 → 存储)
documents = SimpleDirectoryReader("docs").load_data()
index = VectorStoreIndex.from_documents(documents, embed_model=embed_model)

# 3. 创建查询引擎
query_engine = index.as_query_engine(llm=llm, similarity_top_k=3)

# 4. 提问
response = query_engine.query("公司年假有几天?")
print(response)

运行结果:

1
2
3
4
5
根据公司年假制度:
- 入职满一年:5 天带薪年假
- 入职满三年:8 天带薪年假
- 入职满五年:10 天带薪年假
年假需提前 3 天在 OA 系统提交申请,由直属领导审批。

4 行核心代码就完成了加载文档 → 切分 → 向量化 → 构建索引 → 检索 → 生成回答的全流程。这就是 LlamaIndex 的效率——它把所有 RAG 管道的环节都封装好了,你只需要关注”问什么”和”怎么答”。

核心价值:这 4 行代码背后,LlamaIndex 自动完成了:①用 SimpleDirectoryReader 读取目录下所有文档;②用默认的 SentenceSplitter 按句子边界切分文本;③用 bge-large-zh-v1.5 生成向量;④构建 VectorStoreIndex(内存模式);⑤用 Top-K 向量检索找到最相关的文本块;⑥拼接 Prompt 调用 DeepSeek 生成回答。


四、核心概念深入理解

4 行代码跑通了,但要调优效果,你需要理解每个环节在做什么。下面逐层拆解。

4.1 Documents:原始文档对象

1
2
3
4
5
6
7
8
9
10
from llama_index.core import SimpleDirectoryReader

# 加载目录下所有文档
documents = SimpleDirectoryReader("docs").load_data()

# 查看文档内容
for doc in documents:
print(f"文本长度: {len(doc.text)} 字符")
print(f"元数据: {doc.metadata}") # 文件名、创建时间等
print(f"前 100 字: {doc.text[:100]}...")

SimpleDirectoryReader 自动识别文件格式(.txt、.md、.pdf、.docx 等),每个文件生成一个 Document 对象,包含文本内容和元数据(文件名、路径等)。

4.2 Nodes:切分后的最小单元

1
2
3
4
5
6
7
8
9
10
11
from llama_index.core.node_parser import SentenceSplitter

# 使用句子分割器切分文档
splitter = SentenceSplitter(chunk_size=300, chunk_overlap=50)
nodes = splitter.get_nodes_from_documents(documents)

print(f"共切分为 {len(nodes)} 个节点")
for i, node in enumerate(nodes[:3]):
print(f"\n--- Node {i+1} ---")
print(f"文本: {node.text[:80]}...")
print(f"来源: {node.metadata.get('file_name', '未知')}")

Node 是 LlamaIndex 的核心概念——索引和检索的最小单元。每个 Node 包含:

属性 说明
text 文本内容
embedding 向量(构建索引时自动生成)
metadata 元数据(来源文件、页码等)
relationships 与其他 Node 的关系(如父子关系)

4.3 Index:向量索引

1
2
3
4
5
6
7
8
9
10
from llama_index.core import VectorStoreIndex, Settings

# 设置全局默认配置
Settings.embed_model = embed_model
Settings.llm = llm
Settings.chunk_size = 300
Settings.chunk_overlap = 50

# 从 Nodes 构建索引
index = VectorStoreIndex(nodes)

VectorStoreIndex 是最常用的索引类型。它把每个 Node 的文本转为向量,存储在内存中(也可持久化到 Chroma 等向量库)。Settings 是 LlamaIndex 的全局配置对象,设置一次后所有组件都会使用默认值。

4.4 QueryEngine:查询引擎

1
2
3
4
5
6
7
8
9
# 创建查询引擎
query_engine = index.as_query_engine(
llm=llm,
similarity_top_k=3, # 检索 Top-3 最相关的节点
response_mode="compact" # 压缩上下文,节省 Token
)

response = query_engine.query("公司用什么数据库?")
print(response)

QueryEngine 封装了完整的”检索 → 生成”流程:

1
用户问题 → Retriever(检索 Top-K 节点)→ ResponseSynthesizer(拼接 Prompt + 调 LLM)→ 回答
response_mode 说明
compact(默认) 把检索结果尽量压缩到一个 Prompt 中,效率高
tree_summarize 对多个检索结果逐层总结,适合长文档
no_text 只返回检索结果,不调用 LLM(用于调试检索质量)

五、进阶配置

基础 RAG 跑通后,通过调整分块策略、检索方式和重排序,可以显著提升效果。

5.1 自定义分块策略

分块质量直接影响检索精度。LlamaIndex 提供多种内置分割器:

分割器 说明 适用场景
SentenceSplitter 按句子边界切分,保持语义完整 大多数场景(推荐默认)
TokenTextSplitter 按 Token 数切分,精确控制块大小 需要严格控制 Token 数时
SemanticSplitterNodeParser 按语义相似度切分,自动识别段落边界 长文档、主题多变的文档
MarkdownNodeParser 按 Markdown 标题层级切分 Markdown 文档
HierarchicalNodeParser 层级切分,生成父子节点 需要父子分段检索时

SentenceSplitter(推荐)

1
2
3
4
5
6
7
8
9
from llama_index.core.node_parser import SentenceSplitter

splitter = SentenceSplitter(
chunk_size=500, # 每个块的最大 Token 数
chunk_overlap=50, # 相邻块的重叠 Token 数
separator="。", # 中文句号作为辅助分隔符
paragraph_separator="\n\n" # 段落分隔符
)
nodes = splitter.get_nodes_from_documents(documents)

💡 建议chunk_size 中文文档建议 300-500 Token。太小(如 100)语义不完整,太大(如 1000)噪声多。从 400 开始试,根据效果调整。

SemanticSplitter(语义分块)

1
2
3
4
5
6
7
8
9
from llama_index.experimental.node_parser import SemanticSplitterNodeParser

# 语义分割器:根据相邻句子的语义相似度自动判断切分点
semantic_splitter = SemanticSplitterNodeParser(
buffer_size=1, # 每次比较相邻 1 个句子
breakpoint_percentile_threshold=95, # 相似度低于 95 分位数时切分
embed_model=embed_model
)
semantic_nodes = semantic_splitter.get_nodes_from_documents(documents)

语义分块的优势是能自动识别主题切换的位置,避免把两个不同话题的内容切到同一个块里。

5.2 混合检索(向量 + BM25)

纯向量检索在专有名词、产品型号等精确匹配场景下表现不如关键词检索。LlamaIndex 支持向量 + BM25 的混合检索:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from llama_index.core import VectorStoreIndex
from llama_index.core.retrievers import BM25Retriever
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.schema import IndexNode
import bm25s

# 向量检索器
vector_retriever = index.as_retriever(similarity_top_k=5)

# BM25 关键词检索器
bm25_retriever = BM25Retriever.from_defaults(
nodes=nodes,
similarity_top_k=5
)

# 混合检索:合并两路结果,去重排序
from llama_index.core.retrievers import RouterRetriever
from llama_index.core import QueryBundle

class HybridRetriever:
"""向量检索 + BM25 混合检索器"""
def __init__(self, vector_retriever, bm25_retriever):
self.vector_retriever = vector_retriever
self.bm25_retriever = bm25_retriever

def retrieve(self, query: str):
# 两路检索
vector_nodes = self.vector_retriever.retrieve(query)
bm25_nodes = self.bm25_retriever.retrieve(query)

# 合并去重(按 node_id 去重)
seen_ids = set()
merged = []
for node in vector_nodes + bm25_nodes:
if node.node_id not in seen_ids:
seen_ids.add(node.node_id)
merged.append(node)
return merged

# 使用混合检索器
hybrid_retriever = HybridRetriever(vector_retriever, bm25_retriever)
hybrid_query_engine = RetrieverQueryEngine.from_args(
retriever=hybrid_retriever,
llm=llm
)

response = hybrid_query_engine.query("公司技术栈用的什么数据库?")
print(response)

💡 提示:混合检索是生产环境的标配。向量检索擅长语义理解(”数据库”和”PostgreSQL”能匹配),BM25 擅长精确匹配(”PostgreSQL”只匹配包含这个词的文档),两者互补效果最好。

5.3 Reranker 重排序

Reranker 对初次检索返回的结果做二次精排,用专门的模型重新计算相关性分数,把最相关的排到前面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 使用 BGE Reranker(需要先安装)
# pip install llama-index-postprocessor-flag-embedding-reranker
from llama_index.postprocessor.flag_embedding_reranker import FlagEmbeddingReranker

reranker = FlagEmbeddingReranker(
model="BAAI/bge-reranker-v2-m3",
top_n=3 # 重排后只保留 Top-3
)

# 创建带 Reranker 的查询引擎
query_engine_with_rerank = index.as_query_engine(
llm=llm,
similarity_top_k=10, # 初次检索多取一些
node_postprocessors=[reranker] # 用 Reranker 精排到 Top-3
)

response = query_engine_with_rerank.query("公司的报销流程是什么?")
print(response)

Reranker 的工作原理

1
初次检索 Top-10 → Reranker 重新打分 → 保留 Top-3 → 送给 LLM 生成回答

核心价值:没有 Reranker 时,向量检索的 Top-1 不一定是最相关的(向量距离只是近似语义匹配)。Reranker 用交叉注意力机制对”问题-文档”对做更精细的相关性判断,显著提升检索精度。实测中,加 Reranker 后回答准确度通常能提升 10-20%。

5.4 持久化索引到 Chroma

默认的 VectorStoreIndex 存在内存里,重启就丢失。接入 Chroma 可以持久化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core import StorageContext

# 连接 Chroma(持久化到磁盘)
chroma_client = chromadb.PersistentClient(path="./chroma_db")
chroma_collection = chroma_client.get_or_create_collection("company_docs")

# 创建存储上下文
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)

# 构建索引(自动存入 Chroma)
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
embed_model=embed_model
)

下次启动时,可以直接从 Chroma 加载已有索引,不需要重新处理文档:

1
2
# 从已有 Chroma 索引加载
index = VectorStoreIndex.from_vector_store(vector_store, embed_model=embed_model)

六、多轮对话:ChatEngine

QueryEngine 每次提问都是独立的。LlamaIndex 的 ChatEngine 在 QueryEngine 基础上加入了对话记忆,支持连续追问。

6.1 基础多轮对话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建 ChatEngine
chat_engine = index.as_chat_engine(
llm=llm,
chat_mode="condense_question", # 把追问改写为独立问题再检索
verbose=True # 打印内部处理过程
)

# 第一轮
response1 = chat_engine.chat("公司年假有几天?")
print(f"AI: {response1}\n")

# 第二轮(追问)
response2 = chat_engine.chat("那怎么申请?")
print(f"AI: {response2}\n")

# 第三轮
response3 = chat_engine.chat("没休完怎么办?")
print(f"AI: {response3}")

6.2 ChatEngine 的 chat_mode

chat_mode 原理 适用场景
condense_question(推荐) 把追问 + 历史对话改写为一个独立问题,再去检索 大多数 RAG 对话场景
context 每轮都检索,把结果和历史对话一起送给 LLM 每轮问题都需要新知识时
condense_plus_context 改写问题 + 检索 + 完整上下文 需要最高回答质量时
simple 不做检索,纯 LLM 对话(不用知识库) 闲聊场景

condense_question 的工作流程

1
2
3
4
5
6
7
用户追问:"那怎么申请?"
↓ 结合历史对话改写为独立问题
"公司年假的申请流程是什么?"
↓ 用改写后的问题检索
检索到相关节点
↓ 生成回答
"年假需提前 3 天在 OA 系统提交申请..."

💡 提示condense_question 是多轮 RAG 对话的最佳选择——它先用 LLM 把追问改写为独立的完整问题,再去检索,避免了”那””这个”这类代词导致检索不到的问题。

6.3 重置对话

1
2
3
4
5
# 清空对话历史,开始新话题
chat_engine.reset()

response = chat_engine.chat("公司用什么技术栈?")
print(response)

七、高阶能力

7.1 Agent + 工具调用

LlamaIndex 支持把 RAG 查询引擎封装为 Agent 工具,让 LLM 自主决定何时查知识库、何时用其他工具。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core.agent import ReActAgent

# 把查询引擎封装为工具
knowledge_tool = QueryEngineTool(
query_engine=query_engine,
metadata=ToolMetadata(
name="company_knowledge_base",
description="查询公司内部知识库,包含年假制度、报销流程、技术栈、产品架构等信息"
)
)

# 定义一个天气查询工具
from llama_index.core.tools import FunctionTool

def get_weather(city: str) -> str:
"""查询指定城市的天气"""
weather_data = {"北京": "晴,25°C", "上海": "多云,22°C", "广州": "小雨,28°C"}
return weather_data.get(city, f"{city}:暂无天气数据")

weather_tool = FunctionTool.from_defaults(fn=get_weather)

# 创建 Agent(ReAct 策略:推理 + 行动)
agent = ReActAgent.from_tools(
tools=[knowledge_tool, weather_tool],
llm=llm,
verbose=True # 打印推理过程
)

# 测试 1:知识库问题
response = agent.chat("公司年假有几天?")
print(f"AI: {response}\n")

# 测试 2:天气问题
response = agent.chat("北京天气怎么样?")
print(f"AI: {response}\n")

# 测试 3:混合问题
response = agent.chat("公司技术栈用的什么数据库?顺便帮我查一下上海天气")
print(f"AI: {response}")

Agent 的推理过程(verbose=True 时可见):

1
2
3
4
5
6
> Thought: 用户问的是公司年假制度,我应该使用 company_knowledge_base 工具来查询
> Action: company_knowledge_base
> Action Input: {'input': '公司年假制度'}
> Observation: 入职满一年5天...
> Thought: 我已经获得了足够的信息来回答
> Answer: 根据公司年假制度...

7.2 结构化数据查询:CSV

LlamaIndex 不仅能处理文本文档,还能直接查询 CSV 表格数据:

1
2
3
4
5
6
7
8
9
10
11
12
from llama_index.experimental.query_engine import PandasQueryEngine
import pandas as pd

# 加载 CSV 数据
df = pd.read_csv("data/employees.csv")

# 创建 Pandas 查询引擎
pandas_engine = PandasQueryEngine(dataframe=df, llm=llm, verbose=True)

# 用自然语言查询表格
response = pandas_engine.query("技术部门有多少人?平均工资是多少?")
print(response)

💡 提示:PandasQueryEngine 会把自然语言问题转换为 Pandas 代码执行。这对结构化数据分析场景非常有用——比如让 AI 直接回答”上个季度销售额最高的产品是什么”这类问题。

踩坑记录:LlamaIndex 模块导入错误

现象

1
2
from llama_index import VectorStoreIndex
# 报错:ImportError: cannot import name 'VectorStoreIndex' from 'llama_index'

原因

LlamaIndex 从 v0.10.0 开始进行了大规模模块化重构,原来的 llama_index 包被拆分为 llama-index-core 和多个集成包。旧的导入路径全部失效。

解决方案

1
2
3
4
5
6
7
# 旧写法(v0.10 之前,已失效)
from llama_index import VectorStoreIndex, SimpleDirectoryReader

# 新写法(v0.10+)
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.llms.openai_like import OpenAILike
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

避坑建议

安装时注意版本号,确认你看的文档和教程是基于 v0.10+ 的。如果从网上复制代码,先检查导入路径是否是旧版格式。推荐锁定版本:

1
pip install llama-index>=0.11.0

八、LlamaIndex vs LangGraph:怎么选

对比维度 LlamaIndex LangGraph
核心定位 RAG 专用框架,管道式数据流 通用图编排框架,状态机范式
API 风格 高度封装,4 行代码跑通 RAG 需要定义 State/Node/Edge,代码量较多
上手难度 ⭐⭐ 较低(管道式,直觉性强) ⭐⭐⭐ 中等(需理解状态机概念)
基础 RAG 效率 ⭐⭐⭐⭐⭐ 极高(开箱即用) ⭐⭐⭐ 中等(需要手写节点函数)
分块策略 丰富(5+ 内置分割器,含语义分块) 需要自己实现或借助 LangChain
混合检索 内置支持(向量 + BM25) 需要自己实现
Reranker 内置 node_postprocessors 需要自己集成
多轮对话 ChatEngine 开箱即用(多种模式) MemorySaver + Checkpointer(需配置)
条件路由 有限(需借助 Agent 实现) ⭐⭐⭐⭐⭐ 原生支持,任意复杂
Agent 融合 有(ReActAgent),但不如 LangGraph 灵活 ⭐⭐⭐⭐⭐ 原生支持,深度定制
流程可视化 较弱 可打印拓扑图,LangSmith 可视化
适用人群 快速搭建 RAG 应用、不想写太多代码 需要精确控制每一步流程的开发者

选型建议

场景 推荐方案 理由
快速搭建文档问答系统 LlamaIndex 4 行代码跑通,分块/检索/Rerank 开箱即用
需要自定义分块和检索策略 LlamaIndex 内置 5+ 分割器和混合检索
复杂流程编排(条件路由、循环、自我修正) LangGraph 状态机 + 条件边,灵活度无可比拟
RAG + Agent 深度融合 LangGraph 原生工具调用和图编排
多轮对话 RAG 都行 LlamaIndex 的 ChatEngine 更简洁,LangGraph 更可控
快速原型 → 生产级 LlamaIndex → LangGraph 先用 LlamaIndex 验证效果,再用 LangGraph 深度定制

核心价值:如果你的需求是”用文档做一个问答机器人”,LlamaIndex 是最高效的选择——它把 RAG 的所有环节都封装好了,你只需要调参数。如果你需要”让 RAG 流程具备自我修正、多路并行检索、Agent 工具调用”等高级能力,LangGraph 更合适。两者也可以组合使用——用 LlamaIndex 做文档处理和检索(利用其丰富的分块和检索策略),用 LangGraph 做上层流程编排。


常见问题踩坑汇总

Q:LlamaIndex 默认使用什么 LLM?不配置会怎样?
A:LlamaIndex 默认使用 OpenAI 的 GPT 系列模型。如果你没有配置 LLM 和 Embedding,它会尝试调用 OpenAI API。国内用户必须在 Settings 或创建引擎时显式指定 LLM 和 Embedding 模型,否则会报 API 错误。

Q:检索结果不相关,怎么调优?
A:按优先级排查:①检查分块质量(打印 nodes 查看切分是否合理);②切换混合检索(向量 + BM25);③加 Reranker 重排;④调大 similarity_top_k;⑤换更适合你文档语言的 Embedding 模型(中文用 BGE 系列)。

Q:ChatEngine 的 condense_question 模式追问效果不好?
Acondense_question 依赖 LLM 把追问改写为独立问题。如果改写质量差(比如 LLM 能力不够),可以切换到 condense_plus_context 模式——它同时做改写和检索,把改写结果和检索上下文一起送给 LLM,回答质量更高但 Token 消耗也更多。

Q:索引构建很慢,有没有优化方法?
A:①使用持久化存储(Chroma),避免每次重启都重建索引;②对大文档集使用 batch_size 参数控制批量向量化速度;③如果只需要关键词检索,可以用 SummaryIndex(不做向量化,速度快但精度低)。

Q:LlamaIndex 能和 LangChain 一起用吗?
A:可以。LlamaIndex 支持把 LangChain 的 LLM、Embedding、工具等组件通过适配器接入。但通常不需要——LlamaIndex 自己的集成包已经覆盖了主流模型和工具。


总结与回顾

知识点 关键要点
LlamaIndex 定位 RAG 专用框架,API 最简洁,开箱即用
核心概念 Documents → Nodes → Index → QueryEngine / ChatEngine
基础 RAG 4 行代码跑通:加载文档 → 构建索引 → 创建引擎 → 查询
分块策略 5+ 内置分割器,SentenceSplitter 是默认推荐,SemanticSplitter 按语义切分
混合检索 向量 + BM25 互补,生产环境标配
Reranker 对检索结果二次精排,实测提升 10-20% 准确度
多轮对话 ChatEngine + condense_question 模式,自动改写追问为独立问题
Agent 工具 ReActAgent 绑定知识库和外部工具,LLM 自主决策调用
结构化查询 PandasQueryEngine 用自然语言查询 CSV 表格
与 LangGraph 对比 LlamaIndex 高效简洁,LangGraph 深度定制,按需选择

下篇预告

第 8 篇:RAGFlow 私有化套件实战 —— 前 4 篇实战分别用了原生 Python、Dify、LangGraph、LlamaIndex 搭建 RAG,它们各有侧重。但如果你需要”一体化私有部署 + 深度文档解析(PDF 布局分析、表格 OCR)”,RAGFlow 是更好的选择。下一篇完整实战 RAGFlow 的 Docker 部署、模型接入、深度文档解析、RAPTOR 索引、Agent 工作流,末尾与 Dify 做平台选型对比。


参考资料

资源 链接
LlamaIndex 官方文档 docs.llamaindex.ai
LlamaIndex GitHub run-llama/llama_index
DeepSeek 开放平台 platform.deepseek.com
bge-large-zh-v1.5 HuggingFace 模型页
bge-reranker-v2-m3 HuggingFace 模型页
Chroma 向量数据库 trychroma.com

本文为「从零到落地:RAG 检索增强生成实战系列」第 7 篇,完整系列持续更新中。