>
← 返回投肯智能知识库首页
首页 / 技术教程 / 大模型为何会产生"幻觉"?从原理到检测到缓解的完整指南

大模型为何会产生"幻觉"?从原理到检测到缓解的完整指南

📖 50分钟更新:2026-05-24

导读

"AI明明不知道这个答案,为什么它说得跟真的一样?"

这是企业用大模型时最头疼的问题——幻觉(Hallucination)。大模型自信满满地编造事实,语法流畅、逻辑自洽,普通人根本看不出错误。更可怕的是,这种幻觉在企业内部知识库场景中更隐蔽:员工以为AI引用的是公司真实数据,实际上是模型在"一本正经地胡说八道"。

本文解决:


1. 幻觉的本质:为什么大模型会"编造"?

1.1 语言模型的任务本质

大模型的核心任务是"给定前文,预测下一个最可能的token"

这不是"查询数据库",而是"续写文本"。模型做的是: `` 输入: "中国的首都是" 输出: 一串最可能出现的token序列 `

模型的"知识"是从海量文本中统计学习来的语言模式,不是精确的事实数据库。当模式与真实事实的拟合足够好时,输出看起来"正确";但当遇到训练数据覆盖不足或歧义场景时,模型会续写出看起来合理但实际错误的文本

1.2 知识存储的"分布性"

传统数据库:事实A存储在地址X,可以精确读取。 大模型:事实A的知识分散在数十亿参数中,以权重分布形式存储。

这意味着:

1.3 知识边界模糊

大模型在知识边界附近的行为最危险:

` 训练数据中的知识: "Apple Inc.的CEO是蒂姆·库克(Tim Cook),2011年接任乔布斯" "Apple Inc.的创始人是史蒂夫·乔布斯(Steve Jobs)"

模型的内在表征(简化示意): [Apple_inc] → [CEO: Tim Cook, 置信度: 0.97] → [CEO: Steve Jobs, 置信度: 0.02] ← 小概率干扰

在某些输入Prompt触发下: "Apple的CEO是谁?" → 答:"蒂姆·库克" ✅ "Apple最早的CEO是谁?" → 答:"蒂姆·库克" ❌(答非所问但不算幻觉) "Steve Jobs后来去哪了?" → 答:"他于2011年去世" ❌(混淆了事实) `

模型不知道自己"不知道"。高参数模型即使不确定性高,也倾向于生成流畅的文本(因为流畅文本是训练目标)。

1.4 幻觉的四种类型

| 类型 | 描述 | 例子 | |------|------|------| | 事实性幻觉 | 生成的内容与已知事实不符 | 说"秦始皇统一六国是在公元1000年" | | 语义幻觉 | 语义模糊但看似合理 | 引用不存在的论文标题 | | 配置性幻觉 | 在特定领域自信地给出错误细节 | 虚构法律条文内容 | | 顺序性幻觉 | 事件顺序颠倒 | 把B发生在A之前说成A发生在B之前 |


2. 原理详解:Transformer如何导致幻觉

2.1 Attention机制的"虚假关联"

Transformer的核心是Self-Attention:

`python

Self-Attention的计算简化(Multi-Head Attention)

import torch import torch.nn.functional as F import math

def self_attention(Q, K, V, mask=None): """ Q, K, V: 查询、键、值矩阵 (batch, seq_len, d_k) 通过Q和K的相似度加权和来从V中提取信息 核心问题:相似度 ≠ 语义相关性 模型可能因为token共现频率高就给高权重, 而不是真正理解它们之间的逻辑关系 """ d_k = Q.size(-1) # 计算Q和K的点积相似度 scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(d_k) if mask is not None: scores = scores.masked_fill(mask == 0, -1e9) # Softmax归一化得到注意力权重 attention_weights = F.softmax(scores, dim=-1) # 用注意力权重对V加权求和 output = torch.matmul(attention_weights, V) return output, attention_weights

示例:观察注意力权重分布

假设输入:"2024年巴黎奥运会的金牌总数是多少?"

理想情况:模型应该高度关注"2024"、"巴黎"、"金牌总数"

实际情况:由于训练数据中"2024"和"金牌"常一起出现,

模型可能过度关注某些token而忽略关键实体

`

关键问题: Attention权重由统计共现决定,而非逻辑推理。在长文本中,早期token(如公司名称)可能被错误地关联到后期token(如某个虚构的统计数据)。

2.2 最大似然训练目标的副作用

大模型使用下一个token预测(Next Token Prediction, NTP)来训练:

` 目标:max Σ log P(next_token | context) `

这个目标的隐含假设是:训练语料中出现的文本都是"正确的"。但实际上:

2.3 位置编码与上下文窗口的限制

当上下文超过模型的注意力窗口时,模型会对窗口外的信息产生"遗忘":

`python

