RAG 也会胡说:怎么把幻觉压下去

2026-07-28

数据截至 2026-07,规范与各项目能力以官方文档当前版本为准。

RAG 不是幻觉的解药,它只是把幻觉的来源从”模型脑子里的记忆”换成了”检索回来的那几段文字”。只要检索段有可能空手而归、有可能捞回不相干的内容,模型就仍然有编的空间。真正能把幻觉压下去的,是一整套约束:让模型只在证据里说话、说不出来就明说没有、每句话都能回溯到原文、再用评估把每次改动的效果钉死。

很多团队上线知识库问答时抱着一个默认假设:既然答案是从自己的文档里检索出来的,那模型就不会瞎编了。真实情况是,接上 RAG 之后幻觉的总量通常会明显下降,但性质会变得更麻烦——以前模型是凭空编,一眼能看出不靠谱;现在它是拿着三段真实文档,编出一句文档里根本没写的结论,还顺手附上了看起来很像的出处。这种错误更难被业务方发现,杀伤力反而更大。

如果你还不清楚 RAG 的基本链路,可以先看 RAG 是什么?一文讲清给大模型外挂知识库的原理;关于模型幻觉本身的成因,大模型为什么会「胡说八道」? 讲得更基础。这篇只谈一件事:RAG 已经搭起来了,答案还是不可信,接下来怎么办。

一、先把”胡说”拆成三类,别一锅烩

调优失败的第一原因,是把所有错误都归给”模型不行”,然后一路去换更贵的模型。实际上 RAG 里的胡说至少要分成三种,每种的修法完全不同。

第一类:根本没检索到。 知识库里压根没有这条信息,或者有但没被召回。此时模型面对的是一堆不相干的上下文,它要么老老实实说不知道(多数默认提示词下它不会这么做),要么就用自己的预训练记忆凑一个答案出来。这类错误的责任在检索段和语料覆盖,改提示词基本无效。

第二类:检索到了,但没用上。 正确的段落确实进了上下文,但排在很靠后的位置,或者被十几段噪声淹没,模型注意力没落在上面。表现是”明明文档里写了,它却说没有”,或者答了个半截。这类问题的解法在重排和上下文组装,不在模型。

第三类:检索到了,读错了或糅合了。 这是最隐蔽的一类。模型把两份不同年份、不同产品线的文档揉成一句话,或者把”建议值”读成”强制要求”,把”部分场景适用”读成”全部适用”。跨文档的数字合并、条件从句的丢失,都属于这一类。

判断属于哪一类有个笨办法但很有效:把出错的问题拿出来,先人工看一眼检索回来的原始片段。片段里没有答案,是第一类;片段里有但答案没体现,是第二类;片段里有而模型说反了、说串了,是第三类。做二三十条就能看出你的主要矛盾在哪,比盲目换框架靠谱得多。

二、把提示词从”参考资料”改成”证据边界”

默认的 RAG 提示词大多是这么写的:「以下是相关资料,请根据资料回答用户问题」。这句话的问题在于,它把检索结果定位成参考,而不是边界——模型完全可以理解为”资料只是辅助,我自己知道的也能用”。

改法是把约束写死,至少包含这几条:

  • 只使用给定材料中出现的信息作答,材料之外的知识一律不引入;
  • 材料不足以回答时,直接回复”提供的资料中没有相关信息”,不要推测、不要补全;
  • 材料之间互相冲突时,不做调和,把冲突如实指出来并列出各自出处;
  • 每一条结论后面标注它来自哪个片段编号。

第三条经常被忽略,但它对付的正是第三类幻觉。文档库跑了两年之后,同一个问题在不同文件里有不同说法几乎是必然的,模型的默认倾向是找一个自洽的说法讲出来,而不是告诉你”你们自己文档打架了”。把”允许指出冲突”明确写进去,它才会这么做。

还有一个实践细节:给检索片段编号,并在提示词里要求模型用 [1][2] 这样的标记回引。这不只是为了显示引用,更是一种行为约束——当模型被要求为每句话找编号时,它编造无出处内容的倾向会下降,因为编出来的句子挂不上任何一个编号。

三、让每句话可回溯,把核查成本交给用户

引用不是装饰。企业场景里,用户对 AI 答案的信任是靠能随时抽查建立起来的,而不是靠答案本身看起来专业。

可落地的做法有几层,按成本从低到高:

  1. 文档级引用:答案末尾列出用到了哪几篇文档。最容易实现,但用户点进去还得自己找,核查成本高,实际很少有人点。
  2. 片段级引用:每段结论后面挂片段编号,点击展开原文。这是性价比最高的一档,大多数团队做到这里就够。
  3. 句级定位与高亮:点引用直接跳到原文档对应位置并高亮。体验最好,但要求你的解析环节保留了片段在原文中的位置信息(页码、字符偏移),这件事必须在建索引时就做,事后补不回来。

