Skip to content

RAG 优化全景:从召回到精度、重排到知识图谱,一文讲透

🕒 Published at:

RAG 这东西,"搭起来"一个下午就够了,"调好用"却能耗掉你几个月。因为它是一条长链路,任何一环拉胯,最终答案就崩。这一篇把散落在各处的 RAG 优化手段系统地梳理一遍——沿着 RAG 的每个阶段,讲清有哪些旋钮、各自解决什么问题、以及什么情况该拧哪个。这是一篇可以收藏当速查表的长文。代码以 Python 为主、点到为止,重点在思路和判断。

先建立地图:RAG 的五个阶段,每一环都能优化

别把 RAG 当成"检索 + 生成"两步。把它拆细成五个阶段,你才知道优化的抓手在哪:

① 建索引解析·分块·元数据② 查询理解改写·分解·路由③ 检索向量·关键词·图④ 检索后重排·压缩·去冗⑤ 生成约束·溯源·自纠

一条铁律先说在前:先诊断,再优化。 答错时,先用评测集分清是"检索没召回"(该找的没找到)、"排序不好"(找到了但没排进前几)、还是"生成翻车"(资料对了模型却答偏)。不诊断就乱调,就是拆东墙补西墙。下面逐阶段展开。

阶段一:建索引——地基决定上限

检索的天花板,在文档变成向量之前就定了。 这一环没做好,后面全是徒劳。

① 解析要干净。 真实文档是带表格的 PDF、扫描件、多栏排版。表格要转成结构化文本(Markdown 表格),扫描件要走 OCR,页眉页脚水印要去噪。脏进脏出,别指望后面补救。

② 分块策略,看文档下菜。 这是最影响效果、又最没有标准答案的一环:

  • 递归字符分块(按段落/句子边界切、带重叠):通用首选,适合大多数连续文本。
  • 语义分块(按语义相似度找断点):适合主题切换频繁、段落界限模糊的文本,切得更"整"。
  • 父子分块(small-to-big):子块小、检索精准;命中后返回大的父块给模型、上下文完整。当你既想检索准、又想给模型足够上下文时用它,几乎是长文档的标配。
  • 按结构分块:文档有清晰标题层级(手册、法规)时,按"标题 + 其下内容"成块,语义最完整。
  • 一问一答分块:FAQ 类,每个 Q&A 独立成块。

举例:产品手册按结构切;FAQ 按问答切;一篇连续的分析报告用递归分块 + 父子分块。没有万能参数,先看文档长什么样。

③ 元数据富化。 给每块打上来源、页码、部门、时间、类型等标签。它有三重价值:过滤(权限、时间范围)、溯源(答案标出处)、路由(按类型选库)。这一步顺手做,后面处处受益。

④ 索引增强(进阶)。 不止把原文切块入库,还可以:给每块生成摘要再索引(摘要更聚焦、检索更准,命中后取原文);为每块预先生成一些假设问题入库(用户问题往往更像"问题"而非"陈述",用问题去匹配问题,召回更高)。这类"多向量/摘要索引"是提升召回的隐藏大招。

阶段二:查询理解——先把用户的话"翻译"好

用户的原始提问往往又短、又口语、又有歧义。直接拿去检索,等于让检索器带着一个烂输入干活。在检索之前先加工查询,性价比极高:

  • 多查询改写:让模型把一句话改写成多种问法,各检索一遍再合并。治"用户和文档用词对不上"。→ 泛用,几乎总能提召回。
  • HyDE(假设文档嵌入):先让模型"编"一段假想的答案,拿这段假答案去检索(假答案和真资料在语义上更接近)。治"问题和答案文本形态差异大"的场景。
  • 查询分解:把复杂的多跳问题拆成子问题分别检索。治"一个问题里套了好几个问题",比如"对比 A 产品和 B 产品的保修政策"——拆成分别查 A、查 B。
  • 后退式提问(step-back):先问一个更抽象的上位问题("这属于什么类别的规定"),再检索。治"问题太具体、直接检索抓不到大背景"。
  • 查询路由:有多个知识库/数据源时,先判断这个问题该去哪个库(HR 问题去 HR 库、技术问题去技术库),甚至判断"要不要走 RAG,还是直接答/查数据库"。治"多源混检导致噪音"。

举例:FAQ 简单问答,用多查询改写就够;"对比型/多步型"问题,上查询分解;有多个部门知识库,加查询路由。

阶段三:检索——三种武器 + 知识图谱

① 向量检索懂语义、抓近义,但对精确关键词(型号、编号、人名)不敏感。② 关键词检索(BM25)认死字面、精确词命中稳,但不懂近义。③ 混合检索把两者加权融合,取长补短——这是生产里的默认选择,比单用任何一种都稳。再叠上元数据过滤(权限、时间、类型),把检索范围先圈准。

什么时候,向量检索根本不够——该上知识图谱(GraphRAG)

普通向量 RAG 有个天生短板:它把文档切成一块块孤立的片段,块与块之间的"关系"丢了。 有几类问题它天然搞不定:

  • 多跳关系推理:"张三的直属领导,负责哪个项目?"——要先找张三→找到领导→再找领导负责的项目,跨了好几块,向量检索一步到位抓不全。
  • 全局汇总类:"总结一下所有客户投诉的共同点"——答案不在某几块里,而要纵览整个语料。
  • 强关系型问题:涉及实体之间错综的关联(组织架构、供应链、人物关系)。

GraphRAG 的思路是:先用大模型把语料抽取成一张知识图谱(实体是节点、关系是边),检索时不再只找相似片段,而是在图上游走(顺着关系跳转),还能预先对图里的"社区/子群"生成摘要,专门回答全局性问题。