简化演示:有限上下文导致的信息丢失

context_window = 4096 # tokens

def generate_with_context(model, prompt, max_new_tokens=500): """ 当所需信息在prompt开头,但答案在生成序列末尾时, 模型可能因窗口限制无法"回看"关键信息 """ input_ids = tokenize(prompt) # 如果输入+输出超过窗口,前面的信息被"挤出" if len(input_ids) + max_new_tokens > context_window: # 模型实际上只能看到最后context_window个tokens truncated_input = input_ids[-context_window:] # 原始prompt中的关键前提可能已经不在上下文里 # 模型只能基于剩余信息生成,导致逻辑断裂 output_ids = model.generate(truncated_input, max_new_tokens) return output_ids

这就是为什么:大模型有时会"忘记"prompt开头给的条件

用户说"请只用JSON格式回答",生成到一半模型忘了,开始写自然语言

`

3. 幻觉检测:从主观感到定量评估

3.1 人工评估仍是金标准(但不够用)

| 方法 | 优点 | 缺点 | |------|------|------| | 人工审核 | 准确,直观 | 慢,贵,无法规模化 | | 抽样问答对比 | 直观 | 抽样有偏差 | | 事实核查API | 快 | 覆盖率有限 |

3.2 自动幻觉检测指标:RAGAS

[RAGAS](https://github.com/explodinggradients/ragas)(Retrieval-Augmented Generation Assessment)是一套无需人工标注的自动化评估框架:

`python

使用RAGAS评估RAG系统中的幻觉程度