第三档的前提值得强调一下:能不能做精确定位,取决于文档解析阶段有没有保留结构与位置元数据。如果你的入库流程是”PDF 转纯文本再按固定长度切块”,位置信息在第一步就丢光了。这是很多团队后期想加高亮却发现做不了的原因。

四、允许模型说”不知道”,并给拒答留兜底

一个反直觉的经验:能压住幻觉的系统,都有一条明确的拒答通路。如果产品设计上要求”必须给出答案”,那幻觉就是被制度逼出来的。

拒答通路一般由两个部分组成。一是检索侧的阈值判断——当召回结果的相关性分数普遍低于某个水平时,直接不进入生成环节,返回”没有找到相关资料”。阈值具体设多少没有通用值,只能拿你自己的评估集试出来,通常从宽松开始逐步收紧,观察漏答率和错答率的此消彼长。二是生成侧的自我判断——在提示词里明确给出”资料不足”这个合法出口,并且在少样本示例里真的放一个拒答的例子。只在文字里说”可以拒答”而示例全是正面回答,模型学到的还是”要回答”。

拒答之后不能是死路。比较稳妥的兜底:把用户问题转成检索关键词展示出来(让用户知道系统找了什么)、列出最接近的几篇文档标题、提供转人工或提交知识补录的入口。这几步做完,一次拒答会变成一条知识库缺口线索,而不是一次糟糕的体验。

五、上游治理:解析和分块决定了证据的质量

前面几节都在生成侧做文章,但如果证据本身是碎的、错的,再好的提示词也救不回来。这也是为什么调 RAG 常常要回到最上游。

解析环节的典型翻车点:扫描版 PDF 的表格被拉成一行乱序文本、跨页的表格被切成两半、页眉页脚混进正文、多栏排版被按行读串。这些错误进了索引,检索得越准,模型读到的错误内容就越确定,幻觉反而更难识别。这类问题的详细拆解见 RAG 效果差?先确认瓶颈是不是在解析这一步

工具层面,如果你的瓶颈确实在解析,从面向文档理解的方案入手比在检索侧硬调更有效。RAGFlow 是开源 RAG 引擎里在这个方向着力比较明显的一个,它的分块会尊重文档结构,并带有版面感知的解析和内置的知识图谱构建,官方定位上适合扫描版 PDF、财报、版式复杂的法律文书这类传统文本解析器搞不定的语料;LlamaIndex 一侧的 LlamaParse 也是常见选择。具体能力边界以各项目官方文档当前版本为准。

分块环节要守的原则是:一个块要能独立看懂。被切断的条件从句、脱离标题的数字表格、缺了主语的补充说明,都会诱发第三类幻觉。实践中常用的补救是给每个块补上”文档标题 + 章节路径”作为前缀,让块自带上下文;对于表格,宁可整表不切,也不要按行切。

六、检索段:召回不到就一定会编

第一类幻觉的根在召回。纯向量检索对精确名词(型号、编号、人名、专有缩写)并不擅长,这些恰恰是企业问答里最常被问到的东西。混合检索(关键词 + 向量)加重排,是目前最常规也最有效的组合拳,具体的调优顺序在 RAG 检索调优:嵌入、混合检索与重排的取舍 里展开得更细。

这里只补充跟幻觉直接相关的两点。

一是重排比扩大召回数量更值得先做。很多人发现答不准就把 top-k 从 5 调到 20,结果噪声也翻了四倍,第二类幻觉(检索到了没用上)反而变多。正确顺序通常是召回放宽、重排收紧,最终送进上下文的还是少而准的几段。

二是语料本身有链接结构时,图检索能减少跨文档糅合。当知识点之间存在明确的引用、从属、版本演进关系(比如制度文件的引用链、产品文档的继承关系),基于图的检索能把关联段落一起带出来,模型就不容易只看到半截而自行脑补。RAGFlow 内置了知识图谱构建能力,GraphRAG 怎么用 里有更具体的适用判断。这条路的代价是构建成本明显更高,不是所有语料都值得。

七、后置校验:让另一次调用来挑刺

前面所有手段都是”事前预防”,还有一类是”事后拦截”:答案生成之后,再跑一次校验,把明显没有证据支撑的部分标出来或者打回。

常见的三种做法:

  • 逐句核对:把答案拆成句子,逐句问模型”这句话能否由给定片段推出”,不能的标为存疑。准确率不错,代价是调用次数随句子数线性增长。
  • 数字与实体抽查:只校验答案里出现的数字、日期、人名、型号,检查它们是否在片段中原样出现。成本低很多,能挡住相当一部分最容易被投诉的错误。
  • 二次生成对比:同一问题跑两次,比较结论是否一致,不一致的转人工。适合高风险场景,成本翻倍。

后置校验的代价必须算清楚:它会拉长响应时间、增加 token 消耗。实际部署里比较务实的做法是分级——普通查询不校验,命中敏感关键词(价格、合同、合规、医疗、财务)的查询才走完整校验。全量校验听起来严谨,但多数团队撑不住成本,最后往往整个关掉,还不如一开始就只保住关键路径。

