Agent 如何失效
七种反复出现的失效模式,各自的成因,以及能防住它的具体护栏。上线任何自主运行的东西之前,先读这篇。
Agent 失效不是随机的。同样这七种反复出现,而且每一种都有已知的护栏。
1 · 重复循环
同一个工具、同一组参数,一遍又一遍。结果没帮上忙,模型也没有更好的主意,于是再试一次。
成因。 没有「这一步已经试过」的记忆,也没有判定某条路已经走不通的机制。
护栏。 检测到参数完全相同的重复调用就中断。在上下文里维护一份明确的「已试过的方案」清单。无论如何都要设硬性迭代上限。
2 · 选错工具
模型挑了一个看着合理但其实是错的工具,或者干脆编一个根本不存在的。
成因。 几乎总是工具描述互相重叠或写得太笼统。这个问题比推理质量差更常见。
护栏。 让描述形成对比,每条都写明什么情况下该优先选旁边那个。合并功能相近的工具。请求了不存在的工具时,返回明确的报错,并列出可用的工具。
3 · 上下文耗尽
跑到一半,对话记录就超出了上下文窗口。早先的指令被截断,agent 忘了自己在干什么。
成因。 啰嗦的工具结果越积越多,而且每一轮都重新发一遍。
护栏。 让工具返回紧凑的输出——这是收益最高的一招,领先幅度还很大。跟踪 token 数,在溢出之前停下来。把较早的状态总结掉或外置出去。
4 · 提前宣布完成
任务只做了一部分,甚至一点没做,agent 就宣布成功。
成因。 把「没有工具调用」当成完成,混淆了做完了和卡住了。偏好训练也会让它倾向于给出一个答案。
护栏。 给一个显式的 finish 工具,把结果作为参数传进去,这样「完成」就是一个有意为之、可验证的动作。然后去验证——确认它声称的结果真的发生了。
5 · 自信地做错事
agent 基于一个误解做出了真实动作。删错记录,发错人。
成因。 带上了工具的幻觉。一次流畅的工具调用,丝毫不能说明它背后的推理站得住脚。
护栏。 这一种要靠结构上的防御,光靠 prompt 不行。只读工具可以随便跑;任何不可逆的操作都必须确认。优先选可逆的做法——用软删除代替直接删除,存草稿代替直接发送。凭证按最小权限授予。
6 · 经由工具结果的提示注入
检索到的文档或抓取的页面里,藏着一小段长得像指令的文字,agent 就照着做了。
成因。 工具结果是作为文本进入上下文的,和你的指令在性质上无从区分。
护栏。 目前没有完整的解法——这是 agent 安全里最核心的未解难题。部分防御手段:让破坏性工具从不可信内容那里够不着,给工具输出划定边界并声明它是数据,对有后果的动作要求确认,以及在规划时一律把任何读过开放网络的 agent 视为已被攻陷。
7 · 目标漂移
跑到第十二步,agent 干的活已经和原任务只是沾边了。
成因。 目标被越积越多的对话记录埋住了,而每一个局部决策看起来都还算合理。
护栏。 每一轮都重述目标,而不是只靠system prompt。定期对着原目标重新规划。见多步规划。
底下的算术
这些失效大多会随循环变长而加重,原因只有一个:可靠性向下复利递减。
单步 95%,十步下来大约 60%,二十步就是 36%。没有任何 prompt 能改变一个指数。
由此得出设计准则:更少、更可靠的步骤,胜过多几步。 另外要做检查点,这样第 8 步失败时不会把前七步一起丢掉。
基线护栏
每个 agent,无论做什么任务:
- 硬性迭代上限——没有商量余地
- token 预算检查,每次调用之前
- 墙钟超时
- 重复检测
- 显式的完成工具,并带验证
- 完整日志:记录思考、调用和结果——你唯一能拿来调试的东西
- 不可逆操作上的确认闸门
怎么测这些
Agent 不能只测顺利路径,因为上面这些失效都出现在顺利路径之外。
强制工具失败。 返回错误,看它是恢复过来,还是一蹶不振。
喂它模糊的任务。 看它是会追问,还是直接猜。
试不可能完成的任务。 表现好的 agent 会报告这做不到;表现差的会一直循环,或者捏造一个成功。
在它检索的内容里塞进对抗内容,看注入的指令会不会被照做。
反复地跑。 Agent 是非确定性的。成功一次说明不了什么——见你怎么知道它管用?。
要点回顾
- 七种反复出现的模式:重复循环、选错工具、上下文耗尽、提前宣布完成、自信地做错事、提示注入、目标漂移。
- 大多数靠结构来预防——上限、检测、显式完成、闸门——而不是靠把 prompt 写得更好。
- 紧凑的工具结果和迭代上限是两个收益最高的护栏。
- 不可逆动作需要确认闸门;提示注入没有完整的解法。
- 在顺利路径之外测,而且要反复测。
下一篇: MCP 是什么?