
前面两篇我们讲了 Agentic RAG 的整体架构和查询路由。路由解决的是"该不该查"的问题。但还有一个更致命的问题没回答:
查了,但查出来的东西是垃圾,怎么办?
传统 RAG 管线是"检索即信任"——向量库返回什么,LLM 就基于什么生成。哪怕检索出来的文档完全不相关,系统也会硬着头皮编答案。结果就是幻觉。
自我纠正 RAG 的核心思想只有一句话:在生成之前,先让系统评估一下检索结果到底行不行。不行就不要硬上,走纠正路径——重写查询、换知识源、或直接告诉用户"我不知道"。
一、传统 RAG 的"盲信"问题
来看一个真实场景:用户问"2026 年杭州公积金贷款额度上限是多少?"
向量库里存的文档可能是 2024 年的政策。相似度很高(都是公积金贷款),但内容过时了。
传统 RAG 怎么做的?直接把这个 2024 年的文档塞进 Prompt,让 LLM 基于过时内容回答。输出的答案可能是旧数据,但用户看不出来——因为它写得非常自信。
问题出在哪?
❗ 系统没有任何环节去判断"检索到的文档是否真的能回答这个问题"。这就是盲信。
二、CRAG 的解决方案
Corrective RAG(CRAG)是 2024 年提出的框架,核心思想很朴素:
💡 在检索和生成之间,插入一个"评估-纠正"环节。
2.1 文档相关性评分
检索完成后,不急着生成。先让一个 LLM(或轻量分类器)对每篇文档打分:这篇文档和问题相关吗?能回答吗?结果分三级:
✅ Correct(正确):包含回答所需信息,可直接使用
❌ Incorrect(不相关):和问题没关系,或信息过时/错误
❓ Ambiguous(模糊):有一定相关性,但不确定能否充分回答
2.2 三级判定后的不同动作
这是 CRAG 最核心的设计:
判定 Correct → 走正常生成,但先做"知识精炼",剥掉无关段落,只留真正回答问题的部分。
判定 Incorrect → 完全放弃检索结果,触发 Web 搜索回退,重新找答案。
判定 Ambiguous → 两边都做。既保留当前文档的精炼结果,又同时触发 Web 搜索,最后合并两个来源。
2.3 知识精炼(Knowledge Refinement)
这一步经常被忽略但非常关键。即使文档被判为"正确",CRAG 也不会原封不动扔给 LLM,而是做一次"分解-重组":
把文档拆成更细粒度的知识单元 对每个单元再做一次相关性评分 只保留高相关单元,丢弃其余部分
好处:减少噪音,降低 LLM 被无关信息干扰的概率。
三、Self-RAG 的另一种思路
Self-RAG 是另一个自纠正方案,切入点和 CRAG 不同:CRAG 在"检索后、生成前"做纠正,Self-RAG 则更激进——
让模型自己决定什么时候该检索、检索结果好不好、生成的答案对不对。
Self-RAG 的核心是引入了四种"反思 Token":
整个流程是这样的:
拿到问题,先自问:"我需要检索吗?" 需要的话执行检索,再自问:"检索到的文档和问题相关吗?" 相关就基于文档生成,再自问:"我的答案被文档支持吗?" 最后自问:"这个答案对用户有用吗?" - 任何一步判定"不行",就回退重来。
Self-RAG vs CRAG 的区别
对于大多数生产场景,CRAG 的思路更容易落地——它不要求微调模型,只要在管线里加一个文档评分步骤就行。
四、Critic Agent 模式
实际工程中,很多团队把 CRAG 和 Self-RAG 的思想提炼成一个通用的"Critic Agent"模式:专门设一个 Agent,它不负责回答问题,只负责"挑毛病"。
Critic Agent 的职责清单:
检索结果是否相关(Retrieval Grading) 检索结果是否充分(Sufficiency Check) 生成结果是否被文档支持(Faithfulness Check) 生成结果是否真的回答了问题(Answer Relevancy)
三层评估流水线
ActiveWizards 在实践中提出了一个三层评估结构,非常值得参考:
① 第一层:检索相关性评估
对每篇文档判断它和查询的相关程度 → 输出保留/丢弃决策。
② 第二层:回答支持度评估
生成答案后逐句检查:这句话能否在文档中找到依据?→ 输出每句话的支持度标签(Supported / Not Supported / Partially)。
③ 第三层:答案有效性评估
综合判断:这个答案真的回答了用户的问题吗?→ 输出通过/需要重新生成。
三层都通过,才输出给用户。任何一层失败,触发对应的纠正动作。
五、Web 回退策略
当知识库确实回答不了用户问题时,退回去用搜索引擎是合理的降级方案。但 Web 回退不是简单调一下搜索 API,有几个工程细节要注意。
5.1 什么时候触发回退
不是检索到一个不相关文档就立刻回退。推荐策略:
top-5 文档中超过 3 篇被判为 Incorrect → 触发回退 所有文档相关性分数都低于阈值(比如 0.3)→ 触发回退 Ambiguous + 问题含时间敏感词("最新""现在""2026 年")→ 触发回退
5.2 搜索结果怎么处理
Web 搜索返回的内容质量参差不齐。拿到后也要走一遍和知识库文档同样的评估流程:
提取正文(去广告、导航栏等噪音) 对提取的内容做相关性评分 只保留相关的段落 融合进最终的上下文中
5.3 来源标注
用户需要知道"这个答案来自哪里"。如果答案来自 Web 回退而非知识库,需要明确标注来源,让用户自己判断可信度。
六、查询重写触发
检索结果不好,除了换知识源(Web 回退),另一条路是换种问法再查一遍。当 Critic Agent 判定检索结果不行时,不立刻放弃,先尝试改写用户的查询。
重写策略
① 补充上下文:"额度多少" → "2026 年杭州住房公积金个人贷款最高额度"
② 换个表达方式:"怎么申请" → "申请流程步骤方法"
③ 拆分子问题:"公积金贷款和商贷哪个划算" → "公积金贷款利率" + "商贷利率" + "对比条件"
重写次数限制
查询重写不能无限循环。实践中一般设置:
- 最多重写 2 次
两次重写后仍不达标,走 Web 回退或直接返回"无法回答" 每次重写前先对比新旧查询的语义距离,差别不大就不浪费这次机会
七、生产落地要考虑的事
延迟增量
加了自纠正环节后整体延迟会增加,具体取决于用什么做 Grader:
LLM(GPT-4o / Claude)做 Grader:每次评估 +500ms-1.5s 轻量分类器(fine-tuned BERT / 小模型):+50-200ms 规则 + 阈值做初筛、超阈值再用 LLM 精评:折中方案
💡 推荐两级分流:先用向量相似度分数粗筛(几乎零成本),只对"模糊地带"调用 LLM 精评。
成本控制
每多一次 LLM 调用就多一笔钱。控制方法:
不是每个查询都要走自纠正。检索结果相似度很高的可以直接信任 高置信度结果跳过评估,只对中等置信度的文档做 Grading 用小模型做 Grader(GPT-4o-mini 就够),不需要最贵的模型
评估 Grader 本身的质量
Grader 判断错了怎么办?这是个容易被忽略的问题。如果 Grader 把相关文档判成不相关(假阴性),会导致好文档被丢弃,答案反而变差。解决方法:
定期用人工标注的测试集评估 Grader 准确率 记录 Grader 的判定日志,做事后分析 设置"宁可多留不要多丢"的偏好(recall 优先)
八、完整流程图
把以上内容串起来,一个带自纠正能力的 RAG 管线长这样:
👤 用户查询 ↓🔀 查询路由 → 不需检索 → 直接回答 ↓ 需要检索🔍 检索执行 ↓⚖️ 文档相关性评估(Grader)
✅ Correct → 知识精炼
❓ Ambiguous → 知识精炼 + Web 搜索 → 结果合并
❌ Incorrect → 查询重写 → 重新检索 → 还不行?→ Web 回退
↓ 三条路汇合✍️ 统一生成 ↓🔎 答案验证(Faithfulness + Relevancy) ↓✅ 通过 → 输出给用户❌ 不通过 → 重新生成(最多 1 次)
#RAG #AgenticRAG #自我纠正 #CRAG #大模型应用
第16篇
夜雨聆风