RAG 为什么会产生幻觉?如何降低 RAG 幻觉问题?
很多人使用 RAG,是因为觉得:
“只要给大模型提供知识库,它应该就不会胡说了吧?”
实际上并不是。
RAG 虽然能够显著降低大模型幻觉,但它并不能彻底消除幻觉。
甚至有时候会出现一种更麻烦的情况:
检索出来的资料是错的,而大模型非常自信地根据错误资料给出了答案。
所以,一个成熟的 RAG 系统,除了关注“能不能检索到内容”,还必须关注一个问题:
如何降低幻觉。
一、什么是 RAG 的幻觉?
简单来说:
RAG 幻觉,就是模型生成了检索资料无法支持的内容。
例如用户问:
Redis 默认端口是多少?
知识库里实际上没有相关内容。
但是模型回答:
Redis 默认端口是 6379。
这个答案虽然事实上可能是对的,但如果我们的系统要求:
必须严格根据企业知识库回答
那么这依然属于一种幻觉。
因为这个答案不是来自 RAG 检索到的资料,而是来自模型自己的参数知识。
再比如:
检索结果只写了:
公司提供 7 天退款服务。
模型却回答:
公司提供 7 天无理由退款,
退款通常会在 3~5 个工作日到账。
其中:
7 天退款
有文档依据。
但:
无理由退款
3~5 个工作日到账
文档里根本没有。
这就是典型的 RAG 幻觉。
二、RAG 为什么还是会产生幻觉?
RAG 的工作流程大概是:
用户问题
↓
检索知识库
↓
找到相关 Chunk
↓
把 Chunk 交给 LLM
↓
LLM 生成答案
所以任何一个环节出问题,都可能产生幻觉。
常见原因主要有下面几种。
1. 根本没有检索到正确资料
例如用户问:
产品 A 是否支持退款?
Retriever 却找到了:
产品 B 的退款政策
产品 A 的付款方式
产品 C 的售后政策
这些内容“看起来相关”,实际上无法回答问题。
如果仍然把这些内容交给模型,模型就可能自己拼一个答案出来。
所以很多所谓的:
LLM 幻觉
实际上首先是:
Retrieval Failure,检索失败。
三、第一道防线:限制模型只能根据文档回答
这是最简单,同时也是非常重要的一层。
在 System Prompt 或 Prompt 中明确要求:
请严格根据提供的 Context 回答问题。
如果 Context 中没有足够的信息回答,
请明确回答“根据当前资料无法确定”。
不要使用外部知识进行补充,
不要猜测或编造答案。
例如:
Question:
产品 A 是否支持退款?
Context:
当前文档只介绍了产品 A 的支付方式。
模型应该回答:
根据当前提供的资料,无法确定产品 A 是否支持退款。
而不是:
产品 A 应该支持 7 天退款。
这可以理解为:
让模型学会说“不知道”。
在企业 RAG 中,这往往比“什么问题都必须回答”更加重要。
四、第二道防线:通过相似度阈值过滤低质量结果
这是非常常见,也是我实际比较推荐的方法。
向量数据库检索通常会返回:
Document
+
Similarity Score
例如:
| 文档 | 相似度 |
|---|---|
| Doc A | 0.91 |
| Doc B | 0.86 |
| Doc C | 0.72 |
| Doc D | 0.43 |
我们可以设置:
Similarity Threshold = 0.7
那么:
Doc A
Doc B
Doc C
会进入 Context。
而:
Doc D
会被过滤掉。
整体流程就变成:
Vector Search
↓
Similarity Score
↓
Threshold Filtering
↓
高质量 Chunk
↓
LLM
这样可以避免:
为了凑 Top K,硬塞几个其实根本不相关的文档给模型。
五、但相似度阈值不能乱设
这里需要注意一个很容易踩的坑。
例如直接规定:
Similarity > 0.8
不一定适用于所有 Embedding 模型和向量数据库。
因为不同系统中的:
Cosine Similarity
Dot Product
Euclidean Distance
Reranker Score
分数含义都可能不同。
甚至不同 Embedding 模型的分数分布也完全不同。
所以更合理的方法是:
准备 Evaluation Dataset
↓
测试不同 Threshold
↓
观察 Recall / Precision
↓
选择合适的阈值
因为阈值过低:
垃圾内容太多
→ 容易产生幻觉
而阈值过高:
真正有用的资料也被过滤
→ Recall 下降
→ 模型没有资料可回答
所以本质上是在平衡:
Precision 和 Recall。
六、第三道防线:给检索结果明确标注来源
另外一个很有效的方法是:
让模型知道每一段信息从哪里来。
例如不要只是传:
Redis 使用内存存储数据,因此访问速度很快。
而是传:
[source: redis_architecture.md]
Redis 使用内存存储数据,因此访问速度很快。
甚至可以携带更多 Metadata:
Source:
redis_architecture.md
Section:
Performance
Updated:
2026-08-10
Content:
Redis 使用内存存储数据……
然后要求模型回答时给出来源:
Redis 的高性能主要来自内存访问和高效的数据结构。
来源:
redis_architecture.md
这样至少有两个好处:
第一,模型更容易区分:
哪些是知识库信息
哪些是自己的推理
第二,用户能够验证答案。
因此实际企业 RAG 非常推荐:
Answer
+
Citation
而不是只返回一个裸答案。
七、第四道防线:增加置信度信息
还可以进一步告诉模型:
这条检索结果到底有多可靠?
例如:
Document A
Similarity: 0.93
Confidence: High
Document B
Similarity: 0.81
Confidence: Medium
甚至可以设计:
0.90 ~ 1.00 → High
0.75 ~ 0.90 → Medium
< 0.75 → Low
然后 Prompt 中规定:
优先使用 High Confidence 内容回答。
Medium Confidence 内容只能作为补充。
不要使用 Low Confidence 内容生成确定性结论。
这比单纯把一堆 Chunk 扔给 LLM 更好。
不过这里要注意:
Similarity Score 不完全等于真正的“可信度”。
它通常更准确地表示:
Query 和 Document 在语义上有多接近。
所以真正成熟的系统往往还会结合:
Similarity
+
Reranker Score
+
来源权威性
+
文档更新时间
综合计算 Confidence。
八、第五道防线:使用 Reranker 二次排序
现在很多 RAG 系统都会使用:
Retriever
+
Reranker
例如第一阶段:
Vector Search
↓
Top 20
先快速找出 20 个候选文档。
然后:
Reranker
↓
重新判断 Query 和 Document 的真正相关性
↓
Top 5
最后只把最相关的内容交给 LLM。
整个结构:
Query
↓
Vector Search
↓
Top 20
↓
Reranker
↓
Top 5
↓
LLM
为什么这么做?
因为 Embedding Search 比较擅长:
快速找到“语义差不多”的东西。
而 Reranker 更擅长:
判断“这个文档到底能不能回答这个具体问题”。
因此使用 Reranker 通常能够减少很多:
看起来相关、实际上答非所问
的 Context。
自然也会降低幻觉。
九、第六道防线:Hybrid Search
只使用向量搜索,有时候也会出现问题。
例如用户问:
ERROR_CODE_10451 是什么?
这种:
产品编号
错误码
订单号
函数名
专业缩写
Embedding Search 未必特别擅长。
这时候可以结合:
Vector Search
+
BM25
也就是:
Hybrid Search
向量搜索负责:
语义相关性
BM25 负责:
关键词匹配
二者结合以后:
Query
↓
Vector Search ─┐
├→ Merge → Reranker → LLM
BM25 Search ───┘
可以进一步提高检索可靠性。
而检索质量越高:
大模型胡说八道的机会通常就越少。
十、第七道防线:Context 不要越多越好
很多人在做 RAG 时,会有一个误区:
怕模型不知道,所以多塞几个 Chunk。
例如:
Top 20
全部给模型。
实际上这可能反而让效果变差。
因为 Context 中可能同时出现:
正确资料
+
无关资料
+
过期资料
+
重复资料
+
相互矛盾的资料
模型就可能开始:
混淆
拼接
错误归纳
所以:
Context 不是越多越好,而是越相关越好。
相比:
20 个一般相关的 Chunk
很多情况下:
3~5 个高度相关的 Chunk
反而效果更好。
十一、第八道防线:处理相互冲突的文档
企业知识库还有一个非常现实的问题:
不同文档可能互相冲突。
例如:
旧文档:
退款期限为 7 天。
新文档:
退款期限调整为 14 天。
如果两个文档同时进入 Context,模型可能不知道相信谁。
所以最好保留 Metadata:
source
version
updated_at
department
authority_level
然后制定规则:
优先使用最新版本
↓
优先使用官方政策
↓
优先使用权威数据源
例如:
官方产品文档
>
内部 Wiki
>
历史聊天记录
这也是减少 RAG 幻觉非常重要的一环。
十二、第九道防线:生成答案之后再做一次验证
更加严格的系统不会:
LLM 生成答案
↓
直接返回
而是:
LLM 生成答案
↓
Answer Verification
↓
检查答案是否能够被 Context 支持
↓
通过
↓
返回用户
可以让另一个 LLM 判断:
答案中的每一个核心事实,
是否都能够在 Context 中找到依据?
例如:
Answer:
退款期限是 14 天。
Context:
用户可以在付款后 14 天内申请退款。
Result:
SUPPORTED
如果答案是:
退款期限是 30 天。
则:
Result:
UNSUPPORTED
这类方法通常叫:
Groundedness Check
Faithfulness Check
Answer Verification
也就是检查:
答案是不是忠于检索到的资料。
十三、一个比较完整的 RAG 防幻觉流程
实际项目中,我比较推荐这样的结构:
User Query
↓
Query Rewrite
↓
Hybrid Retrieval
Vector + BM25
↓
Similarity Threshold
↓
Reranker
↓
Top K Context
↓
Source + Metadata + Confidence
↓
LLM
↓
Groundedness Check
↓
Final Answer + Citation
也就是说,不应该只依赖 Prompt:
“请不要产生幻觉”
而应该从整个 Pipeline 控制。
十四、一个简单实用的 Prompt
例如可以这样设计:
你是一个基于企业知识库回答问题的助手。
请严格根据提供的 Context 回答问题。
规则:
1. 不要使用 Context 之外的信息补充答案。
2. 如果 Context 无法支持答案,请明确回答:
“根据当前知识库内容,无法确定。”
3. 不要猜测。
4. 如果多个资料存在冲突,
优先使用更新时间较新、可信度较高的资料。
5. 回答中的关键结论必须标注来源。
6. 不要把推测表达成事实。
Context:
[Source: refund_policy_v3.pdf]
[Confidence: High]
[Updated: 2026-08-01]
用户购买产品后,
可以在 14 天内申请退款。
最终回答:
该产品支持购买后 14 天内申请退款。
来源:refund_policy_v3.pdf
这样的回答就比单纯:
支持 14 天退款。
更加可靠。
十五、RAG 防幻觉的核心思路
其实可以总结成三个阶段。
第一层:控制输入
确保:
真正相关的知识
↓
才进入 Context
常用方法:
Similarity Threshold
Hybrid Search
Reranker
Metadata Filtering
Top K 控制
第二层:控制生成
要求模型:
只根据 Context 回答
↓
不知道就说不知道
↓
不要自行补充
↓
引用来源
主要依靠:
Prompt Engineering
+
Structured Context
第三层:控制输出
模型回答完以后再判断:
这个答案真的有依据吗?
常用:
Groundedness
Faithfulness
LLM-as-a-Judge
Citation Verification
最终形成:
高质量检索
↓
可靠 Context
↓
受约束生成
↓
答案验证
↓
带来源的最终答案
总结
RAG 幻觉并不是单纯的“大模型喜欢胡说”。
很多情况下,真正的问题其实发生在:
检索
↓
Context
↓
生成
整个链路里面。
所以一个比较可靠的 RAG 系统,通常会同时做:
Prompt 限制模型只能根据文档回答
+
Similarity Threshold
过滤低相关结果
+
Hybrid Search / Reranker
提高检索质量
+
Source / Metadata / Confidence
让信息来源更加明确
+
Groundedness Check
验证最终答案
+
无法回答时允许模型说“不知道”
其中最重要的一点是:
RAG 防幻觉的目标并不是让模型“永远回答”,而是让模型只在有足够证据的时候回答。
对于企业知识库来说:
一个明确的“根据当前资料无法确定”,往往比一个听起来非常专业、但没有依据的答案更有价值。