Skip to content

第5章 检索增强进阶

5.1 问题场景

基础检索增强系统能跑通后,常见问题并不会自然消失,反而会以更复杂的形式出现:

  • 命中率波动大。
  • 引用不稳定。
  • 复杂问句下回答质量下降。
  • 同一个问题换一种问法就召回失败。
  • 调了一堆参数,但效果提升不可复现。

这也是为什么很多团队在完成第 4 章的“最小 RAG 闭环”后,会进入一个很尴尬的阶段: 系统看起来能用,但一上线或一扩展样本规模,问题就不断暴露。 真正的挑战不再是“有没有 RAG”,而是“RAG 是否稳定、可解释、可复现”。

前端迁移提示

第 5 章和前端工程也很像,因为它本质上是在做系统优化、实验对照与证据呈现:

  • 前端性能优化思维 -> 检索链路参数与上下文优化。
  • A/B 实验与埋点思维 -> 不同检索策略的对照实验。
  • 列表排序和筛选思维 -> 重排、裁剪和上下文压缩。
  • 结果可视化能力 -> 评测结果、失败样本和引用稳定性展示。

最小项目目标

本章建议先完成一个“RAG 优化实验最小闭环”项目,例如:

  • 固定一批低分样本。
  • 设计一组小型实验矩阵。
  • 记录查询改写、召回数量、重排策略变化前后的结果。

参考入口:

5.2 核心原理

RAG 进阶优化的关键,不是“继续调参数”这么简单,而是把“问题归因 -> 实验设计 -> 指标对比 -> 配置固化”做成一套标准过程。 如果没有这个过程,优化很容易沦为随机试错。

一、查询优化:让系统更容易理解用户真实意图

同一个业务问题,用户可能会有很多问法。 如果不做查询优化,常见问题包括:

  • 表达不同但本质相同的问题,召回结果不一致。
  • 复杂问句里关键信息被淹没。
  • 长尾问句命中率明显偏低。

因此查询优化常常是第一层收益来源。

二、检索融合:不要把希望押在单一路径上

只用向量检索或只用关键词检索,都可能产生偏差。 在很多业务场景里,融合检索会更稳,因为它同时兼顾:

  • 语义相近。
  • 关键词命中。
  • 文档结构信息。

三、结果精排:真正进入模型上下文的证据必须更干净

很多 RAG 系统的问题,不是没召回正确文档,而是正确文档排得不够前,或者被无关上下文稀释。 重排和裁剪的目标是:

  • 把最关键证据放在最前。
  • 删掉噪音片段。
  • 减少上下文浪费。

四、上下文压缩:不是证据越多越好

RAG 优化的一个高频误区是: “既然模型错了,那就给更多证据。” 实际情况往往相反:

  • 噪音增多。
  • 成本上升。
  • 延迟变长。
  • 模型注意力被稀释。

因此“更少但更相关”的上下文,通常比“更多但更乱”的上下文更有效。

五、评测驱动:进阶优化必须和样本绑定

如果没有固定评测集和实验记录,你很难回答:

  • 这次优化到底有收益吗。
  • 收益来自哪一项改动。
  • 这种收益是否可复现。

5.3 实操步骤

推荐做法不是同时改很多变量,而是先做“固定评测集 + 小步实验矩阵 + 失败归因”三件事。 先把优化方法跑起来,再逐步扩展复杂策略。

步骤 1:建立稳定基线

先在固定评测集上记录当前指标:

  • 命中率。
  • 引用准确率。
  • 拒答率。
  • 平均延迟。

步骤 2:挑低分样本做误差归因

建议先把表现最差的一批样本挑出来,判断它们主要属于:

  • 查询表达问题。
  • 召回问题。
  • 重排问题。
  • 生成解释问题。

步骤 3:设计小规模实验矩阵

建议一次只变动 1 到 2 个参数或策略因素,例如:

  • 是否做查询改写。
  • top_k 从 3 调到 5。
  • 是否启用重排。
  • 片段长度调整。

步骤 4:记录实验结果

建议至少记录:

  • 实验 ID。
  • 改动点。
  • 样本集名称。
  • 指标变化。
  • 结论。

参考入口:

  • docs/examples/assets/samples/chapter-05-rag-optimization-log.json

步骤 5:固化收益明显的配置

不是所有优化都值得保留。 建议优先固化:

  • 收益明显。
  • 成本增长可接受。
  • 结果可复现。
  • 对高频场景有效。

步骤 6:同步准备前端和证据材料

建议至少保留:

  • 优化日志样本:docs/examples/assets/samples/chapter-05-rag-optimization-log.json
  • 评测结果样本:docs/examples/assets/samples/example-02-eval-result.json
  • 截图清单:docs/examples/assets/screenshots/README.md
  • 章节片段索引

步骤 7:把优化能力映射回项目线

如果你已经做通最小优化闭环,可以继续映射:

  • 项目线 A:知识问答效果优化。
  • 第 8 章:优化结果的回归评测与门禁。
  • 第 9 章:优化配置的上线与回退策略。

5.4 常见坑

坑 1:只追求单一指标最大化

如果只盯一个指标,整体体验反而可能变差。

坑 2:同时改动多个变量

最后根本不知道哪一项真正起作用。

坑 3:没有失败样本复盘

这样同类问题会在后续版本里反复出现。

坑 4:召回正确却不做重排和裁剪

正确文档被噪音淹没,最终效果仍然不稳。

