
【AI应用开发】怎么降低 Agent 幻觉有几种可行方案目录Agent 幻觉的三种类型根因分析八种降低幻觉的方案方案一强制引用溯源方案二事实核查层方案三多模型交叉验证方案四检索增强RAG方案五输出约束与校验方案六不确定性量化方案七人类反馈闭环方案八Anti-Hallucination Prompt组合策略与效果评估1. Agent 幻觉的三种类型类型A: 事实幻觉 用户: 2024年GDP增速多少 Agent: 根据最新数据2024年GDP增速为5.2%。 ← 编造的具体数字 类型B: 来源幻觉 用户: 退货政策是什么 Agent: 根据《消费者权益保护法》第25条... ← 编造的法律条文引用 类型C: 逻辑幻觉 工具返回: 订单已发货 Agent: 您的订单将在今天下午3点送达。 ← 没有物流数据支持自己推断的Agent 比普通 LLM 更容易产生幻觉因为 Agent 在多步推理中每一步都可能产生幻觉然后后续步骤基于虚假信息继续推理形成幻觉级联Hallucination Cascade。2. 根因分析原因说明知识边界模糊LLM 不知道自己不知道什么概率本质LLM 本质是合理续写不是事实核查上下文干扰Agent 多步推理中前面的误解影响后续判断工具返回误解LLM 曲解了工具返回的数据缺乏验证机制默认信任 LLM 输出没有独立的事实核查3. 八种降低幻觉的方案防御层次 第一道防线Prompt层: Prompt 约束 Few-Shot 第二道防线检索层: RAG 检索增强 第三道防线输出层: 强制引用 输出校验 第四道防线验证层: 事实核查 交叉验证 第五道防线反馈层: 不确定性量化 人工反馈4. 方案一强制引用溯源要求 Agent 的每个事实性声明都必须标注来源CITATION_PROMPT你是一个严谨的智能助手。遵循以下铁律 1. 对于任何事实性陈述数字、日期、政策、流程、价格等必须标注来源 2. 来源标注格式: [来源: 工具名/文档名] 3. 如果某个信息来自你的知识训练数据而不是当前工具返回的结果 必须标注为 [来源: 模型内部知识 - 请核实] 4. 如果不确定某个信息是否正确请直接说明根据现有信息无法确定 5. 绝对禁止编造以下内容 - 具体的数字和统计数据 - 法律法规条款 - 价格和金额 - 人名、日期、地点 示例: ✅ 根据知识库退货需要在收到商品后7天内申请 [来源: 退货政策文档] ✅ 订单 ORD-2024-00123 的状态为已发货 [来源: query_order 工具返回] ❌ 您的包裹将在明天送达没有物流数据支持 ❌ 根据公司规定退款在3-5个工作日到账没有确认该规定的来源 4.1 自动化引用验证classCitationValidator:验证 Agent 回答中的引用是否真实defvalidate(self,response:str,tool_results:list,retrieved_docs:list)-dict: 检查 Agent 回答中标注的引用是否真实来自工具返回 # 1. 提取回答中标注的引用cited_sourcesre.findall(r\[来源: (.?)\],response)# 2. 收集所有真实的来源real_sourcesset()forrintool_results:real_sources.add(r[tool])fordinretrieved_docs:real_sources.add(d.get(metadata,{}).get(source,))# 3. 交叉检查violations[]forcitedincited_sources:# 检查引用是否在真实来源中ifcited模型内部知识 - 请核实:violations.append({type:uncited_knowledge,source:cited,risk:medium})elifcitednotinreal_sourcesand请核实notincited:violations.append({type:fake_citation,claimed:cited,risk:high})# 4. 检查是否有事实性声明没有标注来源fact_statementsself._extract_fact_statements(response)cited_sentencesself._find_cited_sentences(response)uncited_facts[fforfinfact_statementsiffnotincited_sentences]ifuncited_facts:violations.append({type:uncited_facts,examples:uncited_facts[:3],risk:medium})return{has_violations:len(violations)0,violations:violations,hallucination_risk:highifany(v[risk]highforvinviolations)elsemediumifviolationselselow}def_extract_fact_statements(self,text):提取事实性声明含数字、日期、专有名词的句子facts[]forsentinre.split(r[。\n],text):ifre.search(r\d|[A-Z]{2,}|政策|规定|法律|价格|金额,sent):facts.append(sent.strip())returnfactsdef_find_cited_sentences(self,text):找出已标注来源的句子citedset()formatchinre.finditer(r\[来源: (.?)\],text):# 找到引用前的句子beforetext[:match.start()]sentencesre.split(r[。\n],before)ifsentences:cited.add(sentences[-1].strip())returncited5. 方案二事实核查层在 Agent 输出最终回答前增加一个独立的事实核查步骤classFactChecker:独立的事实核查模块def__init__(self,llm,search_tool):self.llmllm self.search_toolsearch_tool FACT_CHECK_PROMPT你是事实核查员。对以下 Agent 回答进行逐条核查 Agent 回答: {agent_response} 该回答基于以下工具返回数据: {tool_data} 核查规则: 1. 每条声明必须有工具数据或检索结果支撑 2. 数字、日期、名称必须精确匹配来源 3. 推断性结论标记为推断非事实 4. 超出工具数据范围的内容标记为未验证 输出 JSON: {{ verified: [ {{statement: 声明内容, source: 来源, confidence: 0.9}} ], unverified: [ {{statement: 声明内容, reason: 无法在工具数据中找到支撑, risk: high/medium/low}} ], contradictions: [ {{statement: 声明内容, conflict_with: 冲突来源, resolution: 建议}} ], overall_hallucination_risk: high/medium/low }}asyncdefcheck(self,agent_response,tool_results,retrieved_docs):tool_datajson.dumps([{tool:r[tool],result:str(r[result])[:500]}forrintool_results],ensure_asciiFalse,indent2)resultawaitself.llm.chat(self.FACT_CHECK_PROMPT.format(agent_responseagent_response,tool_datatool_data))check_resultjson.loads(JSONFixer.extract_and_fix(result))# 如果风险高可以触发重试或标记ifcheck_result.get(overall_hallucination_risk)high:return{approved:False,check_result:check_result,action:rewrite_or_flag}return{approved:len(check_result.get(unverified,[]))1,check_result:check_result,action:approvediflen(check_result.get(unverified,[]))1elsereview}6. 方案三多模型交叉验证classCrossModelValidator:用不同模型验证输出一致性def__init__(self,primary_model,secondary_model):self.primaryprimary_model# 例如 GPT-4oself.secondarysecondary_model# 例如 Claude 3.5asyncdefgenerate_with_verification(self,prompt,context):# 1. 主模型生成primary_responseawaitself.primary.chat(prompt,context)# 2. 验证模型独立生成不看到主模型的答案secondary_responseawaitself.secondary.chat(prompt,context)# 3. 一致性分析consistencyawaitself._analyze_consistency(primary_response,secondary_response)ifconsistency[agreement_score]0.7:# 分歧大 → 让验证模型仲裁returnawaitself._arbitrate(primary_response,secondary_response,consistency,prompt)# 一致 → 返回主模型答案returnprimary_responseasyncdef_analyze_consistency(self,resp1,resp2):分析两个答案的一致性analysis_promptf比较以下两个回答的一致性 回答A:{resp1[:1000]}回答B:{resp2[:1000]}输出 JSON: {{ agreement_score: 0.0-1.0, // 整体一致性 agreed_facts: [事实1, ...], // 双方一致的事实 disagreed_facts: [ // 有分歧的事实 {{fact: ..., version_a: ..., version_b: ..., severity: high/medium/low}} ], recommendation: trust_a / trust_b / merge / flag }}resultawaitself.secondary.chat(analysis_prompt)returnjson.loads(JSONFixer.extract_and_fix(result))7. 方案四检索增强RAG这是最有效的方案之一——用检索到的真实文档约束 LLM 的输出classRAGConstrainedAgent:检索约束的 Agent —— 强制基于检索结果回答def__init__(self,llm,retriever):self.llmllm self.retrieverretrieverasyncdefanswer(self,question):# 检索相关文档docsawaitself.retriever.search(question,k5)# 强制约束 Promptpromptf基于以下文档回答问题。 铁律 1. 只能使用文档中的信息不得添加任何文档中不存在的信息 2. 如果文档中没有答案直接说根据现有资料无法回答 3. 引用文档内容时必须标注来源段落 4. 如果不同文档有矛盾列出矛盾并说明不要自行判断 参考文档 {self._format_docs(docs)} 问题 {question} 回答 严格遵守铁律responseawaitself.llm.chat(prompt)# 后验证检查回答是否超出文档范围returnawaitself._verify_against_docs(response,docs)asyncdef_verify_against_docs(self,response,docs):验证回答是否都在文档范围内all_doc_text .join(d[content]fordindocs)verify_promptf检查以下回答中的每条声明是否能在参考文档中找到依据。 回答:{response[:1000]}文档:{all_doc_text[:2000]}对回答中每条事实性声明标注: verified / not_found / contradicted 如果不确定标记为 uncertain 输出 JSON: {{statements: [{{text: ..., status: verified/not_found/contradicted}}]}}resultawaitself.llm.chat(verify_prompt)verificationjson.loads(JSONFixer.extract_and_fix(result))# 清理违规内容hallucinated[sforsinverification.get(statements,[])ifs[status]in(not_found,contradicted)]return{response:response,hallucinated_statements:hallucinated,clean:len(hallucinated)0}8. 方案五输出约束与校验classOutputGuard:输出安全守卫BLACKLIST_PATTERNS[r根据《.{2,20}法》第\d条,# 编造法律条文r据(最新|权威)数据(显示|表明),# 模糊引用r\d{4}年.{0,5}(增长|下降)\d%,# 精确统计数字]defcheck(self,response:str,available_data:dict)-dict:检查输出中是否有不安全的模式warnings[]# 1. 黑名单模式检查forpatterninself.BLACKLIST_PATTERNS:matchesre.findall(pattern,response)formatchinmatches:# 检查是否在可用数据中ifmatchnotinstr(available_data):warnings.append({type:suspicious_pattern,match:match,risk:high})# 2. 数值范围检查numbersre.findall(r\d\.?\d*,response)fornum_strinnumbers:numfloat(num_str)ifnum1000000:# 大数值更可能是编造的warnings.append({type:large_number,value:num,risk:medium})# 3. 时间检查datesre.findall(r(\d{4})年(\d{1,2})月(\d{1,2})日,response)fromdatetimeimportdatetime nowdatetime.now()fory,m,dindates:dtdatetime(int(y),int(m),int(d))ifdtnow:warnings.append({type:future_date,date:f{y}-{m}-{d},risk:high})return{safe:len(warnings)0,warnings:warnings,recommendation:rewriteifany(w[risk]highforwinwarnings)elsereview}9. 方案六不确定性量化让 LLM 自己标注回答中每个部分的确定性UNCERTAINTY_PROMPT在回答用户问题时同时对每段回答标注确定性级别 确定性级别定义: - [确定] 信息直接来自工具返回或检索文档 - [基本确定] 信息来自推理但有充分依据 - [不确定] 信息来自一般知识未经验证 - [无法确定] 纯粹推测 格式: [确定] 您的订单 ORD-2024-00123 状态为已发货。 [基本确定] 根据发货时间预计2-3天后到达。 [不确定] 物流公司通常在上午派送。 [无法确定] 具体派送时间可能需要联系物流公司确认。 10. 方案七人类反馈闭环classHumanFeedbackLoop:人工反馈闭环 —— 标记幻觉用于持续改进def__init__(self):self.feedback_db[]# 实际应用应持久化defcollect(self,session_id,response,user_feedback):收集用户对幻觉的反馈ifuser_feedback.get(has_hallucination):self.feedback_db.append({session_id:session_id,response:response,hallucination_detail:user_feedback.get(detail),timestamp:time.time()})defgenerate_anti_hallucination_examples(self)-list:从反馈中生成反面示例用于 Few-Shot Promptexamples[]forfbinself.feedback_db[-10:]:examples.append(f ❌ 错误回答有幻觉:{fb[response][:200]}问题:{fb[hallucination_detail]})returnexamplesdefget_stats(self)-dict:获取幻觉统计return{total_feedback:len(self.feedback_db),hallucination_rate:(len(self.feedback_db)/max(1,len(self.feedback_db))),}11. 方案八Anti-Hallucination PromptANTI_HALLUCINATION_SYSTEM_PROMPT# 角色与原则 你是严格遵循事实的智能助手。 # 绝对禁止违反即失败 1. 禁止编造任何不在工具返回或检索结果中的数字、日期、人名、地名 2. 禁止编造法律条文、公司政策、产品功能 3. 禁止说根据最新数据/研究显示除非你有具体的数据来源 4. 禁止对工具返回的结果做超出范围的推断 5. 禁止填补信息空白——不知道就说不知道 # 必须遵守 1. 每条事实性信息标注来源 2. 区分工具返回的数据和自己的推断 3. 对推断性内容使用推测、可能、建议核实等措辞 4. 工具返回空或报错时如实告知用户不要编造替代答案 5. 如果回答依赖的信息不完整主动告知用户缺失了哪些信息 # 不确定性表达指南 - 100%确定 → 根据[来源][事实] - 90%确定 → 根据[来源]推测[结论] - 50-90% → [分析]但需要进一步确认[细节] - 50% → 我不确定。根据现有信息无法判断。建议您[替代方案] # 典型错误不要犯 ❌ 工具返回订单已发货 → 您的包裹明天到达没有物流轨迹纯推测 ❌ 工具返回库存充足 → 库存在100件以上工具没说具体数字 ❌ 检索到退货政策 → 根据《消费者权益保护法》...文档里没有这条法律 ❌ 查询失败 → 虽然查不到但一般来说...承认失败不要替代编造 12. 组合策略与效果评估classAntiHallucinationAgent:综合防幻觉 Agent —— 集成多种方案def__init__(self):self.citation_validatorCitationValidator()self.fact_checkerFactChecker(llm,search_tool)self.output_guardOutputGuard()self.cross_validatorCrossModelValidator(llm,claude)# 统计self.stats{total:0,hallucination_blocked:0}asyncdefsafe_generate(self,question,tools,context):self.stats[total]1# 1. 检索增强docsawaitself.retriever.search(question,k5)# 2. Agent 生成使用 Anti-Hallucination Promptresponseawaitself.agent.run(question,system_promptANTI_HALLUCINATION_SYSTEM_PROMPT,toolstools,context{retrieved_docs:docs})# 3. 引用验证citation_checkself.citation_validator.validate(response,context[tool_results],docs)ifcitation_check[has_violations]:# 标记但可能仍返回取决于风险等级pass# 4. 输出安全检查guard_checkself.output_guard.check(response,context)ifnotguard_check[safe]:self.stats[hallucination_blocked]1return抱歉生成的回答存在不确定性请重新描述您的问题。# 5. 可选项事实核查高价值场景ifself._is_high_stakes(question):fact_checkawaitself.fact_checker.check(response,context[tool_results],docs)ifnotfact_check[approved]:# 重试或降级returnawaitself._regenerate_with_facts(question,tools,context,fact_check)returnresponse方案效果对比方案幻觉降低额外延迟额外成本适用强制引用-30%0.1s低所有场景RAG约束-50%0.5s中知识密集型事实核查-40%2s高高风险场景交叉验证-45%3s很高关键决策不确定性量化-20%0.1s低用户体验输出守卫-15%0.05s低安全兜底推荐组合: 强制引用 RAG约束 输出守卫覆盖 80% 场景低延迟低成本。高风险场景额外加事实核查。