返回课程目录

第 6 课  Agent loop

理解循环如何驱动智能体,以及如何让它持续推进、适时停止。

预计 10 分钟  ·  系列:从 0 到 1 设计一个 Agent

本课要点

  • 行动结果进入下一轮决策,形成 Agent loop
  • 避免无效重复,区分完成、等待、无法继续与被终止
  • 在决策前、执行前、返回后和结束时按业务需要加工循环

1. 什么是 Agent loop?

在本文中 loop 和循环同义。

智能体的运行靠一个循环来驱动:用户的每一次请求,智能体都有两个选择——要么直接回答用户问题,要么调用工具获得结果,然后判断结果是否足以满足用户要求。如果可以满足,则回答用户。如果不能满足,则继续调用工具。

用户请求
决策下一步做什么?
可以直接回答需要行动或更多信息
回答用户
调用工具
观察结果
回答用户问题
满足
是否满足
用户要求?
不满足
继续调用工具携带结果,进入下一轮决策与行动
决策 → 行动 → 观察 → 再决策

2. 为什么 Agent 需要循环

因为 Agent 无法提前知道每一步行动的结果。它必须不断根据行动获得的新信息,而 Agent 做出的行动又会改变它掌握的信息。必须把行动结果重新告诉模型,模型才能继续决定下一步做什么,因此需要形成“决策 → 行动 → 观察 → 再决策”的循环。

可以把它类比成人类处理现实任务。
比如我让你:“去厨房看看有没有可乐,没有的话帮我买一瓶。”

你不可能一开始就想好完整的行动计划。你得先:

去厨房 → 看冰箱
如果有可乐
拿回来 → 结束
如果没有
  1. 查附近商店
  2. 去商店
  3. 看有没有货
  4. 有就买
  5. 回来把可乐给我
下一步行动取决于上一步看到的结果,Agent 也是一样的。

3. 生产环境中的循环

怎样让 Agent 在真实环境中持续推进任务,同时在该停的时候停下来。

01避免无效重复
02明确停止条件
03按业务需要调整循环

“决策 → 行动 → 观察 → 再决策”这个循环让 Agent 能够根据新信息调整行动。但把这个循环放到真实环境中还需要回答几个问题:

  • 如果它一直找不到答案怎么办?
  • 如果工具一直报错怎么办?
  • 如果任务已经完成,它却还在继续行动和推理怎么办?

因此,我们不仅要让 Agent 能够循环,还要设计好循环的边界。Anthropic 也明确提出:Agent 应依据环境反馈评估进展,在遇到阻碍时寻求人类帮助,并设置最大迭代次数等停止条件。

参考:Building effective agents ↗

3.1 如何防止智能体陷入死循环

这里的“死循环”,可以理解为:Agent 不断行动,却没有取得有意义的进展。常见情况如下:

情况原因买可乐的例子可以怎么处理
重复相同行为没有有效利用历史行动和反馈,无法识别哪些方法已经尝试过、为什么不可行已经确认冰箱里没有可乐,却反复检查;或者在两家已经确认缺货的商店之间来回寻找保留已尝试的方法、结果和失败原因;发现连续行动没有带来新信息或任务进展时,调整策略,必要时停止
执行遇到阻碍外部环境或工具无法支持当前行动,但系统没有区分“等待或重试能解决的问题”和“必须改变条件的问题”商店库存查询一直没有响应,仍无限等待;或者付款因余额不足失败,却不断重复付款设置超时和有限重试;临时故障可以等待后重试,余额不足等问题则需要补充条件、换方案或请求帮助
缺少结束标准智能体无法判断什么算完成、什么情况下应放弃继续尝试已经买到符合要求的可乐,却继续寻找“更便宜的一瓶”;附近商店都缺货,仍无限扩大寻找范围提前明确完成条件和搜索范围,例如“买到一瓶预算内的可乐即可”;达到时间、费用或尝试次数上限时,整理结果并停止

应对时,可以分成两层。

第一层:让 Agent 根据反馈调整

