Agent 跑偏的三种形态 | Agent 与 Skill | 做产品
Agent 跑偏的三种形态
Agent 跑偏不是玄学,是可以分类的。绝大多数失控,落在这三种形态里——每种都有对应的拦截方式。
你会遇到的现象
-
它做着 A,做着做着开始做 B,做完 B 还不停
-
它调了不该调的工具,或者参数传得离谱
-
同一个动作反复重试,停不下来,账单一直在涨
目标漂移
症状:开始时目标明确,但随着上下文变长、中间动作变多,模型渐渐把「完成当前子任务」当成了「目标」。你让它查订单,它查完订单开始分析订单数据,分析完开始写改进建议——每一步都合理,整体已经跑远了。
为什么会这样?因为 Agent 每轮决策时,上下文里堆满了中间结果,原始目标(「查订单并汇报」)被淹没在后面,注意力逐渐被最近的步骤带走。
拦截手段:
**一、把目标写成「终点条件」。**不只是「查订单」,而是「查订单,把结果用一段话汇报,汇报完任务即结束」。让模型有明确的「做完」判断。
**二、把目标固定在显眼位置。**在系统提示或每轮开头重申一次本次任务边界——不是靠「记住」,是靠放在高注意力位置。
**三、允许它「拒绝延展」。**提示词里明确:「如果发现当前动作超出了原始请求范围,停下来向用户确认」。让「停下来问」成为一个正当选项,而不是逼它一直做下去。
工具误用
症状:该调工具时调错工具,或参数传错。最危险的是「够得着但用错了」:一个能删数据的工具和一个只读工具放在一起,模型选错了。
为什么会这样?一是工具清单太杂、说明太含糊,模型分辨不清;二是外部内容(网页、文档)里藏了引导它调用某工具的指令——提示注入的典型手法。
拦截手段:
一、工具说明写清边界。「此工具只读,不产生任何修改」「仅当用户明确要求发送时才可调用」。模型会照说明行事,说明越清楚,误用越少。
**二、风险工具分级。**有副作用的工具(发送、删除、转账)单独归类,设为需人工批准,不让模型在循环里自动调用。
**三、参数校验放执行层。**不要相信模型传的参数。执行前校验类型、范围、权限,把「模型说错」拦截在真正的动作之前。
循环不收敛
症状:同一个动作反复重试。失败 → 换个参数重试 → 再失败 → 再换参数……每轮都在增加上下文、每轮都在花钱,永远不会达到终止条件。
为什么会这样?往往是失败的结果没有给出「为什么失败」,或者失败后模型没有足够信息改变策略,只能原地打转。
拦截手段:
**一、硬性最大轮数。**这个必须有。循环是刹车失灵的重灾区,超过 N 轮直接终止并降级处理。
二、失败要带回原因。「重试时带上上次失败的原因」,让模型有信息改变做法,而不是盲试。
**三、失败收敛策略。**规定:同一步失败 K 次就停止,改为向用户说明问题。别让它用不同的方式失败一百次。
**四、监控轮数与花费。**循环次数、工具调用次数、累计 Token,这些是最基本的运行指标。不记录这些,你连它跑了多远都不知道。
灰色是你要的,红色是它实际做的
原始终点
越走越远
只读工具
删除工具 够得着,但选错了那一个
× N 轮数一直涨 终点永远到不了
目标漂移 每一步都合理,整体已跑远 工具误用 清单太杂,或被外部内容诱导 循环不收敛 失败没带回原因,只能盲试
拦:把目标写成终点条件 拦:允许它「停下来问」 拦:说明里写清工具边界 拦:参数校验放执行层 拦:硬性最大轮数 拦:失败必须带回原因
三种形态的共同点:模型不会自己「醒悟」,一切克制都来自你搭的约束。
把失控拆成三类之后,「Agent 不靠谱」就变成了三个可以分别下手的工程问题。每一列的拦截手段都写在代码和提示词里,不在模型的自觉里。
通用的兜底
三种形态各有拦法,但还有几条适用于所有情况的底线:
**一、权限是最后一道闸。**规则再完善也拦不住意外。把所有高风险动作(删除、发送、付款、外发)都放到人工断点之后——这是唯一你不需要信任模型的防线。
**二、全程留日志。**每一步的输入、输出、工具调用、理由都记下来。跑偏之后,没有日志你连「它为什么这么做」都说不清。
三、给 Agent 留「不知道」的出口。「不确定时停下问用户」要作为一个正当选项写进提示词。一个永远在行动的 Agent,比一个会停下来问的 Agent 危险得多。
最后记住这件事:**跑偏的拦截是设计出来的,不是祈祷出来的。**模型不会自己「醒悟」,一切克制都来自你搭的约束。
权限分级与人工断点 三种跑偏的共同最后防线。
Agent 循环 不收敛的根源,在循环怎么转的。
Agent 评测 跑偏是偶发还是常态,要靠评测才能确认。
