上篇我们覆盖了 RAG 链路的前三个阶段——查询转换、路由和查询构建,核心目标是在检索发生之前把查询优化到位。本篇进入后半程:索引、检索和生成。这三个阶段是 RAG 的核心链路,也是优化策略最密集的地方。
先回顾一下全景图:

阶段四:索引(Indexing)
目标:构建高质量的索引,确保检索时能找到最相关的片段。
索引阶段是 RAG 的基石。如果索引建得不好,后面的检索和生成再努力也是”垃圾进、垃圾出”。
1. 分块策略
分块(Chunking)是 RAG 优化中最基础也最容易踩坑的一环。关于四种主流分块策略的详细对比,可以参考 RAG 实战:核心组件、调优与问题排查。这里补充两个容易被忽略的要点:
块大小不是越小越好。 太小可能丢失上下文,太大又可能引入噪声。500-1000 字符可以作为部分文本知识库的实验起点,但不是通用最佳值;代码、表格、FAQ 和长篇规章应分别设计切分策略,并用检索评测选择大小。
重叠不是“多就好”。 可以先测试 10%-20% 等较小重叠率,再比较召回率、重复结果和索引成本。是否需要超过 30% 取决于边界语义和文档结构,不能脱离数据集断言“没有收益”。
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", "。", ".", " "] # 优先在自然边界切
)
2. RAPTOR(递归文档树检索)
处理长文档的利器。核心思路:给文档建立层次化的摘要树。
文档总摘要(第 3 层)
/ \
段落组摘要 A 段落组摘要 B(第 2 层)
/ | \ / | \
Chunk1 Chunk2 Chunk3 Chunk4 Chunk5 Chunk6(第 1 层:原始块)
构建方法:先将文档切成小块,用 LLM 对相邻块做摘要并聚类,逐层向上构建。检索时可以从任意层级切入:
- 用户问宏观问题(“这篇文档讲了什么”)→ 用顶层摘要检索;
- 用户问细节(“第三章的参数怎么配置”)→ 用底层块检索。
适用场景:知识库包含大量长篇文档(论文、技术手册、产品说明书)。短文档(如 FAQ)用 RAPTOR 性价比不高。
3. 多向量 / 表征检索
为同一文档块生成多个向量表示。比如为一篇长文档生成一个概括性向量(用于粗筛),再为其中每个小段落生成详细向量(用于精排)。检索时先用概括性向量快速定位候选文档,再用详细向量做精确匹配。
这种方法在处理”一篇文档涵盖多个子主题”的情况时特别有效——概括性向量负责”找到对的文档”,详细向量负责”找到对的段落”。
4. Embedding 选型
Embedding 选型可能显著影响召回质量,但收益取决于语言、领域、查询分布和基准数据,应该与分块、混合检索等方案在同一评测集上比较。
| 考量维度 | 建议 |
|---|---|
| 维度 | 维度影响存储和计算,但跨模型不能用“1024 > 768”推断质量;应比较实际检索指标 |
| 领域适配 | 医疗、法律等垂直领域优先选领域微调过的模型 |
| 多语言 | 中英混合场景选 BGE-M3 等多语言模型 |
| 部署方式 | API 调用省运维但按量付费;本地部署前期投入但边际成本低 |
领域微调只有在数据量、标注质量和评测结果支持时才值得投入。先建立基线,再比较通用模型、领域模型和微调方案的质量与成本。
阶段五:检索(Retrieval)
目标:从索引中高效、准确地召回最相关的文档片段。
1. 多路召回 + 混合检索
单一检索方式总有盲区。向量检索擅长语义匹配但容易漏掉精确关键词,关键词检索(BM25)擅长匹配专有名词但对同义词不敏感。
关于混合检索的详细讨论可以参考 企业级 RAG 怎么落地?,这里给出一个完整的集成检索器实现:
# LangChain v1 需要额外安装 langchain-classic
from langchain_classic.retrievers import EnsembleRetriever, BM25Retriever
# 向量检索器
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 10})
# 关键词检索器
bm25_retriever = BM25Retriever.from_documents(docs)
bm25_retriever.k = 10
# 组合检索器(可调权重)
ensemble_retriever = EnsembleRetriever(
retrievers=[vector_retriever, bm25_retriever],
weights=[0.6, 0.4] # 向量检索权重略高
)
三种检索方式的分工:
| 方式 | 擅长 | 盲区 |
|---|---|---|
| 向量检索 | 语义匹配、同义词、模糊表达 | 精确关键词、专有名词 |
| BM25 关键词 | 专有名词、编号、精确匹配 | 同义词、语义相近但用词不同 |
| 元数据过滤 | 按日期/作者/类别/权限过滤 | 无法做内容级别的检索 |
2. ReRank 搜索重排
ReRank 位于初次召回之后、把上下文交给生成模型之前,因此属于检索阶段或“检索—生成边界”,不是生成本身。典型流程如下:
用户查询 + 召回候选文档
│
▼
Reranker 模型
重新评估查询与文档的相关性
│
▼
按分数重排 → 截取 Top-K 交给 LLM
Reranker 不负责从全库检索,而是对候选集精排。候选数、最终 Top-K 和模型选择都应通过 Recall、MRR、nDCG、延迟与成本共同确定,不能把“召回 30-50、保留 5-10”当成固定规则。
| 模型类型 | 部署方式 | 评估重点 |
|---|---|---|
| 托管 Rerank API | 在线 API | 领域效果、数据合规、价格与延迟 |
| BGE 等开源 Reranker | 本地部署 | 语言/领域效果、硬件占用与吞吐 |
不存在对所有数据集都“效果最好”的 Reranker;应使用同一标注集做离线比较。
阶段六:生成(Generation)
目标:基于检索到的上下文,生成高质量、无幻觉、流畅的答案。
1. Prompt 工程
关于 Prompt 模板设计可以参考 RAG 实战:核心组件、调优与问题排查。这里补充两个容易被忽略的点:
明确限制回答范围。 在 Prompt 中写清楚“仅根据提供的上下文回答,如果信息不足请明确说明”,可以降低部分无依据生成,但不能替代检索质量、引用校验、事实核验和拒答评测。
控制输出格式。 要求 LLM 输出结构化答案(如先给结论、再给依据、最后标注来源),方便后续处理和验证。
2. Self-RAG(自我反思 RAG)
原始 Self-RAG 不是给任意 LLM 套一个“三次自问”Prompt,而是训练一个模型在生成时输出特殊的 reflection tokens,用它们决定是否检索,并评价证据相关性、回答支持度和整体质量。下面是概念化流程,不是原论文算法的逐步实现:
┌─────────────────────────────────────────────┐
│ Self-RAG 生成循环 │
│ │
│ 1. 要不要检索? │
│ ├─ 需要 → 执行检索 │
│ └─ 不需要 → 直接用内部知识 │
│ │
│ 2. 检索结果有没有用? │
│ ├─ 有用 → 基于检索结果生成 │
│ ├─ 部分有用 → 只取有用部分生成 │
│ └─ 没用 → 放弃检索结果,改用内部知识 │
│ │
│ 3. 生成的答案是否事实正确? │
│ ├─ 是 → 输出 │
│ └─ 否 → 重新生成或补充检索 │
└─────────────────────────────────────────────┘
- 潜在收益:在原论文的特定模型和评测集上提高了事实性与引用表现。
- 工程代价:需要匹配的训练模型、检索器和解码逻辑;用通用 LLM 多轮模拟并不等价。
- 适用方式:先在低风险数据集验证收益。医疗、法律、金融等高风险场景还必须增加权威来源、领域专家复核和明确责任边界,不能把 Self-RAG 当成准确性保证。
实现前应先阅读 Self-RAG 原论文,并区分“原始 Self-RAG”与泛化的自检索/自反思流程。
3. CRAG(纠正性 RAG)
CRAG 在传统 RAG 的基础上加了一个检索质量评估模块,在生成之前先判断检索结果靠不靠谱:
用户提问 → 检索 → 评估检索质量
│
┌─────────┼─────────┐
▼ ▼ ▼
高质量 中等质量 低质量
│ │ │
▼ ▼ ▼
直接生成 问题重写 扩大搜索范围
再检索 或告知用户
这个评估模块可以用一个小型 LLM 或专门的分类模型来实现。相比 Self-RAG,CRAG 的”反思”发生在检索阶段而不是生成阶段,对延迟的影响更可控。
| Self-RAG | CRAG | |
|---|---|---|
| 反思位置 | 生成过程中 | 检索之后、生成之前 |
| 核心机制 | 训练模型生成 reflection tokens,控制检索并评价证据与生成内容 | 独立模块评估检索质量,触发纠正动作 |
| 延迟影响 | 较高(多次 LLM 调用) | 中等(一次额外评估) |
| 适用场景 | 准确性优先 | 鲁棒性优先 |
场景化选型:别什么都往上堆
RAG 优化不是做加法。不同的场景,性价比最高的策略组合完全不同。以下是从上篇和下篇所有策略中提取的选型建议:
| 场景 | 特点 | 推荐策略 | 成本 |
|---|---|---|---|
| 简单问答 | 问题直接,知识库清晰 | 高质量 Chunking + 多查询重写 + ReRank + 精炼 Prompt | 低 |
| 复杂推理 | 多步骤、逻辑关联 | 问题分解 + 混合检索 + Self-RAG/CRAG | 高 |
| 知识密集型 | 长文档、领域专业 | RAPTOR + 领域 Embedding + 集成检索器 + ReRank | 中-高 |
| 高实时要求 | 对响应速度敏感 | 自检索 + 动态路由 + 缓存 + 轻量模型 | 低-中 |
建议路径:从简单问答的组合开始,跑通后看效果,再根据实际痛点逐步引入复杂策略。千万别一上来就上 Self-RAG + RAPTOR + 多路召回全家桶。
性能优化 6 招
除了算法层面的优化,工程层面的性能优化同样重要。以下 6 招可以显著提升响应速度和资源利用率:
1. 并行处理
多查询重写、多路召回等场景天然适合并行。多个子查询可以同时发往检索器,多个检索器可以同时执行。利用 asyncio 或线程池能显著减少总等待时间。
2. 增量更新
避免全量重建索引。对于新增或修改的文档,只更新受影响的索引部分。如果向量数据库支持 upsert,优先使用增量写入而非全量覆盖。
3. 缓存策略
对频繁查询、热门文档嵌入、ReRank 结果进行缓存。可以分层设计:
- L1(内存):高频查询的 embedding 向量,毫秒级命中;
- L2(磁盘):文档 chunk 的向量,避免重复计算;
- L3(LLM 响应):相同问题的生成答案,直接返回。
4. 批量操作
在 API 限制允许时,批量提交 embedding 输入通常能减少网络往返和调度开销,但不保证端到端一定更快。价格是否优惠取决于服务商是否提供单独的 Batch API 或计费方案;普通批量请求不会自动获得折扣。
5. 量化与剪枝
对于本地部署的模型,可以评估 INT8/INT4 量化或模型剪枝,以减少显存和计算开销。精度损失和速度收益高度依赖模型、硬件、量化方法与任务,必须在目标评测集和部署硬件上验证。
6. 硬件加速
GPU/TPU 往往更适合大规模矩阵计算,但小模型、低并发或受数据传输开销影响的任务未必比 CPU 更划算。应比较目标负载下的吞吐、p95 延迟、利用率和总成本,再决定本地 CPU、加速器或云实例。
评估:你怎么知道优化真的有效?
做了优化,怎么衡量效果?直觉感受不靠谱,需要量化的评估体系。
常用评估框架
| 框架 | 特点 | 适用场景 |
|---|---|---|
| Ragas | 专注 RAG 评估,自动化指标丰富 | 开源项目首选,与 LangChain/LlamaIndex 集成 |
| LangChain Eval | 框架内置,用 LLM 评估 LLM | 已经在用 LangChain 的项目 |
| Arize Phoenix | 可观测性平台,可视化追踪 | 需要运行时监控的团队 |
核心指标
评估分两个维度:
检索维度:
- 召回率(Recall):相关文档有多少被召回了?
- 精确率(Precision):召回的文档中相关占比多少?
- MRR:第一个相关文档排在什么位置?
生成维度:
- 忠实度(Faithfulness):答案是否基于检索到的上下文,有没有编造?
- 相关性(Relevance):答案有没有回答用户的问题?
- 完整性(Completeness):有没有遗漏关键信息?
- 引用准确性(Citation Accuracy):引用来源是否真正支撑答案中的关键结论?
- 拒答准确率(No-answer Accuracy):资料不足或无权限时,系统是否能正确拒答?
企业场景还要额外评估权限安全:同一组问题应使用不同角色账号执行,检查检索候选、Prompt 上下文、引用来源和运行日志中是否出现无权访问内容。否则最终答案看起来合规,中间链路仍可能已经泄露敏感信息。
自动化指标能覆盖大部分场景,但对于复杂的主观判断(如”答案是否足够清晰”),人工评估仍然不可替代。
总结
回到开头的问题:你的 RAG 为什么总差一口气?
答案很可能是——你只优化了其中一两个阶段,而瓶颈藏在其他阶段。上下两篇覆盖了 6 个阶段、20+ 种策略,下面是一张快速定位表:
| 如果你的症状是… | 重点检查… |
|---|---|
| 检索结果和问题不沾边 | 查询转换(阶段一)、Embedding 选型(阶段四) |
| 召回了正确文档但答案不对 | ReRank 与上下文组装(阶段五)、生成 Prompt(阶段六) |
| 复杂组合问题翻车 | 问题分解(阶段一)、路由(阶段二) |
| 长文档检索效果差 | RAPTOR(阶段四)、分块策略 |
| 幻觉严重 | ReRank(阶段五)、证据质量、Prompt 限制、引用/事实校验 |
| 响应太慢 | 性能优化 6 招、自检索(阶段三) |
| 不知道优化有没有用 | 评估体系 |
最后记住三条铁律:
- 从简单的开始:先建立 Chunking、基础检索和生成基线,再根据评测结果决定是否加入多查询重写或 ReRank。
- 不是越多越好:每加一层优化,成本就涨一截。根据场景选策略组合。
- 数据是根:任何优化都无法弥补知识库本身的质量问题。垃圾进、垃圾出。
本系列文章:
- 第一篇:RAG 为什么回答流程问题会漏步骤? — 流程类 RAG 的专项问题与双层上下文方案
- 第二篇:企业级 RAG 怎么落地? — 知识治理、权限、安全与运营闭环
- 第三篇:RAG 检索不准?先别换模型,把问题问对再说 — 查询转换、路由与查询构建
- 第四篇:本文 — 索引、检索与生成