Agent 上线难点:退出、预算与执行授权
一个约 32 行的 Agent 循环,在真实任务中仍会遭遇参数错误、工具异常、停止状态遗漏和上下文成本累积。作者提出将工具失败返回模型、限制轮次与时间及令牌、记录每轮输入,并为 Shell 执行设置人工审批。
AI 深度解读
Agent 的核心循环,作者用 Python 大约 32 行就写出来了:调用模型、执行工具、把结果放回对话,再继续。真正把它变成可用产品的,却是让它在出错、超支或执行危险操作前停下来。
这篇短文的价值,在于把 AI 编程里容易混淆的两件事分开:模型决定请求什么,程序决定是否执行、如何执行、何时结束。能跑通循环,只完成了最容易的一步。
32 行能跑起来,为什么还不能放心用
作者先用一个故意制造异常行为的假模型测试,循环第一次就跑通了。但换到真实任务后,智能水平还没来得及发挥作用,工程问题就接连出现。
原文列出了六个问题:
- 第一次请求还没发出去,错误的
temperature参数就让流程受阻。 - 模型的停止原因不只有
end_turn,程序需要处理其他情况。 - 工具执行报错,会直接把进程带崩。
- 没有预算限制,卡住的 Agent 会持续花钱。
- 缺少可见性,开发者不知道模型实际收到了什么。
- 每一轮都会重新发送完整的 messages 列表,对话越长,重复输入的成本越需要关注。
这些是作者报告遇到的问题,但原文没有给出完整实现、请求记录或成本明细。它能说明故障类型,不能用来估算你的 Agent 会贵多少、多久会出问题。
其中,temperature 和 end_turn 都依赖具体接口约定。原文没交代模型、SDK 或版本,读者不能直接据此推断自己使用的平台支持什么参数、会返回哪些停止原因。
真正的控制权,应该留在程序里
模型只请求调用工具,真正执行工具的是你的代码。
这句话决定了责任边界。模型输出一个 shell 调用请求,并不会自动获得文件操作能力;是宿主程序接住请求,启动命令,才让它碰到文件。
作者因此认为,shell 执行前需要有人审核。审核必须发生在命令运行之前,执行完再展示日志,已经无法阻止刚才的操作。
同样,while True 本身没有问题,但如果没有程序自己的退出条件,是否继续就主要取决于模型。一旦模型反复尝试无效操作,循环仍然可以保持「正常运行」,费用却不断累积。
作者给出的控制措施有四类:
- 工具失败时,把错误作为带有
is_error的结果返回,让模型知道发生了什么。 - 为轮数、时间和 tokens 设置上限,防止任务无限继续。
- 记录每一轮,帮助定位请求、响应和执行过程中的问题。
- 在 shell 命令运行前取得人工批准。
这里有一个需要补上的理解:返回错误,是为了让失败进入可处理的流程,并不代表应当一直重试。错误反馈仍然要受预算和退出条件约束。
日志也不能只记录「调用成功」。作者提到的痛点,是看不到模型究竟收到了什么;日志是否能回答这个问题,比有没有一行成功提示更有用。原文没有进一步给出日志字段设计。
我的判断
我认同作者把工程控制放在模型能力之前。对于能调用工具的程序,能否限制执行范围、处理失败并及时终止,是可用性的基础。
但「每个退出点都要有保护」仍然是经验性主张。作者没有提供加入这些措施前后的成功率、成本或故障恢复对照,也没有证明这些措施已经覆盖所有风险。
人工审核 shell 有明确用途,也有交互成本。原文没有讨论只读命令、受限目录或隔离执行等方案,因此不能据此判断每条命令都人工批准是否适合一般团队。审批解决的是执行前的决策问题,无法单独替代执行环境的限制。
另外,完整 messages 列表反复发送,是作者这个循环的行为。原文没有比较上下文裁剪、摘要或缓存等处理方式,不能把它扩大成所有 Agent 都必然采用的成本模型。
至于 Claude Code,作者借它解释为什么成熟工具需要循环之外的控制功能;这不是对 Claude Code 内部实现的验证。
能拿来做什么
- 自己用 Node 写工具调用循环时,先列清接口允许的参数和停止原因,再接真实模型,避免只处理
end_turn。 - 给日常 AI 编程任务设置轮数、时间和 tokens 上限,并明确达到上限后如何结束,别只依靠模型主动停止。
- 把工具错误转换成模型能接收的失败结果,同时记录每轮实际发送的内容,方便区分参数错误、工具故障和模型判断问题。
- 接入 shell 工具时,把人工审批放到执行入口,并检查每轮 messages 的发送范围,确认长对话产生了哪些重复输入。