向量 RAG:一堆孤立片段块之间没有连线 → 关系丢失GraphRAG:实体+关系成网张三领导项目部门顺着关系跳转 → 多跳可达

但别一上来就上 GraphRAG。 它代价很大:构建图谱要对全语料跑大模型抽取,贵、慢、还要维护图的更新。只有当你的核心问题确实是"多跳/关系/全局汇总"类时才值得;如果是"某个政策是什么"这种直接事实查询,普通向量 + 混合检索又快又好,上图谱纯属杀鸡用牛刀。现实中也常混用:日常问答走向量 RAG,遇到关系型问题再走图谱。

阶段四:检索后处理——把"找回来的"整理干净

检索回来一堆候选,直接全塞给模型是不对的。这一环决定了"喂进模型的上下文"质量:

① 重排序(rerank)——最该做的一步。 检索器海选出前 20 条(保召回),再用更强的重排模型逐条精算相关性、只留前 3~5(保精度)。因为检索用的相似度打分较粗,正确答案常被"字面沾边"的内容挤到后面。重排方式:专门的 cross-encoder 重排模型(如 bge-reranker)、云服务(Cohere/Jina Rerank)、或直接用大模型重排(省事,不用额外部署)。只要你在乎排序质量,就该加重排。

② 上下文压缩/过滤。 命中的块里往往只有几句真正相关,其余是噪音。用压缩器(如 LLMChainExtractor 抽取相关句、LLMChainFilter 过滤无关块)把上下文"提纯",既省 token 又减干扰。

③ 多样性去冗(MMR)。 检索到的前几条有时高度重复(同一句话在多处出现)。最大边际相关(MMR)在"相关"和"不重复"之间平衡,让返回结果更多样,覆盖更全:

python
# MMR:在相关性和多样性之间平衡,避免检索结果高度重复
docs = vectorstore.max_marginal_relevance_search(query, k=4, fetch_k=20)

④ 缓解"中间迷失"(lost in the middle)。 研究发现模型对长上下文中间位置的信息容易忽略。把最相关的内容重排到上下文的头和尾能缓解——LangChain 的 LongContextReorder 就干这个。上下文条数多时值得一做。

阶段五:生成——最后一步别功亏一篑

资料对了,也可能栽在生成:

① 忠实度约束 + 引用溯源。 提示词死约束"只依据资料回答、没有就说没查到、不许编",答案带出处。既降幻觉,又便于发现模型在编。

② 自我纠错型 RAG(进阶范式)。 让流程"会反思":

  • CRAG(纠正式 RAG):先给检索结果打个质量分,检索得好就正常答;检索得差就触发补救(比如改写查询重检、或转去联网搜索),而不是拿着烂资料硬答。
  • Self-RAG:让模型自己判断"这个问题要不要检索""检索到的这条有没有用""我的回答有没有依据",边生成边自检。
  • Agentic RAG:把检索变成 Agent 手里的工具,让它自主决定检索几次、怎么改写、要不要换数据源——用 Agent 的循环能力处理复杂问题。这是当前的主流演进方向,本质是把上面这些优化"编排"起来交给模型动态决策。

举例:简单知识库问答,做好忠实度约束 + 引用就够;对准确性要求极高、又常遇到检索不稳的场景,上 CRAG/Agentic RAG 让它能自我补救。

对症下药速查表

优化不是全都堆上,而是"哪疼治哪"。按症状查:

症状(现象)大概率的病根对应优化手段
换个说法就搜不到用词不匹配多查询改写、混合检索、HyDE
精确词(型号/编号)搜不准向量对字面弱混合检索(加 BM25)
答案资料明明有却排太后排序粗糙重排序(rerank)
一块里噪音多、答偏分块太大父子分块、上下文压缩
表格类问题全错解析没做好表格结构化解析
多步/对比型问题答不全单次检索够不着查询分解、Agentic RAG
"关系型/全局汇总"问题搞不定片段间关系丢失知识图谱(GraphRAG)
模型爱编、加戏生成没约束忠实度约束、引用溯源、CRAG
检索到一堆重复内容缺多样性MMR
长上下文里的信息被忽略中间迷失LongContextReorder
不同人看到不该看的资料没权限过滤元数据过滤(权限前置)

一个务实的优化顺序

别想着一口气全上。真实项目里我建议这个节奏:

先打地基(解析干净 + 合理分块 + 元数据)→ 搭基线并建评测集(没有尺子后面无法判断优化是否有效)→ 上混合检索 + 重排序(性价比最高的两招,通常一下就能把效果拉上一个台阶)→ 按评测集的错题分布,针对性加查询改写/父子分块/压缩等 → 只有当核心问题确实是关系型/多跳时,才评估 GraphRAG只有当需要动态多步检索时,才上 Agentic RAG

每加一个优化,都用评测集验证它真的带来了提升——很多"听起来高级"的技巧,在你的具体场景里未必有用,甚至帮倒忙。用数据说话,别凭感觉堆技术。

小结

RAG 优化是一个贯穿五个阶段的系统工程:建索引(解析/分块/元数据/索引增强)、查询理解(改写/分解/路由)、检索(向量/关键词/混合/图谱)、检索后(重排/压缩/MMR/重排位置)、生成(约束/溯源/自纠)。

但比记住这些技术更重要的是那套方法论先诊断是哪一环的锅,再对症下药,每一步都用评测集验证,能简单就别复杂。 GraphRAG、Agentic RAG 这些"重武器"很酷,但它们是"确实需要了"才上的——大多数场景,把混合检索、重排序、好的分块这几样做扎实,就已经是一个很能打的 RAG 了。