AI Agent原理篇04:Agent Loop:感知-思考-行动循环与 ReAct

前三篇讲了 Agent 是什么、模型如何工作、消息长什么样。这一篇进入 Agent 最核心的部分:循环。几乎所有 Agent 框架,不管包装得多复杂,内核都是同一个循环。

一、最简单的 Agent Loop

Agent Loop 只有四步:

  1. 调用模型:把目前为止的全部消息发给模型。
  2. 检查输出:如果模型请求调用工具,进入第 3 步;如果没有,说明它给出了最终回答,循环结束。
  3. 执行工具:由你的程序真正去执行,拿到结果。
  4. 回填结果:把工具结果作为新消息追加到消息列表,回到第 1 步。

用伪代码表示:

messages = [{"role": "user", "content": user_question}]

for step in range(MAX_STEPS):
    reply = call_model(system_prompt, messages, tools)
    messages.append(reply)

    if not reply.tool_calls:          # 没有工具调用,任务完成
        return reply.text

    for call in reply.tool_calls:     # 可能一次请求多个工具
        result = run_tool(call.name, call.arguments)
        messages.append({"role": "tool",
                         "tool_call_id": call.id,
                         "content": result})

return "超过最大步数,任务未完成"

就这么多。所谓「Agent 自主完成任务」,就是模型在这个循环里一轮一轮地决定下一步做什么,直到它认为任务完成。

二、谁决定循环何时结束

正常情况下,模型自己决定结束:当它认为信息足够、不再需要调用工具时,就直接输出最终回答。

但不能完全依赖模型,程序还需要几道保险:

保护机制 作用
最大步数 防止无限循环,通常设置在十几到几十步
最大 token / 费用上限 防止一个任务把预算烧光
总超时 防止任务卡住不返回
重复调用检测 同一个工具、同样参数连续调用多次,说明模型陷入了死循环
人工中断 用户可以随时停止

触发保护时,不要只是简单报错。更好的做法是让模型基于已有信息做一次总结,告诉用户「查到了什么、还缺什么」。

三、ReAct:边想边做

ReAct 是 Reasoning + Acting 的缩写,是 Agent Loop 背后最有影响力的思路。它的核心是:不要一次性想好所有步骤,而是想一步、做一步、看结果,再决定下一步。

一个 ReAct 过程大致是这样的:

思考:用户问今天下单量为什么下降,我先看每小时的数据。
行动:query_orders(hours=24)
观察:10 点到 11 点下单量比平时少 70%。

思考:问题集中在 10 点之后,看看下单流程哪个环节出错。
行动:query_api_errors(start="10:00", end="11:00")
观察:支付接口错误率 60%,主要是超时。

思考:支付接口超时,看看支付服务的日志。
行动:read_logs(service="payment", start="10:00")
观察:10:05 起连接第三方支付网关持续超时。

思考:原因已经清楚,可以回答了。
回答:……

现在的模型大多不需要你在提示词里显式要求「思考 / 行动 / 观察」格式,工具调用机制本身就实现了这个模式。但理解 ReAct 有助于你设计工具:每个工具的返回结果,都是模型决定下一步的依据,结果越清晰,下一步越准确。

四、ReAct 与一次性规划的对比

一次性规划 ReAct
做法 先列出全部步骤,再依次执行 每一步根据上一步的结果决定
优点 过程可预期,容易审查 能应对中途发现的新情况
缺点 计划赶不上变化 可能走弯路,步数难以预估
适合 步骤相对明确的任务 排查、调研这类探索性任务

实际中两者常结合使用:先列一个粗略计划,执行过程中按 ReAct 方式调整。第 10 篇会专门讲规划。

五、循环里容易出的问题

  • 死循环:工具返回的错误信息不清楚,模型反复用同样的参数重试。解决办法是让错误信息说清楚原因和正确用法,并做重复调用检测。
  • 过早结束:模型没查完就急着给结论。可以在 System Prompt 里说明「什么情况才算完成」。
  • 上下文爆炸:每轮的工具结果都追加进消息列表,十几轮后上下文就满了。第 07 篇会讲怎么处理。
  • 跑偏:循环久了,模型忘了最初的目标。可以在关键节点重申任务,或者用待办列表跟踪进度。

六、动手:一个能运行的最小 Agent

把上面的伪代码换成任意一家模型 API,再接一个最简单的工具,比如「获取当前时间」或「执行 ping」,就是一个真正的 Agent。建议亲手写一遍,代码不超过 50 行,但能让你彻底理解后面所有框架在做什么。

写的时候注意三点:

  • 把每一轮的消息列表打印出来,观察它是怎么一步步增长的。
  • 故意让工具返回一个错误,看模型如何应对。
  • 把最大步数设成 2,观察任务被截断时的表现。

本篇小结

  • Agent Loop:调用模型 → 有工具调用就执行 → 回填结果 → 再调用,直到模型不再请求工具。
  • 结束由模型决定,但必须有最大步数、费用上限、超时等保护。
  • ReAct 的核心是边想边做,每步根据观察结果决定下一步。
  • 常见问题:死循环、过早结束、上下文爆炸、跑偏。

思考与练习

  • 用你熟悉的模型 API 写一个最小 Agent Loop,工具只有一个:执行 ping,然后问它「百度和谷歌哪个延迟更低」。
  • 如果模型连续 3 次用相同参数调用同一个工具,你的程序应该怎么处理?

上一篇:AI Agent原理篇03:消息结构与角色:System、User、Assistant、Tool
下一篇:AI Agent原理篇05:Tool Use / Function Calling 原理
返回系列总目录

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