ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI Agent 工具调用幻觉的检测与纠偏:一次真实事故复盘(附实现方案)

AI Agent 工具调用幻觉的检测与纠偏:一次真实事故复盘(附实现方案) 背景系统形态定时任务触发 LLM AgentAgent 通过 capability等价于 function call / tool串起一条内容生产流水线选题 → 生成正文 → humanize 改写打分 → 发布到平台 → 登记台账 → 汇报每一步都对应一个真实可执行的 capabilityAgent 循环负责按 prompt 依次调用。故障现象某日日报显示零发布但 Agent 运行日志中输出了完整的成功汇报文章已生成拟人化评分 82 分已发布至平台 链接 https://domain/item/fake-id已登记到台账登记号 CT-20260922-001。核查结果| 检查项 | 期望 | 实际 ||—|—|—|| 发布器执行记录 | ≥1 次 |0 次|| 台账文件 | 有新记录 |空|| Agent 进程退出码 | 0 | 0 || 日志中的 ERROR | — |无|即模型输出的 URL、评分、登记号全部为编造且整个流程以「成功」状态静默退出。根因分析1. 工具调用被降级为散文部分模型尤其是自动路由类聚合模型在tool_choiceauto下不输出标准tool_calls结构而是用自然语言描述工具调用的结果。推测原因是训练语料中「工作汇报」类文本占比高模型在格式不确定时退化到最熟悉的续写模式。编造内容具备高度迷惑性URL 域名与路径结构正确仅 ID 为假评分落在合理区间70~90非随机值登记号格式与真实生成规则一致2. 循环终止条件被绕过Agent 循环的终止判据通常是「本轮模型未请求工具调用」。当模型把调用写成散文时循环判定为「无待执行动作」→正常退出exit code 0无异常、无告警。这是该问题最危险的特性它不表现为崩溃而表现为静默的成功。解决方案声称-事实比对Claim vs Fact核心原则不信任模型的自述只信任系统的执行记录。数据结构# 唯一事实来源本次会话中真实执行成功的 capability 名称called_caps:set[str]set()# 完成类声称的识别规则_CLAIM_RULES:list[tuple[str,re.Pattern[str]]][(publish,re.compile(r(已发布|发布成功|已推送|已上线))),(register,re.compile(r(已登记|已写入台账|已入账|登记号))),(humanize,re.compile(r(评分\s*\d|拟人化.{0,6}\d\s*分))),# ... 按业务补充]_HALLUCINATION_NUDGE(检测到你声称已完成操作但系统未记录到任何真实工具调用。请勿用自然语言描述执行结果必须通过标准 tool_call 实际调用对应能力。)主循环改造nudges0max_nudgescfg.agent_hallucination_max_nudges# 默认 2whileTrue:respllm.chat(messages,toolstool_schemas)# 1) 正常路径有真实工具调用ifresp.tool_calls:forcallinresp.tool_calls:resultdispatcher.execute(call)ifresult.ok:called_caps.add(call.name)# ← 只有成功执行才记账messages.append(tool_message(call,result))nudges0continue# 2) 无工具调用先做幻觉检测再决定是否终止ifguard_enabled:claimed{nameforname,patin_CLAIM_RULESifpat.search(resp.text)}hallucinatedclaimed-called_capsifhallucinatedandnudgesmax_nudges:nudges1messages.append(assistant_message(resp.text))messages.append(user_message(_HALLUCINATION_NUDGE))log.warning(hallucination_detected,claimedhallucinated,nudgenudges)continue# 重跑本轮给模型改正机会ifhallucinated:raiseAgentHallucinationError(claimedhallucinated,calledcalled_caps)break# 无声称、无调用 → 真正的正常结束配置开关AGENT_HALLUCINATION_GUARDtrue# 默认开启调试时可关AGENT_HALLUCINATION_MAX_NUDGES2# 纠偏重试上限上线效果首日即拦截一次真实幻觉模型输出「已发布」类声称 → 规则命中 → 注入 nudge → 模型改发真实tool_call→ 该轮任务共执行13 次工具调用正常完成。单元测试覆盖 8 个用例tests/test_agent_hallucination.py正常调用不误报单/多声称命中声称已被真实执行claimed ⊆ called_caps不触发nudge 超限抛AgentHallucinationError开关关闭时行为回退纠偏后恢复正常调用四条工程结论1. Agent 可观测性的核心是「事实台账」不是日志。日志记录模型说了什么台账记录系统做了什么。两者的差集就是幻觉。任何 Agent 系统都应该能一行命令打印出这个差集。2. 循环终止条件必须挂在业务状态上不能挂在模型行为上。「模型不再请求工具」≠「任务完成」。正确判据是业务侧的可验证结果台账是否有记录、目标资源是否存在。3. 防护规则要基于抽象不要基于某个模型的怪癖。今天出问题的是 A 模型换供应商可能是 B 模型。「声称 vs 事实」这个抽象是稳定的具体模型的输出格式不是。4. 纠偏优先于失败。直接抛异常最安全但会丢弃整段上下文含已消耗 token。先给一次带明确指令的重试机会成本更低实测恢复率可观超限再失败告警。延伸其他值得加的护栏幂等键发布类 capability 带业务幂等键防止纠偏重试导致重复发布。URL 可达性校验模型返回的 URL 在登记前做一次 HEAD 请求 域名白名单校验能拦掉绝大部分编造链接。结构化输出约束对关键节点用 JSON Schema 强约束输出减少散文化空间但不能完全替代上述防护模型仍可能在 JSON 里填假值。标签AI Agent、LLM 应用、Function Calling、幻觉检测、工程实践
返回列表