跳到主要内容

如何优化 RAG 的检索效果?

RAG 效果差,多数先死在检索:该召回的 chunk 没进 top-k,后面生成再强也是「有据错引」。本篇按 索引 → 查询 → 检索 → 评测 讲优化思路与面试答法;概念见 RAG 与检索增强;动手见 RAG 落地实践、[LangChain RAG 实践](/docs/ai/RAG/LangChain RAG 实践);全局/关系题见 [GraphRAG 概览与查询](/docs/ai/RAG/GraphRAG 概览与查询)。

先分清:优化检索 vs 优化生成​

症状更可能问题优先优化
引用了无关段落检索噪声大、精排不够重排、混合检索、缩 chunk
库里明明有却答不出召回不足增大 k、混合检索、查询改写
答案跨段被切断切分策略重叠、按结构切、Parent-Document
专有名词/编号搜不到纯向量弱于关键词BM25 混合、元数据过滤
全局归纳题(「整体趋势」)向量局部相似度不够GraphRAG / 社区摘要

面试先一句话:用评测集看是 recall 不够还是 precision 不够,再对症下刀,别一上来堆 rerank。

优化总图​

索引侧 查询侧 检索侧
──────── ────── ──────
切分策略 ──┐ 查询改写 ──┐ 混合检索(向量+BM25)
重叠/结构切 ├→ 更好 chunk HyDE/多查询 ├→ 更好 query → 扩大召回 k
Embedding ─┤ 意图识别 ──┘ Rerank 精排
元数据/权限 ─┘ 阈值 + 元数据过滤
Parent-Document 回填
↓
小评测集:Recall@k / MRR / 人工判相关

1. 索引侧:让 chunk「可搜、可定位」​

检索上限由索引决定——垃圾进,垃圾出。

手段做法解决什么
按结构切分按标题 / 段落 / Markdown 层级,而非固定字数硬切语义不断裂
重叠(overlap)相邻 chunk 共享 10%~20% 文本边界处答案被切断
chunk 大小常见 256~512 token;表格/代码可单独策略太大噪声、太小缺上下文
元数据来源、章节、产品线、版本、租户、时间检索时过滤、可解释引用
Embedding 选型与语料语言/领域匹配;必要时微调 embedding语义空间不对齐
Contextual Retrieval索引时给每个 chunk 补「文档级上下文摘要」再 embedchunk 脱离原文后语义模糊

Parent-Document / 小块搜大块读: 索引用小 chunk 提高定位精度,命中后回填父段落或相邻 chunk 给生成——兼顾 recall 与上下文完整。

2. 查询侧:让用户「问法」更接近库里的「写法」​

手段做法适用
查询改写LLM 把口语问题改写成检索友好表述用户问法飘、指代多
Multi-Query一次生成多个检索 query,结果合并去重召回面窄
HyDE先让 LLM 编「假答案」再 embed 检索问句与文档风格差异大
Step-back先问更抽象的上位问题,再检索需要背景概念的问题
对话上下文多轮时把上一轮意图拼进 query「它」「那个政策」缺主语

注意:查询改写会增加延迟与成本——PoC 可先做 规则 + 一轮改写,用失败 case 决定是否上 HyDE。

3. 检索侧:先召回,再精排​

用户 query ─┬─ 向量检索 top-N
└─ BM25 / 关键词 top-N
↓
分数融合(RRF 等)→ 候选集
  • 向量:语义相似,「退货怎么弄」≈「如何申请退款」
  • BM25:精确 token、SKU、错误码、法条编号
  • 工业界常见:RRF(Reciprocal Rank Fusion) 融合两路排序,比简单加权稳

两阶段:召回 + Rerank​

第一阶段:混合检索,k 开大(如 20~50)——保 recall
第二阶段:Cross-Encoder Reranker 精排 → top 3~5 ——提 precision

Rerank 模型看 query 与 chunk 的交互,比 bi-encoder 向量相似度准,但更贵——适合「第一阶段噪声大」的场景。

其他检索技巧​

技巧说明
相似度阈值低于阈值拒答,防硬凑无关段
元数据预过滤先按产品/版本/权限筛子集再向量搜
Multi-Vector一 chunk 多个 embedding(如摘要 + 原文)
HyDE + 混合常与混合检索组合,不是互斥

4. 按失败 case 选型(面试加分)​

失败现象优先尝试
编号/术语搜不到混合检索 + 元数据
相关段在 top-20 但不在 top-3加 Rerank
相关段根本不在 top-k增大 k、Multi-Query、查 chunk 切分
跨文档归纳GraphRAG Global 查询 / 预建摘要索引
表格/代码块专用 parser、整表/整段为 chunk
多租户串库检索必带 tenant filter

答法:先 Naive 向量基线 + 小评测集,按 bad case 加混合 → rerank → 改写 → 结构切分,比一口气背十个缩写更像做过项目。

5. 怎么知道「优化有效」​

别凭感觉,建 检索层评测(可与生成层分开):

指标含义
Recall@k标准答案所在 chunk 是否出现在 top-k
MRR第一个相关结果排第几
nDCG排序质量(相关度分级时)
人工判相关小集上标注「该段能否回答问题」

最小实践:20~50 条 (question, gold_chunk_id),改 chunk / k / 混合 / rerank 后看 Recall@5 是否上升——见 RAG 落地实践 的 eval 思路。

生成层指标(答案对不对)会掩盖检索问题;面试可说:检索评测先行,端到端评测后置。

常见坑​

坑说明
只调 top-kk 大 recall 升但噪声进 Prompt,需配合 rerank 或阈值
chunk 一刀切PDF/表格/Markdown 同一参数,边界处处漏
忽略权限检索未过滤 tenant,泄漏比答错更严重
过度 HyDE假答案跑偏会带偏检索
不重索引改了切分/embedding 策略却沿用旧向量库

面试参考答法(60~90 秒)​

优化 RAG 检索我会先建小评测集,看是召回不够还是排序太噪。

索引侧:按文档结构切 chunk、加 overlap,补元数据;必要时 Parent-Document——小块检索、大块生成。

查询侧:多轮对话补全指代,必要时 LLM 改写或多 query 扩展。

检索侧:专有名词和编号加 BM25 与向量做混合检索;第一阶段 k 开大保 recall,第二阶段 Cross-Encoder rerank 提 precision;低分阈值则拒答。

全局归纳类再考虑 GraphRAG 或预摘要,别用调 k 硬扛。每改一项用 Recall@k 验证,避免只调生成 Prompt 掩盖检索问题。

延伸阅读​

篇关系
RAG 与检索增强流水线与失效模式速览
[LangChain RAG 实践](/docs/ai/RAG/LangChain RAG 实践)Retriever / Reranker 拼装
[Milvus 向量库实践](/docs/ai/RAG/Milvus 向量库实践)向量索引与过滤
[GraphRAG 概览与查询](/docs/ai/RAG/GraphRAG 概览与查询)全局/关系检索

面试速记​

  1. 先诊断: Recall 不足 vs 排序太噪,决定加召回还是加 rerank。
  2. 索引: 结构切分 + overlap + 元数据;Parent-Document 小块搜大块读。
  3. 查询: 改写 / Multi-Query / HyDE,解决问法与文档风格 gap。
  4. 检索: 混合检索(向量+BM25)→ 大 k 召回 → Rerank 精排 → 阈值拒答。
  5. 评测: Recall@k / MRR 先行;按 bad case 迭代,别只调生成 Prompt。