Agent 的内核是一个循环:模型决定下一步,调用一个工具,把工具的真实返回写回上下文,再决定下一步。循环什么时候结束,和循环本身一样是设计的一部分。只有「最大步数」时,模型会在同一种失败上把步数用完:搜索词几乎没变,工具每次都返回空,费用已经产生,任务没有完成。
循环的结构见 构建你的第一个 AI Agent。这篇只讲停。
至少三种停法
| 条件 | 含义 | 防止什么 |
|---|---|---|
| 模型声明完成 | 输出里 action 为结束,并给出答案 |
正常做完 |
| 最大步数 | 例如 4 或 6 步,到了就返回「未完成」 | 死循环和费用没有上限 |
| 同类错误重复 | 同一工具、同一类错误连续两次 | 换个说法重试,其实没有新信息 |
最大步数是兜底,不是唯一的策略。步数设得很大,短任务也会慢慢用满。需要长链条的任务单独加预算,不要把默认值放宽。
同类错误要算「类」,不是算字符串相等。搜索返回空、超时、参数校验失败,各算一类。同一类连续两次,把最后一次的错误返回给调用方,而不是再让模型改写一次查询。
有些动作不应该出现在循环里
删除、付款、对外发送,不要做成模型可以自己调用的工具。模型最多生成一条待确认的说明,由人执行。工具边界就是权限边界:循环能调用的函数,就是它能造成的副作用。
检索为空时,按提示词回答「资料里没有」,不要自动改写查询再搜,除非这一步是人触发的。自动改写看起来像在努力,常常只是把空结果重复几遍。
日志里要能区分两件事
每一步留下:
- 模型以为自己在做什么(thought / action / 参数)
- 工具实际返回了什么(含错误码和正文)
只有「失败」两个字时,无法判断该改提示词还是该改工具。把这几步串进同一次请求的 trace 里之后,才能和延迟、token 放在一起看。trace 的分法见 LLM 可观测性。
不要先加第二个循环
任务做不好时,常见的下一步是再加一个「检查员」角色。检查员也是一个会犯错的模型,上下文还更长。单循环的停止条件、工具错误和日志还没写清时,多一个角色只是多一份同样的错误。
小结
循环要能停。完成、步数用尽、同一类错误重复,三条都写上。危险动作放在循环外面。日志分开记「模型的打算」和「工具的返回」,否则失败无法复盘。