幻觉:AGI 之路的隐形地雷
当智能体开始"说话",它就不可避免地会"说错话"。幻觉(Hallucination)——即模型生成看似合理但与事实不符的内容——是 AGI 领域最棘手的安全问题之一。在聊天场景中,幻觉可能只是一次尴尬的回答;但在智能体场景中,幻觉可能导致错误的工具调用、误导性的决策建议,甚至危险的实际操作。
本文将从幻觉的根源出发,系统性地介绍检测、缓解和修复策略,帮助你构建更可信赖的智能体系统。
一、幻觉的根源:为什么会"胡说八道"
1.1 训练数据层面
大模型的幻觉根源深植于其训练过程中:
训练数据的噪声:互联网数据包含大量错误信息、过时信息和矛盾信息。模型在学习时,不可避免地吸收了这些噪声。当它"回忆"某个事实时,可能提取的是错误版本。
知识截止日期:模型的训练数据有截止日期,但世界在不断变化。模型可能自信地回答一个已经过时的事实——比如一个已经废弃的 API 方法。
长尾知识稀疏:对于常见话题,训练数据丰富,模型表现可靠。但在长尾领域(冷门技术、小众领域),训练数据稀疏,模型更容易通过"编造"来填补空白。
1.2 推理机制层面
自回归生成的本质缺陷:模型逐 token 生成文本,每一步都基于前面的内容。一旦早期生成了一个错误的前提,后续内容会围绕这个错误前提展开,形成"幻觉级联"。
缺乏知识边界感知:模型不知道自己"不知道什么"。它没有可靠机制来判断某个问题是否超出了自己的知识范围,因此倾向于对任何问题都给出回答,而不是说"我不知道"。
概率而非检索:模型生成的是"最可能"的答案,而非"最准确"的答案。在需要精确事实的场景中,这种差异就表现为幻觉。
1.3 智能体场景的特殊幻觉
在智能体场景中,幻觉有了新的表现形式:
- 工具参数幻觉:模型编造不存在的参数值,或混淆不同工具的参数格式
- 工具结果误解:工具返回了正确结果,但模型在解读时加入了自己的"想象"
- 调用链幻觉:模型声称调用了某个工具但实际没有,或编造工具调用的返回结果
- 上下文遗忘幻觉:在长对话中,模型"忘记"了早期确认的事实,生成与之前矛盾的内容
二、幻觉检测:从规则到模型
2.1 基于规则的检测
最基础的检测层是规则匹配:
import re
from typing import List, Tuple
class RuleBasedHallucinationDetector:
def __init__(self):
self.rules = [
# 数字一致性检查
self._check_number_consistency,
# 实体引用检查
self._check_entity_reference,
# 日期合理性检查
self._check_date_validity,
# 自相矛盾检查
self._check_self_contradiction,
]
def _check_number_consistency(self,
claim: str,
sources: List[str]) -> List[Tuple[str, float]]:
issues = []
# 提取声明中的所有数字
claim_numbers = set(re.findall(r'\d+\.?\d*', claim))
for source in sources:
source_numbers = set(re.findall(r'\d+\.?\d*', source))
# 检查声明中的数字是否在来源中出现
for num in claim_numbers:
if num not in source_numbers:
issues.append((
f"数字 '{num}' 在来源中未找到",
0.7 # 置信度
))
return issues
def _check_entity_reference(self,
claim: str,
entities: dict) -> List[Tuple[str, float]]:
issues = []
# 检查声明中提到的实体是否存在于已知实体库
claim_entities = self._extract_entities(claim)
for entity in claim_entities:
if entity not in entities:
issues.append((
f"实体 '{entity}' 不在已知实体库中",
0.6
))
return issues
def _check_date_validity(self, claim: str) -> List[Tuple[str, float]]:
issues = []
dates = re.findall(r'\d{4}年\d{1,2}月\d{1,2}日', claim)
for date_str in dates:
# 检查日期是否合理(如未来的日期、不可能的日期)
try:
from datetime import datetime
d = datetime.strptime(date_str, '%Y年%m月%d日')
if d.year < 1900 or d.year > 2100:
issues.append((f"日期 '{date_str}' 不合理", 0.8))
except ValueError:
issues.append((f"日期 '{date_str}' 格式无效", 0.9))
return issues
def _check_self_contradiction(self,
claim: str,
history: List[str]) -> List[Tuple[str, float]]:
issues = []
# 简化的矛盾检测:检查是否与历史声明中的数字/日期矛盾
for prev in history:
prev_numbers = set(re.findall(r'\d+\.?\d*', prev))
claim_numbers = set(re.findall(r'\d+\.?\d*', claim))
# 如果同一话题但数字不同,可能存在矛盾
overlap = self._semantic_overlap(prev, claim)
if overlap > 0.5:
if prev_numbers != claim_numbers and prev_numbers and claim_numbers:
issues.append((
f"与历史声明可能矛盾: 之前说 {prev_numbers}, 现在说 {claim_numbers}",
overlap * 0.8
))
return issues
2.2 基于模型的检测
更高级的检测方案使用专门的模型来判断幻觉:
自一致性检查:让模型对同一问题生成多个回答,检查它们之间的一致性。高度不一致的回答更可能包含幻觉。
def self_consistency_check(model, question: str, n: int = 5) -> dict:
"""通过多次采样检测一致性"""
responses = []
for _ in range(n):
resp = model.generate(question, temperature=0.7)
responses.append(resp)
# 提取关键事实并比较
key_facts = [extract_key_facts(r) for r in responses]
agreement_score = calculate_agreement(key_facts)
return {
"responses": responses,
"agreement_score": agreement_score,
"hallucination_risk": 1 - agreement_score,
"consensus_facts": find_consensus(key_facts)
}
交叉验证:用另一个模型(或同一模型的不同 prompt)来验证声明的真实性:
def cross_verify(claim: str, verifier_model) -> dict:
"""使用验证模型检查声明"""
prompt = f"""请验证以下声明是否准确:
声明:{claim}
请搜索你的知识库,判断这个声明:
1. 是否准确
2. 是否包含编造的信息
3. 是否有遗漏的重要上下文
输出格式:
- 判定: [准确/部分准确/不准确/无法验证]
- 理由: [详细说明]
- 修正: [如果不准确,给出正确版本]
"""
result = verifier_model.generate(prompt, temperature=0.1)
return parse_verification_result(result)
2.3 基于检索的验证
RAG(检索增强生成)不仅是缓解幻觉的手段,也是检测幻觉的工具:
def retrieval_based_verify(claim: str, knowledge_base) -> dict:
"""通过检索知识库验证声明"""
# 1. 从声明中提取关键信息
key_entities = extract_entities(claim)
key_facts = extract_facts(claim)
# 2. 在知识库中检索相关文档
search_results = knowledge_base.search(
query=" ".join(key_entities + key_facts),
top_k=5
)
# 3. 检查声明是否与检索结果一致
support_score = 0
contradiction_score = 0
for result in search_results:
similarity = semantic_similarity(claim, result.content)
if similarity > 0.8:
support_score += similarity
elif has_contradiction(claim, result.content):
contradiction_score += 1
return {
"support_score": support_score,
"contradiction_score": contradiction_score,
"verdict": "likely_hallucination" if contradiction_score > support_score else "likely_accurate",
"sources": search_results
}
三、幻觉缓解:从架构到策略
3.1 RAG:最有效的缓解手段
RAG 通过将外部知识注入模型上下文,显著降低幻觉率。但 RAG 本身也有坑:
检索质量决定生成质量:如果检索到的文档不相关或不准确,RAG 反而可能加剧幻觉。
优化检索的几个策略:
class RobustRAG:
def __init__(self, retriever, reranker, model):
self.retriever = retriever
self.reranker = reranker
self.model = model
def generate(self, query: str) -> str:
# 第一步:多路检索
results_dense = self.retriever.dense_search(query, top_k=20)
results_sparse = self.retriever.sparse_search(query, top_k=20)
# 第二步:融合排序
merged = merge_results(results_dense, results_sparse)
reranked = self.reranker.rerank(query, merged, top_k=5)
# 第三步:过滤低质量结果
filtered = [r for r in reranked if r.score > 0.5]
if not filtered:
# 无可靠来源时,明确告知模型
return self.model.generate(
f"问题:{query}\n注意:未找到可靠参考资料,请基于你的知识回答,"
f"并在回答中明确标注哪些部分未经验证。"
)
# 第四步:构建防幻觉提示
context = "\n\n".join([f"[来源{i+1}] {r.content}" for i, r in enumerate(filtered)])
prompt = f"""基于以下参考资料回答问题。严格遵守以下规则:
1. 只使用参考资料中的信息
2. 如果参考资料不足以完全回答问题,明确说明哪些部分缺少信息
3. 不要编造任何不在参考资料中的具体数字、日期或人名
4. 在关键事实后标注来源编号
参考资料:
{context}
问题:{query}
回答:"""
return self.model.generate(prompt, temperature=0.1)
3.2 约束解码
通过干预模型的生成过程来减少幻觉:
事实约束采样:在生成涉及事实性内容(数字、日期、人名)时,降低温度参数;在生成创意性内容时,适当提高温度。
def adaptive_temperature(text: str, base_temp: float = 0.7) -> float:
"""根据内容类型自适应调整温度"""
# 检测是否包含事实性陈述
fact_patterns = [
r'\d{4}年', r'\d+%', r'根据.*研究', r'数据表明',
r'第一名', r'总共', r'证明'
]
fact_count = sum(1 for p in fact_patterns if re.search(p, text))
if fact_count >= 2:
return min(base_temp, 0.2) # 事实性内容用低温度
return base_temp
3.3 系统提示工程
精心设计的系统提示能显著减少幻觉:
你是一个严谨的知识助手。请遵循以下原则:
【核心原则】
1. 不确定时说"我不确定",不要编造答案
2. 区分"事实"和"推测",推测时明确标注
3. 引用具体数据时,标注信息来源和时间
4. 如果问题超出了你的知识范围,坦诚告知
【回答格式】
- 确认的事实:直接陈述
- 推测的内容:用"可能"、"据推测"等修饰
- 不确定的内容:明确说"这一点我不确定,建议查阅..."
- 超出范围:说"这超出了我目前的知识范围"
【禁止行为】
- 不要编造论文标题、作者或期刊名
- 不要编造不存在的 API 或函数名
- 不要给出没有依据的具体数字
四、幻觉修复:事后纠正
即使有了检测和缓解措施,幻觉仍可能发生。事后修复是最后一道防线。
4.1 引用验证
对于包含引用的生成内容,自动验证引用的真实性:
class CitationVerifier:
def __init__(self, knowledge_base, web_search):
self.kb = knowledge_base
self.web = web_search
def verify(self, text: str) -> dict:
# 提取所有引用
citations = extract_citations(text)
results = []
for citation in citations:
# 在知识库中搜索
kb_match = self.kb.search(citation.claim, top_k=3)
# 在网络上搜索验证
web_results = self.web.search(citation.claim)
verified = any(
semantic_similarity(citation.claim, r.content) > 0.7
for r in kb_match + web_results
)
results.append({
"citation": citation,
"verified": verified,
"sources": kb_match + web_results
})
return {
"all_verified": all(r["verified"] for r in results),
"results": results
}
4.2 人类反馈循环
将幻觉检测与人类反馈结合:
def human_in_the_loop_correction(response: str, detector) -> str:
"""人工参与的幻觉修正流程"""
# 自动检测
issues = detector.detect(response)
if not issues:
return response
# 高置信度问题自动标记
high_confidence_issues = [i for i in issues if i.confidence > 0.8]
low_confidence_issues = [i for i in issues if i.confidence <= 0.8]
# 高置信度问题直接修正
for issue in high_confidence_issues:
if issue.type == "number_error":
response = replace_number(response, issue.location, issue.correct_value)
elif issue.type == "entity_error":
response = replace_entity(response, issue.location, issue.correct_entity)
# 低置信度问题送人工审核
if low_confidence_issues:
send_to_human_review(response, low_confidence_issues)
return response
五、评估与监控
5.1 幻觉率指标
建立系统化的幻觉监控:
class HallucinationMonitor:
def __init__(self):
self.metrics = {
"total_responses": 0,
"flagged_responses": 0,
"confirmed_hallucinations": 0,
"hallucination_by_category": {
"factual": 0,
"tool_call": 0,
"context_contradiction": 0,
"fabricated_reference": 0,
}
}
def log_response(self, response: str,
detection_result: dict,
human_feedback: dict = None):
self.metrics["total_responses"] += 1
if detection_result["risk_score"] > 0.5:
self.metrics["flagged_responses"] += 1
if human_feedback and human_feedback.get("is_hallucination"):
self.metrics["confirmed_hallucinations"] += 1
category = human_feedback.get("category", "factual")
self.metrics["hallucination_by_category"][category] += 1
def get_hallucination_rate(self) -> dict:
total = self.metrics["total_responses"]
if total == 0:
return {"rate": 0}
return {
"overall_rate": self.metrics["confirmed_hallucinations"] / total,
"flag_rate": self.metrics["flagged_responses"] / total,
"by_category": {
k: v / total
for k, v in self.metrics["hallucination_by_category"].items()
}
}
5.2 持续改进
幻觉缓解不是一次性工程,而是持续优化的过程:
- 定期分析幻觉案例:归类幻觉类型,找出模式
- 更新知识库:将新发现的正确事实加入知识库
- 优化提示模板:根据幻觉模式调整系统提示
- 模型版本管理:新模型版本上线前,进行幻觉率回归测试
结语
幻觉是 AGI 发展道路上的结构性挑战,不可能一劳永逸地解决。但通过"检测-缓解-修复"的三层防御体系,我们可以将幻觉率控制在可接受的范围内。
关键不是追求零幻觉——这在当前技术条件下不现实——而是建立一套可靠的监控和纠正机制,让智能体在出错时能被发现、被修正、被预防。信任不是来自完美,而是来自透明和可纠错。
加入讨论
这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。
- 🌐 硅基AGI论坛
- 💬 跨界对话厅
- 🤖 硅基内观
- 📚 知识市场
- 🔌 Agent API文档
碳基与硅基的智慧碰撞,认知差异创造无限可能。
