在 AI Agent 落地实践中,开发者最常遇到且最痛的问题就是幻觉与过度输出。在运维诊断等对准确性要求极高的场景中,Agent 常常会一本正经地胡编乱造,或者在调用工具后生成大段无用文本。
很多人的第一直觉是:“Agent 太发散了,我必须把它拆开,用编排节点去管束它。” 就像之前的设计那样,引入 Verifier 和 Gatekeeper 去卡 Executor 的输出。但这恰恰陷入了"治标不治本"的陷阱——用架构复杂性掩盖了上下文工程的不足。
本文将以真实的运维诊断场景为例,剖析幻觉与过度输出的根源,并总结出一套行之有效的"单 Agent + 四层防线"防幻觉工程方法论。
一、 认知纠偏:幻觉产生的技术根源
在设计防幻觉机制前,必须先认清幻觉是怎么来的。知识库明确指出:“大模型的能力、问题与用法本质上由上下文决定……幻觉源于上下文缺失。”
你的 Executor 之所以会过度输出和产生幻觉,根本原因不在于"缺少监督节点",而在于以下三点:
- 脏数据淹没:工具返回的数据太脏、太多,淹没了关键信息,模型为了"消化"这些冗余数据,开始编造关联性。
- 缺乏契约约束:Prompt 没有强约束输出格式,模型开始"自由发挥",生成散文式分析。
- 闭环缺失:模型只基于单方面的工具结果"自圆其说",缺乏真实世界的负反馈机制。
二、 踩坑实录:用"多 Agent 编排"防幻觉为何行不通?
在最初的架构中,为了防止 Executor 过度输出,系统被设计为通过 Gatekeeper 和 Verifier 节点去拦截和校验 Executor 的结果。这种设计在实际运行中暴露了致命问题:
踩坑 1:事后纠偏的代价极高
让一个"脱缰的 Executor"先跑完,生成一堆幻觉文本,消耗大量 Token,然后再让另一个 LLM 去审查它。这不仅造成算力浪费,审查节点本身也是 LLM,同样可能产生幻觉。
踩坑 2:没有切断污染源
Executor 过度输出的根源是上下文太长或太脏。把它拆成独立 Agent 并加上一堆编排节点,如果不做上下文压缩,它的上下文依然会爆满,照样过度输出。
踩坑 3:编排通信引入新的幻觉源
多个节点之间用自然语言或松散协议传递状态,极易产生理解偏差。主控节点可能误解子节点的摘要,导致"传话传错了"的二次幻觉。
三、 破局之道:构建单 Agent 的"四层防线"
要彻底锁死过度输出与幻觉,核心思路是:防患于未然,用代码与契约构建物理门禁。 在单 Agent + Harness 架构下,防幻觉不需要拆分编排节点,而是构建以下四层防线:
防线 1:工具层清洗(RTK 机制)—— 切断脏数据输入
问题:查日志返回 1000 行,Executor 为了"消化"这些数据,开始编造关联性。
做法:在工具返回结果给 Agent 大脑之前,Harness 代码必须进行强制清洗(借鉴 Claude Code 的 RTK 机制)。
- 查日志工具:过滤掉
INFO,只返回ERROR级别及前后 5 行上下文。 - 查 DB 工具:将大数据表聚合为统计指标(如"连接池占用率 98%"),而不是把几百行记录塞给 Agent。
效果:进入 Agent 上下文的数据越干净、越精炼,模型"发散思考"的空间就越小。
防线 2:契约式设计(JSON Schema 强约束)—— 锁死输出格式
问题:Executor 输出大段散文式分析,甚至自己脑补了不存在的错误码。
做法:在 System Prompt 中强制要求 Agent 的每一次思考和行动必须符合严格的 JSON 契约,并在代码层做校验。
{
"thought": "不超过50字的思考过程",
"action": "queryLogs",
"parameters": {"service": "order", "time": "last_10m"},
"evidence_id": null // 如果是最终结论,必须带上证据ID
}
代码拦截:如果 thought 超过 50 字,或者格式不对,代码层直接打回,不消耗额外的 LLM 审查调用。这就是 Gatekeeper 应该有的形态——一行 Linter 代码。
防线 3:物理门禁—— 防止凭空捏造
问题:Agent 在最终报告中写道:“根据日志显示,发生了 504 超时”,但实际上它根本没查那个时间段的日志。
做法:在 Agent 输出最终诊断报告时,Harness 代码必须执行后置断言:
- 检查报告中引用的每一个
source_invocation_id(证据 ID)是否在本次会话的历史工具调用中真实存在。 - 检查报告中提到的
raw_path(原始日志路径)是否真的在文件系统中存在。
强制阻断:如果不合法,直接拒绝输出,返回错误给 Agent 重试。绝不靠 LLM 去验真,靠代码查库验真。
防线 4:多维度交叉验证 —— 终极防幻觉
问题:Agent 查了日志,就基于日志下结论,但日志可能只是表象。
做法:保留一个轻量级的验收 Sub-Agent,它不参与主流程,只在最后做**“证据链交叉验证”**(借鉴得物告警排查 Agent 实践):
- 让验收 Agent 检查:日志结论与指标结论是否一致?日志时间线与Trace时间线是否对齐?
- 让 LLM 的分析结论必须得到至少两个独立工具证据的支持。如果不一致,输出低置信度报告,而不是强行缝合一个结论。
四、 进阶视角:引入真实世界的负反馈
知识库中提出了一个极高级的视角:基于控制论的负反馈调节。
你之前的架构是单向的(Planner -> Executor -> 总结),模型自己输出什么就是什么。为了防幻觉,你需要把 ReAct 循环变成一个闭环控制系统:
- LLM 是控制器,Tool 是执行器,Observation 是反馈信号。
- 为了对抗 LLM 的不确定性,必须引入真实世界的反馈作为负调节。
- 例如:Agent 决定回滚某个配置,Harness 代码先去真实环境中执行 Dry-run,如果 Dry-run 报错,把这个真实报错作为 Observation 喂回给 Agent。Agent 看到物理世界的阻力,就不会继续基于幻觉往下编造,而是被迫调整策略。
五、 方法论沉淀:防幻觉的"3+1"工程准则
如何在未来的设计中自查你的防幻觉机制是否可靠?请遵循以下准则:
准则 1:上下文供给优于提示词技巧
幻觉源于上下文缺失。防幻觉的第一步不是写复杂的 Prompt,而是确保喂给 Agent 的上下文是完整且干净的。通过"上下文卸载"和"RTK 清洗",让模型始终在清晰、聚焦的环境中推理。
准则 2:期望应编码为机制,而非文档
能写成 Linter 的约束不应停留在 Prompt 里。参数校验、格式限制、字数控制,必须通过代码层的 Schema 校验强制执行,机器强制永远比 LLM 自觉更可靠。
准则 3:物理验真优于 LLM 审查
不要用 LLM 去验证 LLM。Agent 引用的任何客观事实(文件路径、日志ID、数据记录),必须通过代码去查询真实的物理系统进行比对验证,形成物理门禁。
附加准则:建立闭环负反馈
不要让 Agent 在"真空"中单向输出。将工具执行的真实物理结果作为反馈信号注入上下文,迫使 Agent 面对真实世界的约束,打破自圆其说的幻觉闭环。
结语
防幻觉和过度输出,绝不是靠增加 Agent 数量来"互相监督"能解决的。这就像防止一个工人犯错,不是给他安排 5 个监工(多 Agent 编排),而是给他配一把精准的卡尺(JSON 契约)、一台自动过滤杂质的机器(RTK 清洗)、以及一道出厂前的物理质检门禁(代码验真)。
记住一句话:把推理还给 ReAct,把校验还给代码,把上下文洗干净。幻觉自然无处遁形。