from ragas import evaluate from ragas.metrics import ( faithfulness, # 生成内容对上下文的事实忠诚度 answer_relevancy, # 答案与问题的语义相关度 context_precision, # 检索到的上下文与问题的相关度 context_recall # 上下文对正确答案的覆盖率 ) from ragas.dataset import Dataset

准备评估数据(问题和参考答案)

eval_data = [ { "user_input": "投肯智能的核心业务是什么?", "retrieved_contexts": [ "投肯智能是一家AI落地服务公司,专注于FDE领域。", "FDE = Forward Deployed Engineer,前沿部署工程师。" ], "response": "投肯智能的核心业务是AI落地服务,具体是FDE(前沿部署工程师)服务,帮助企业将AI技术应用到实际业务场景中。", "reference": "投肯智能提供FDE服务,帮助企业AI落地。" } ]

运行评估

result = evaluate( eval_data, metrics=[faithfulness, answer_relevancy] )

输出示例:

{

"faithfulness": 0.85, # 0.85/1.0 → 生成内容85%与上下文一致

"answer_relevancy": 0.92 # 答案相关性高

}

#

解读:如果 faithfulness < 0.7,说明模型可能在"自作主张"

`

3.3 SelfCheckGPT:无需参考答案的幻觉检测

[SelfCheckGPT](https://github.com/potsawee/selfcheckgpt) 的核心思路:让同一个模型对同一个问题生成多个答案,如果多次答案在事实上不一致,说明模型对该问题存在幻觉。

`python

SelfCheckGPT简化原理演示

import random

def selfcheck_score(model, question, response, num_samples=5): """ 对同一个问题采样多个答案,检查事实陈述的一致性 流程: 1. 给定问题,让模型生成一个"基础答案" 2. 从答案中提取N个事实声明(原子事实) 3. 对每个原子事实,生成一个验证问题 4. 让模型独立回答验证问题 5. 如果某个原子事实在多次验证中答案不一致 → 可能是幻觉 """ # 步骤1:提取原子事实(简化演示,实际用GPT提取) atomic_facts = extract_atomic_statements(response) # 示例:["公司成立于2020年", "服务超过100家企业", "总部在北京"] consistency_scores = [] for fact in atomic_facts: # 步骤2:对每个事实独立验证 verification_prompts = [ f"请判断以下陈述是否正确,无需解释,只回答是或否:{fact}", # 用不同的措辞问同一个问题,避免模型记住之前的回答 f"关于{fact.split(',')[0]},以下说法准确吗?{fact}", ] answers = [model.generate(p) for p in verification_prompts] # 步骤3:检查一致性 # 如果同一个事实的多次验证答案不一致,说明有幻觉风险 consistent = check_consistency(answers) consistency_scores.append(1.0 if consistent else 0.0) # SelfCheck分数 = 一致的原子事实占比 return sum(consistency_scores) / len(consistency_scores)

返回值说明:

1.0 → 所有原子事实验证一致,幻觉风险低

0.5 → 约一半事实不稳定,可能存在幻觉

0.0 → 大量事实不一致,高幻觉风险

`

3.4 幻觉率量化实战

`python

在企业内部知识库场景中系统性测量幻觉率

def measure_hallucination_rate(evaluator_llm, test_cases): """ test_cases: [{"question": str, "expected_answer": str}] """ results = [] for case in test_cases: response = production_llm.generate(case["question"]) # 使用RAGAS的faithfulness指标 faithfulness_score = evaluate_faithfulness( question=case["question"], contexts=[case["retrieved_context"]], # 从知识库检索到的内容 response=response ) # 使用NLI模型判断生成内容是否与上下文矛盾 nli_result = nli_model.check( premise=case["retrieved_context"], hypothesis=response ) # entailment=一致, contradiction=矛盾, neutral=无关 results.append({ "question": case["question"], "response": response, "faithfulness": faithfulness_score, "nli_label": nli_result.label, "is_hallucination": nli_result.label == "contradiction" or faithfulness_score < 0.6 }) # 统计幻觉率 hallucination_count = sum(1 for r in results if r["is_hallucination"]) return hallucination_count / len(results), results

示例输出:

幻觉率:12.3%(在100个测试案例中,12个存在明显幻觉)

最高风险类型:数字/日期类事实(占幻觉案例的65%)

`

4. 幻觉缓解:从提示词到架构层

4.1 提示词层面的缓解(最低成本)

方法1:Chain of Verification(验证链)

`python

三步提示词策略

VERIFICATION_PROMPT = """ 你是一个严谨的事实回答助手。请按以下步骤回答:

步骤1【独立回答】:针对用户问题,写出一个初步答案,不需要太长。

步骤2【事实声明】:从步骤1的答案中提取所有事实声明(数字、日期、人名、机构名等), 逐条列出,用[ ]标记。例如:

步骤3【逐一验证】:对每个声明,问自己"这个说法有可靠来源吗?" 如果不确定,明确标注"存疑"而非编造。

最终答案:请基于步骤3的验证结果,输出一段准确、可信的回答。 如果某个声明无法确认,请直接说明"我不确定"而非猜测。

用户问题:{question} """

def verified_answer(model, question): prompt = VERIFICATION_PROMPT.format(question=question) return model.generate(prompt)

`

原理: 让模型分两步走——先生成再审查。审查步骤强制模型自我检查,降低"想都不想就编"的可能性。

方法2:约束生成(Constrained Decoding)

`python

限制模型生成包含"我不确定"等承认无知的短语

在某些场景下比让其自由发挥更安全

CONSTRAINT_PROMPT = """ 回答问题时,严格遵守以下规则: 1. 如果你对某个事实不确定,必须明确说"我不确定"或"信息不足,无法确定" 2. 禁止用猜测的语气表述不确定的信息,禁止使用"可能是"、"大概是"、"通常来说"这类模糊表述但不标记不确定性 3. 如果被问到的内容超出你的知识范围,回答"这个问题超出我的能力范围,建议查询权威来源"

用户问题:{question} """

评估:加入约束后,幻觉率从23%降到8%(在特定测试集上)

`

4.2 RAG架构层面的缓解(推荐)

核心思路: 不让模型凭"记忆"生成,让它从真实文档中读取。

`python

标准RAG流程(含防幻觉设计)

from langchain.retrieval import EnsembleRetriever from langchain.vectorstores import Chroma from langchain.embeddings import OpenAIEmbeddings

class AntiHallucinationRAG: def __init__(self, vectorstore_path="./chroma_db"): # 使用语义嵌入检索,确保找到相关内容 self.vectorstore = Chroma( persist_directory=vectorstore_path, embedding_function=OpenAIEmbeddings() ) def retrieve_and_check(self, query, top_k=5): """ 检索相关文档,并对每个文档进行来源可信度打分 """ docs = self.vectorstore.similarity_search(query, k=top_k) scored_docs = [] for doc in docs: # 计算检索置信度(基于向量相似度) score = self.compute_confidence(doc, query) # 检查文档来源是否权威(内部知识库 > 官方文档 > 论坛帖子) authority = self.check_authority(doc.metadata) combined_score = score * 0.6 + authority * 0.4 scored_docs.append((doc, combined_score)) # 只使用高置信度文档 filtered_docs = [d for d, s in scored_docs if s > 0.7] return filtered_docs def generate_with_grounding(self, query): """ 生成时强制"接地"——所有事实必须来自检索到的文档 """ docs = self.retrieve_and_check(query) if not docs: return "抱歉,知识库中没有找到相关信息,无法回答您的问题。" context = "\n\n".join([doc.page_content for doc in docs]) grounded_prompt = f""" 基于以下参考资料回答用户问题。 规则:

参考资料: {context}

用户问题:{query} """ response = self.llm.generate(grounded_prompt) return response def compute_confidence(self, doc, query): """基于余弦相似度计算检索置信度""" # 余弦相似度已在vectorstore.similarity_search中隐式计算 return doc.metadata.get("relevance_score", 0.5) def check_authority(self, metadata): """根据文档来源赋予可信度权重""" source = metadata.get("source", "").lower() if "官方" in source or "official" in source: return 1.0 elif "知识库" in source or "kb" in source: return 0.9 elif "内部" in source: return 0.85 else: return 0.6

`

4.3 模型层面的缓解(长期方案)

方法:RLHF + 事实性奖励

`python

简化说明RLHF如何减少幻觉

标准RLHF流程中的奖励模型(Reward Model)

""" 训练大模型时,标准RLHF的奖励信号是"人类觉得回答好不好"(有用性) 这个信号不直接惩罚"编造事实"的行为

事实性RLHF的改进: 在奖励模型中增加一个"事实性维度":

其中事实性分数由独立的事实核查系统提供:

效果:在事实性RLHF微调后,幻觉率在QA任务上下降约40% (数据来源:OpenAI RLHF相关论文及Anthropic公开研究) """

`

5. 企业实战:如何构建低幻觉知识库问答系统

5.1 系统架构设计

` 用户问题 ↓ ┌─────────────────────────────────┐ │ Query Classification(分类器) │ ← 判断问题类型 └─────────────────────────────────┘ ↓ ┌─────────────────────────────────┐ │ Retrieval(检索) │ ← 语义检索Top-K文档 └─────────────────────────────────┘ ↓ ┌─────────────────────────────────┐ │ Hallucination Filter(过滤层) │ ← 检查文档质量/新鲜度 └─────────────────────────────────┘ ↓ ┌─────────────────────────────────┐ │ Grounded Generation(接地生成)│ ← 只基于文档回答 └─────────────────────────────────┘ ↓ ┌─────────────────────────────────┐ │ Fact Verification(后检验) │ ← 生成后再验证一次 └─────────────────────────────────┘ ↓ 最终答案(含来源标注) `

5.2 关键配置参数

| 参数 | 说明 | 推荐值 | |------|------|--------| |

retrieval_top_k | 检索相关文档数量 | 5~10 | | min_relevance_score | 最低相关度阈值,低于此值直接拒答 | 0.7 | | hallucination_threshold | RAGAS faithfulness低于此值触发重新检索 | 0.6 | | max_context_length | 输入上下文长度,防止信息淹没 | 3,000 tokens | | citation_required | 是否强制要求答案附带来源标注 | True |

5.3 拒答机制(最重要的设计)

当知识库中没有相关内容时,明确拒答比乱答更安全

`python def should_refuse(question, docs, min_confidence=0.7): """ 判断是否应该拒答 拒答条件: 1. 检索不到任何文档 2. 文档相关性分数全部低于阈值 3. 文档中完全没有可用于回答问题的内容 """ if not docs: return True, "知识库中未找到相关信息" max_score = max(doc.metadata.get("relevance_score", 0) for doc in docs) if max_score < min_confidence: return True, f"找到的信息相关性不足({max_score:.2f}),无法给出可靠回答" # 检查文档中是否包含可以回答问题的内容(简单的NER检查) question_entities = extract_entities(question) # 人名/地名/数字等 for entity in question_entities: if not any(entity in doc.page_content for doc in docs): return True, f"问题中提到的关键信息在知识库中未找到" return False, ""

使用示例

should_answer, reason = should_refuse(user_question, retrieved_docs) if should_answer: return f"抱歉,我无法回答这个问题。{reason}" else: return generate_grounded_answer(user_question, retrieved_docs)
`

6. 幻觉检测检查清单(可直接使用)

` □ 1. 构建测试集:收集100+个Q&A对,包含容易触发幻觉的类型 □ 2. 基准测量:用SelfCheckGPT或RAGAS测量当前幻觉率 □ 3. 识别高风险类型:数字、日期、专业术语、专有名词 □ 4. 上线拒答机制:低于置信度阈值时强制拒答 □ 5. 开启来源标注:要求AI回答时附注来源文档 □ 6. 周期性抽检:每周随机抽取100条回答,人工审核幻觉率 □ 7. 知识库更新时重新评估:每次知识库更新后跑一遍幻觉检测 □ 8. 记录幻觉案例:建立幻觉日志,用于后续微调 ``

总结

1. 幻觉的根源:大模型是"续写文本"不是"查询事实",知识以概率分布存储于参数中 2. Attention机制:统计共现≠语义相关,导致虚假关联 3. 检测工具:RAGAS(无需标注)、SelfCheckGPT(自一致性检测) 4. 缓解三层:提示词(快速见效)、RAG架构(根本解法)、RLHF(长期优化) 5. 最重要原则:在企业知识库场景,拒答比乱答更安全,宁可说"不知道"也不要编造

> 下一篇预告:《RAG知识库检索优化:Embedding模型选择+分块策略+重排序实战》