八、用评估把每次改动钉住

到这一步会出现一个新问题:前面这些手段互相影响,改了提示词可能让拒答率飙升,加了重排可能让延迟不可接受。凭感觉判断”好像好一点了”,是 RAG 调优最常见的沉没成本来源。

必须有一个固定的评估集:几十到几百条真实问题,配上人工确认的标准答案和应当命中的原文片段。每次改动跑一遍,看四个方向的变化——检索有没有命中该命中的、答案有没有超出证据范围、该拒答的有没有拒答、不该拒答的有没有误拒。评估工具方面,RAGAS 这类可以加挂到你已有的框架上,不需要更换技术栈。具体怎么建评估集、怎么读指标,见 RAG 怎么评估?凭感觉调是调不出来的

评估集的价值不只在于选出更好的方案,更在于防止回退。RAG 系统改到第三个月,最常见的事故不是没优化,而是为了修某一类问题引入的改动,悄悄破坏了原本正常的另一类。

九、框架选择:按瓶颈选,别按名气选

顺带回应一个常被问到的问题:为了降幻觉,是不是该换个框架?

先看一组关注度数据。第三方统计的截至 2026 年 1 月的 GitHub star 排名大致是:LangChain 约 125,000、Dify 约 114,000、RAGFlow 约 70,000、LlamaIndex 约 46,500、Haystack 约 24,000。这个数字只反映关注度,不代表它对你的场景更合适,更不代表换过去幻觉就少了。

按瓶颈选更实际:解析烂 PDF、表格、扫描件是瓶颈,从 LlamaIndex(LlamaParse)或 RAGFlow 入手;瓶颈在检索(嵌入、混合检索、重排)的,LangChain、Haystack、Cognita 可调的旋钮更多;瓶颈在评估的,不用换框架,在现有基础上加挂 RAGAS 即可;语料是有链接的结构化内容,考虑图检索。

还有一点常被误解:这些框架不是互斥的。生产环境里比较常见的组合是 LlamaIndex 做 ingestion 与索引、LangChain 做编排、LangGraph 做 agent 工作流。延伸判断可以看 RAG 框架怎么选?按瓶颈选,别按 star 数选LangChain 和 LlamaIndex 的分工:一个广一个深

需要提醒的是选型的代价也要算。有第三方评测指出,LangChain 的 LCEL 语法能做复杂的查询重写,但相比 LlamaIndex 的直接检索会多出约 15%-20% 的延迟开销——这是第三方基准口径,不是官方指标,只能当作”存在这类开销”的提示,别当成验收标准。自托管方面,RAGFlow 走 Docker 部署,提供 slim(2GB)与 full(9GB)两种镜像,区别是是否内置嵌入模型;LangChain 和 LlamaIndex 本质是库,所谓自托管就是自己跑 Python 服务和向量库。常配的向量库里 Qdrant 支持过滤、payload 索引与量化,第三方称在 100 万以上向量规模下可做到 50 毫秒以内检索,同样属于第三方口径,实际表现取决于你的硬件与配置。以上能力细节均以各项目官方文档当前版本为准。

十、说清楚局限

最后必须诚实一点:上面这套做完,幻觉会显著减少,但不会归零。

一是语料缺失无法用技术弥补。文档里没写的东西,任何检索策略都变不出来,最好的结果是系统诚实地说不知道。知识库的持续维护是运营问题,不是技术问题。

二是歧义问题天然难办。用户问”这个多少钱”,而知识库里有三个版本三种定价,系统要么反问澄清,要么如实列出三种情况,两种都不如”直接给一个数”来得爽快,但后者才是幻觉。这里存在体验与准确性的真实取舍,需要产品侧拍板,不该由工程侧偷偷替用户决定。

三是校验本身也会出错。用模型校验模型,校验器同样有误判,它可能把正确答案标成存疑,也可能放过错误。它是概率上的改善,不是保证。

四是指标好看不等于用户满意。评估集是你自己挑的题,真实用户的提问分布永远比它更野。上线后持续抽样真实对话回灌进评估集,比反复打磨那几十道老题更有价值。

小结

RAG 里的幻觉不是一个开关,而是一条链路上多处泄漏的叠加,第一步永远是把错误分到没检索到、检索到没用上、用错这三类里,再对症下药。生成侧靠证据边界式的提示词、句级引用和明确的拒答出口;上游靠解析与分块保住证据质量;检索侧靠混合召回加重排减少空手而归。高风险问题再加一层后置校验,并按敏感度分级控制成本。所有改动都要跑同一个评估集,既为了选优,也为了防止修一处坏一处。最后接受它压不到零:语料缺口、问题歧义和校验器自身的误判都是真实存在的边界,把这些边界如实告诉使用者,比让系统装作无所不知要可靠得多。

接下来看什么

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。