工具失败时,应该告诉模型“为什么失败、哪些信息仍然有效”,让它有机会修正下一步。

临时网络错误可以有限重试;缺少权限或输入错误,则需要先解决原因。重试策略通常也会区分异常类型,并设置重试次数和等待间隔。

参考:LangGraph 容错机制 ↗

第二层:由程序设置硬性边界

例如,限制最大模型调用轮数、运行总耗时、token 费用和同类错误的重试次数。

这些限制需要由运行 Agent 的程序执行,不能只在提示词里写“不要死循环”。OpenAI Agents SDK 提供了 max_turns,超过上限会抛出异常,需要应用接住并处理。

参考:Running agents ↗
重复调用不一定是无效循环。等待一份报告生成时,定期查询状态可能是合理的。判断重点是:这次行动是否有明确用途,是否仍在允许的时间和成本范围内。
具体阈值应根据任务测试确定,不能把“最多循环 10 次”当成适用于所有 Agent 的标准。

3.2 智能体什么时候该停下来

停止不只有一种情况。产品设计时,至少应区分下面四种状态:

任务完成

触发条件交付物已经满足验收条件

告诉用户给出结果和必要的完成依据

暂停并等待

触发条件缺少用户信息、授权,或需要人工确认

告诉用户说明缺什么,保存进度,等待补充后继续

无法继续

触发条件工具调用总是失败,或者可行方法已经尝试,仍无法完成

告诉用户说明已完成部分、阻碍和可选下一步

被终止

触发条件达到最大运行时间、费用、轮数上限,或用户手动停止

告诉用户明确任务尚未完成,以及停止原因

“模型说完成了”和“任务真的完成了”,需要分开判断。
比如用户要求“整理报告并保存为文件”,只生成一段报告文字还不算完成;还需要确认文件确实保存成功。能够用程序检查的条件,应尽量用实际结果检查;主观质量则可以结合明确标准或人工评审。

接近运行上限时,也可以提前进入收尾流程,整理已完成内容,而不是等异常发生后直接丢失结果。LangGraph 的剩余步数机制就支持这种提前处理方式。

参考:循环步数与提前收尾 ↗

另外,暂停与结束不同。需要用户确认时,可以保存任务状态,收到回复后继续,而不是重新执行整个任务。

参考:Interrupts ↗

3.3 根据实际需要调整循环

基础循环只是起点。面对不同业务和场景,我们可以在循环的不同位置加入处理步骤。可以从四个位置考虑:

  1. 01

    模型决策前

    整理当前目标、已完成事项、失败记录和剩余预算

    告诉 Agent:“已经查过这三家店,前两家缺货,剩余预算 10 元”

  2. 02

    工具执行前

    检查参数、权限和是否需要确认

    查询商品库存可以直接执行;超过预算的购买需要先确认

  3. 03

    工具返回后

    整理结果、更新状态、判断是否需要重试

    区分“商品缺货”“商店关门”和“查询接口暂时不可用”

  4. 04

    准备结束时

    检查交付物是否真正满足要求

    确认订单确实创建成功,再告诉用户已经购买

这些处理步骤可以通过程序、规则或额外的模型调用完成。LangChain 的中间件机制就是在模型和工具执行的前后加入处理,例如调整输入、筛选工具、处理失败和提前终止。

参考:Middleware ↗
继续用买可乐的例子

查看冰箱没有可乐查询商店检查价格是否符合预算购买确认买到了结束

如果价格超出预算,就暂停询问用户;如果查询失败,就按错误原因处理;如果买到了,就停止,不再继续找其他商店。

4. 练习题

01 / 冰箱里没有可乐,下一步呢?

Agent 已检查冰箱并确认没有可乐,却又连续两次检查同一个冰箱。哪种处理最合理?

02 / 找到了可乐,却超过预算

用户要求总价不超过 10 元,当前商品加配送费共 12 元,需要用户确认是否增加预算。此时应该怎么处理?

本课产出

画出任务的决策、行动与反馈循环,并明确停止条件和关键检查点。

进入下一课