Agent 标准执行循环关键阶段构成解析(详解 Plan / Act / Observe / Reflect 的核心职责)

Agent Loop 是把”理解目标—调用工具—评估结果”串成闭环的标准执行循环,其关键阶段可归纳为 Plan(规划)、Act(行动)、Observe(观察)、Reflect(反思)四步;少任何一步 Agent 都会退化为一次性问答或失控的死循环。生产级 Agent 在每一步都有明确的核心职责:Plan 决定”下一步做什么”,Act 决定”动手做什么”,Observe 决定”看到什么结果”,Reflect 决定”还要不要继续”。

一、为什么 Agent Loop 不是”问一句答一句”

LLM 自身只能”想”,不能”动”。要让 Agent 真正完成任务,必须把它放进一个循环:想一次、做一次、看一次、评一次,再决定下一次。ReAct 框架最早把这套流程形式化,2026 年主流 Agent 平台(Azure Logic Apps Agent Loop、Claude Agent SDK、LangGraph、Semantic Kernel)都把 Plan→Act→Observe→Reflect 作为默认骨架。

循环的价值不只是”多做几步”,而是把”我以为我做完了”和”我确实做完了”区分开。一次性问答里没有”对照目标”的机会,Agent 容易在第一步就宣称完成;循环强制每一步都回到目标校验,是把 Agent 从玩具推向生产的关键。

二、四阶段的核心职责对照

四阶段不是顺序清单,而是一个有反馈的闭环。下面这张表把每个阶段的核心职责、典型输入、典型输出、与 LLM 的关系列清楚。

阶段 核心职责 典型输入 典型输出 与 LLM 的关系
Plan 把目标拆成可执行步骤,选下一步动作 目标、上下文、可用工具列表 编号步骤 + 工具选择 + 调用参数 LLM 做推理与决策
Act 调用一个工具或执行一段代码 Plan 选中的工具 + 参数 工具原始输出(API 响应、文件内容) 通常不调 LLM,由 SDK 调度
Observe 把工具输出结构化、剔除噪声 Act 原始输出 摘要后的 observation 注入回上下文 多为格式化代码,少量 LLM 摘要
Reflect 对照目标评估进度,决定继续 / 重试 / 终止 累积 observation + 目标 状态判定:on_track / done / stuck LLM 做评估与决策

这张表的隐藏含义是:LLM 只在 Plan 和 Reflect 两步真正”思考”,Act 与 Observe 是”动手”与”看结果”,由 SDK 与运行时承载。把 LLM 的角色与执行器的角色分开,是 Agent 框架与单纯 prompt 调用的本质区别。

三、Plan 阶段:把目标拆成可执行的步骤

Plan 阶段最容易踩的坑是”一次生成 30 步大计划”。世界会变,过长的计划在第 3 步就可能失效。主流做法是让 Planner 输出 3–5 步的小计划,并显式声明”在第 N 步之后重新规划”。

Plan 的输入必须包含三件事:用户的最终目标、当前已知上下文(含历史 observation)、可用工具及其 schema。输出建议采用结构化格式(编号步骤 + 每步要调的工具 + 关键参数),便于下游 Act 阶段直接消费。

# Plan 阶段输出(结构化示例)
Goal: 给用户写一份关于"分布式锁"的对比文档
Steps:
  1. 搜索内部知识库关键词"分布式锁",取前 5 条结果
  2. 对每条结果调用 summarize 工具,提取 200 字以内摘要
  3. 按"实现方式 / 一致性 / 性能"三维度生成对比表
  4. 输出 Markdown 文档到 /tmp/lock.md
ReplanAfter: step 2

replan_after 是关键设计:明确告诉 Agent 在哪一步要回头重新评估,避免一口气执行到底才发现第 2 步的工具就用错了。

四、Act 与 Observe 阶段:动手与看结果

Act 阶段的核心是”一次只做一个原子操作”。一次调用写入多个文件、一次 SQL 同时改多张表,会让回滚成本陡增。SDK 在这一步通常禁用 LLM,直接把 Plan 输出的参数传给工具运行时。

Observe 阶段容易被低估。它的职责不只是”把工具输出塞回上下文”,还要做三件事:解析工具原始输出(JSON / 二进制 / 异常)、按需截断或摘要(防止上下文爆炸)、对工具错误做归因(是参数错了、权限不够、还是外部系统故障)。这三件事直接决定 Agent 的稳定性。

# Observe 阶段的最小实现(伪代码)
def observe(act_result: ToolResult) -> Observation:
    if act_result.exit_code != 0:
        return Observation(
            status="error",
            summary=act_result.stderr[:500],
            hint="检查工具参数或权限",
        )
    return Observation(
        status="ok",
        summary=summarize(act_result.stdout, max_tokens=300),
        raw=act_result.stdout if len(act_result.stdout) < 2000 else None,
    )

Observe 输出的 Observation 会被注入下一轮 Plan 的上下文,模型据此决定下一步动作。

五、Reflect 阶段:评估进度,决定是否继续

Reflect 是四阶段里最被低估的一环,也是生产 Agent 与 Demo Agent 的分水岭。Reflect 阶段要回答三个问题:目标达成没?上一步成功没?若失败是否可恢复?对应三种动作:done / continue / escalate。

Reflect 必须与 Executor(执行器)解耦。把”反思”塞进 Act 后的同一次 LLM 调用,会引发乐观偏差——刚成功的执行器倾向于宣称成功。生产做法是把 Reflect 设为独立的 prompt,甚至用不同模型做交叉评估。

# Reflect 阶段输出(结构化)
Question: 当前是否达成目标?
  -> Yes: 输出最终答案
  -> No : 继续
Question: 上一步是否成功?
  -> Yes: 按计划继续下一步
  -> No : 进入重试或升级路径
Question: 是否卡在重复失败上?
  -> Yes: 升级到人类处理
  -> No  : 继续

done / continue / escalate 三态判定必须显式返回,便于运行时记账与对账。

六、循环运行的关键工程约束

把四阶段串起来后,还需要给循环加上工程边界,否则 Agent 会”跑飞”或”烧光预算”。

  1. 设置最大步数(如 25 步),超过即强制终止;
  2. 设置最大 token / 美元预算,预算耗尽即终止;
  3. 设置最大墙钟时间,单轮工具调用超时即中断;
  4. 为 Reflect 阶段的 escalate 提供人类接管入口,不要让 Agent 自循环到资源耗尽;
  5. 把每一步的 Plan / Act / Observe / Reflect 写入可观测日志,便于事后复盘。

常见问题(FAQ)

Q1:Plan 阶段能不能省掉,直接进 Act?

简单任务可以省,但只要任务跨多个工具调用,省掉 Plan 容易在第二步就失去方向感。

Q2:Reflect 一定要单独调用 LLM 吗?

可用规则判定替代简单场景,但涉及语义评估(”答案是否合理”)时仍需 LLM 介入。

Q3:循环跑飞(陷入死循环)怎么防?

同时设置最大步数、最大 token、最大重复失败次数三道闸门,触发任一即终止并升级。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
赵其鑫的头像赵其鑫管理团队

相关推荐

返回顶部