坑 5:把“更多上下文”当成万能解法

上下文越多不一定越好,很多时候反而会伤害效果和成本。

坑 6:实验记录不完整

没有实验日志,后面很难把优化过程讲清楚,也不利于作品集展示。

5.5 验证方式

RAG 进阶优化做完后,不应只看“这次感觉更好了”,而要看它是否真的形成了可复现的优化方法。

一、指标波动是否可控

  • 固定评测集多次运行结果是否稳定。
  • 命中率波动是否控制在合理范围。

二、复杂问句是否明显改善

  • 长尾问句是否比基线更稳。
  • 引用是否更集中、更准确。

三、实验记录是否完整

  • 每次优化是否有实验 ID、改动点和结果记录。
  • 是否能回溯“为什么保留这个配置”。

四、前端证据是否更可信

从前端视角检查:

  • 引用来源是否更稳定。
  • 引用片段是否更短、更清晰。
  • 风险提示是否更准确。

五、证据材料

  • 优化日志样本:docs/examples/assets/samples/chapter-05-rag-optimization-log.json
  • 评测结果样本:docs/examples/assets/samples/example-02-eval-result.json
  • 截图清单:docs/examples/assets/screenshots/README.md
  • 图解配图:docs/examples/assets/diagrams/chapter-04-rag-flow.svg
  • 章节片段索引

5.6 面试表达

我在基础检索增强可用后,重点做了查询优化、检索融合、结果精排和上下文压缩四层优化。 通过固定评测集、实验矩阵和失败样本复盘,把效果提升从偶发结果变成可复现的方法论。

实战案例:制度问答命中率优化

  • 背景:企业制度问答在复杂问句和长尾问题上命中率偏低,引用不稳定。
  • 动作:引入查询改写、混合检索和重排,并以实验矩阵记录不同策略的收益与成本变化。
  • 结果:复杂问题命中率和引用一致性显著改善,优化过程也可被后续版本复用。

推荐答题框架

如果面试官问“RAG 进阶和入门的差别是什么”,可以按下面顺序回答:

  1. 先讲基础闭环和稳定可用是两回事。
  2. 再讲查询优化、检索融合、重排和压缩。
  3. 再讲如何用实验矩阵和失败样本做归因。
  4. 最后讲如何固化配置,并接入后续评测与上线流程。

5.7 练习任务

  1. 选 20 条低分或高风险样本,做一次失败原因标注。
  2. 设计 2 组实验矩阵,分别测试查询改写和重排策略。
  3. 记录每次实验的改动点、指标变化和结论。
  4. 固化一套当前最优配置,并说明为什么保留它。
  5. 基于 docs/examples/assets/samples/chapter-05-rag-optimization-log.json,整理出你的第一版 RAG 优化日志。

5.8 验收清单

  • 任务完成率 >= 85%
  • 关键指标达标率 >= 90%
  • 异常场景通过率 >= 90%
  • 至少完成 1 组实验矩阵和 1 份优化日志。
  • 至少保留 1 份优化样本、1 组截图占位清单和 1 份章节代码片段索引。
  • 至少能用 2 分钟讲清楚“为什么 RAG 进阶不是继续调参数,而是建立一套可复现的优化方法”。

5.9 💡 自托管 RAG 进阶 — 本地环境下的检索优化

🏠 自托管替代方案

第 4 章介绍了基础的本地 RAG 搭建(BGE-M3 + ChromaDB),本节聚焦在自托管环境下如何应用第 5 章的进阶优化技术。

自托管环境下的进阶优化

本章介绍的 RAG 优化技术(查询改写、重排序、混合检索等)在自托管环境下同样适用,但有一些差异需要注意:

优化技术云端实现自托管实现差异说明
查询改写GPT-4o 改写Qwen3-8B 改写本地小模型改写质量稍低,建议多生成几个变体
重排序Cohere Rerank APIBGE-Reranker-v2 本地开源重排模型精度接近商业 API
混合检索云端向量+关键词Qdrant 混合检索Qdrant 原生支持稀疏+稠密混合
Chunk 策略大上下文窗口容错需更精细分块本地模型上下文窗口通常更小

本地重排序方案

typescript
// 使用 Ollama 运行本地模型进行重排序打分
async function localRerank(query: string, documents: string[]): Promise<string[]> {
  const scored = await Promise.all(
    documents.map(async (doc) => {
      const res = await fetch('http://localhost:11434/api/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          model: 'qwen3:8b',
          prompt: `判断以下文档与查询的相关性,只回答 1-10 的分数。\n查询:${query}\n文档:${doc}\n分数:`,
          stream: false,
        }),
      });
      const data = await res.json();
      return { doc, score: parseInt(data.response) || 0 };
    })
  );
  return scored.sort((a, b) => b.score - a.score).map((s) => s.doc);
}

自托管 RAG 的特殊调优建议

  1. Chunk 更小:本地模型上下文窗口通常 4K-8K,建议 chunk 控制在 300-500 token
  2. Top-K 更少:检索结果控制在 3-5 条,避免超出上下文窗口
  3. Embedding 维度对齐:确保检索和存储使用同一模型的同一维度
  4. 缓存策略:本地推理较慢,对高频查询做结果缓存

🖥️ 前端迁移提示:自托管 RAG 调优就像前端性能优化——资源有限时,需要更精细的 budget 分配(chunk size = bundle size,top-K = 网络请求数)。

深入阅读