type
Post
status
Published
date
Apr 26, 2026
slug
agent20
summary
tags
Agent
category
icon
password
1. 先给结论
在工程型 Agent 项目里,ReAct 更像“默认执行内核”,而 Plan-and-Execute 更像“任务级编排策略”。
ReAct 的核心是:
每一步都在“观察当前状态 → 推理下一步 → 调工具 → 读结果 → 再决定下一步”之间循环。
Plan-and-Execute 的核心是:
先生成一个较完整的多步计划,再按计划逐步执行;执行后可以重新规划。
在真实项目里,例如 Claude Code、OpenCode、OpenClaw 这类 Agent,通常不会只选择其中一种。更常见的工程落地是:
底层用 ReAct 风格的工具调用循环保证反馈闭环,上层用 Plan Mode、Todo、Subagent、Workflow 来增强规划能力。
Claude Code 官方文档中,Plan mode 是一种“先读取和提出方案、不编辑文件,等待用户批准”的权限/交互模式,而不是说整个 Agent 只采用 Plan-and-Execute 架构。(Claude Code) OpenCode 也明确提供 Plan mode:先禁用改动能力,只建议如何实现,再切回 Build mode 执行。(OpenCode) OpenClaw 文档则把真实 Agent loop 描述为 intake、context assembly、model inference、tool execution、streaming、persistence 的序列化循环,这更接近工程里的 ReAct 式运行内核。(OpenClaw)
2. ReAct:边想边做,边做边修正
ReAct 来自 “Reason + Act”。原论文的关键点是让 LLM 交错生成推理轨迹与动作:推理帮助模型创建、跟踪、更新计划并处理异常;动作帮助模型调用外部环境获取信息。(arXiv) Google Research 对 ReAct 的解释也强调:动作会带来外部环境观察,推理则更新模型内部状态,二者交织形成动态决策过程。(Google Research)
一个典型 ReAct 轨迹如下:
图解:ReAct 的运行方式
ReAct 最大的价值不是“有思考过程”,而是它把 外部反馈 纳入了下一步决策。对代码 Agent 来说,这个反馈可能是
grep 结果、文件内容、类型错误、测试失败、权限拒绝、用户反馈、LSP 诊断、Git diff 等。Claude Code 的工具参考里列出了 Bash、Edit、Read、Grep、LSP、WebFetch、WebSearch、EnterPlanMode、ExitPlanMode 等工具,并说明 Claude 通常自行决定什么时候使用工具;这正是典型 Agent 工具循环的工程形态。(Claude Code)3. Plan-and-Execute:先规划,再执行,再重规划
Plan-and-Execute 的核心是把 Agent 拆成两个角色:
Planner:先生成多步计划。Executor:按计划逐步执行每个子任务。
LangChain 对 Plan-and-Execute 的定义很清楚:它由 planner 和 executor 两部分组成,planner 生成多步计划,executor 接收用户问题和当前步骤,并调用一个或多个工具完成该步骤;执行后还可以再次调用 planner 判断是否完成或是否需要后续计划。(LangChain) LangGraph 的教程也说,Plan-and-Execute 会先产生多步计划,然后逐项执行,并在某一步完成后重新审视和修改计划;它相对 ReAct 的优势是更显式的长期规划,也可以让强模型负责规划、弱模型负责执行。(白盒子)
图解:Plan-and-Execute 的运行方式
一个 Plan-and-Execute 轨迹如下:
n8n 的 Plan and Execute Agent 文档也把它描述成“类似 ReAct,但更关注规划;先创建高层计划,再逐步执行”,适合需要结构化方法和谨慎规划的任务。(n8n文档)
4. 两者的核心区别
维度 | ReAct | Plan-and-Execute |
决策粒度 | 每一步动态决定 | 先全局规划,再逐步执行 |
反馈方式 | 每次工具结果都会影响下一步 | 主要在 step 完成后更新状态,必要时 replan |
适合任务 | 探索型、不确定性高、环境反馈强 | 目标清晰、步骤可拆、长期任务 |
成本特点 | 可能每次工具调用都需要模型参与 | 可以大模型规划,小模型执行,降低成本 |
鲁棒性 | 对异常更敏感,容易即时修正 | 对初始计划质量依赖更强 |
可控性 | 轨迹细,但可能“走一步看一步” | 计划清晰,便于人审 |
典型代码场景 | Debug、查代码、修测试、处理线上问题 | 大型重构、迁移、批量任务、复杂工作流 |
LangChain 在介绍 planning agents 时提到,ReAct 这类逐步工具调用有两个局限:每次工具调用都需要 LLM 调用,以及它一次只规划一个子问题,可能导致轨迹不是全局最优;显式规划就是为了解决这两个问题。(LangChain) 但这并不意味着 Plan-and-Execute 总是更好,因为真实工程环境经常变化,错误信息和代码结构往往只有执行后才知道。
5. 从成熟 Agent 看:它们不是二选一,而是组合使用
5.1 Claude Code:ReAct 执行循环 + Plan Mode 人审闸门
Claude Code 的 Plan mode 不是传统意义上完全独立的 Plan-and-Execute 架构,而是一个权限模式:Claude 先研究代码并提出计划,不编辑源码,等用户批准后才开始执行。官方文档明确说,Plan mode 会读取文件、运行只读探索命令、写计划,但不会编辑源文件;计划完成后用户可以批准、继续规划、或者用浏览器界面进一步审阅。(Claude Code)
这说明 Claude Code 更像:
也就是说,Claude Code 的工程取向是:高风险修改前用 Plan Mode 收敛目标,真正落地时仍然依赖 ReAct 式工具反馈循环。
5.2 OpenCode:Plan Agent / Build Agent 分离,但执行仍是工具循环
OpenCode 官方文档建议新增功能时先创建计划:Plan mode 会禁用修改能力,只建议如何实现;用户满意后再切回 Build mode 让它执行。(OpenCode) OpenCode README 也说明它内置两个 agent:
build 是默认全权限开发 agent,plan 是只读 agent,默认拒绝文件编辑,适合探索陌生代码库或规划变更。(GitHub)从源码结构看,OpenCode 的工具注册包含 shell、read、glob、grep、edit、write、task、todo、search、skill、patch、plan 等工具,其中
plan 工具只在 experimental plan mode 且 CLI 客户端下注册。(GitHub) 这反映出它的工程设计不是“所有任务都必须先 planner 再 executor”,而是把 planning 作为一种可切换能力嵌入工具系统。简化后的工具注册结构可以理解为:
OpenCode 的 prompt 里还强调 TodoWrite:复杂任务要用 todo 规划和跟踪,任务完成后及时标记 completed;这其实是“ReAct + Todo 计划记忆”的典型组合,而不是纯 Plan-and-Execute。(GitHub)
5.3 OpenClaw:长生命周期 Agent 更依赖 ReAct 式事件循环
OpenClaw 的文档把 agentic loop 描述为一个真实运行路径:intake、context assembly、model inference、tool execution、streaming replies、persistence;并且每个 session 是序列化运行,过程中会订阅事件并把工具事件桥接到 agent stream。(OpenClaw)
这类个人助理 / 多通道 Agent 的特点是:
输入可能来自 Telegram、Slack、Discord、CLI、Web UI、自动化任务;工具可能包括浏览器、消息、会话、cron、node、canvas;状态需要跨 session 持久化;外部世界随时变化。
因此它天然更适合 ReAct 风格:每次读取状态、调用工具、拿到 observation、再决定下一步。OpenClaw 的 session tools 支持列出会话、读取历史、给其他 session 发消息、spawn 子 agent、yield 等,而且这些工具还受 tool profile、allow/deny policy 和可见性范围约束。(OpenClaw) 多 agent routing 则把每个 agent 定义为独立的 workspace、state directory、session store 和 persona scope。(OpenClaw)
这类架构里,Plan-and-Execute 可以作为某个任务的局部策略,但底层一定需要一个持续的、可恢复的、可接收外部事件的 Agent loop。
6. 源码角度:ReAct 内核一般怎么实现?
一个最小 ReAct Agent 内核通常长这样:
OpenCode 的 session processor 源码也能看到类似工程要素:它维护
toolcalls 状态,提供 updateToolCall、completeToolCall,在工具开始时创建 pending 状态,在完成时把状态更新为 completed,并把输出写回 session。(GitHub) 这类设计正是 ReAct 能在真实工程中落地的原因:工具不是一次性调用,而是 Agent 状态机的一部分。简化成状态机是这样的:
7. 源码角度:Plan-and-Execute 一般怎么实现?
Plan-and-Execute 可以用一个显式状态图实现:
这里有一个非常重要的工程事实:
Plan-and-Execute 的 Executor 内部,往往还是一个 ReAct Agent。
原因很简单:执行某一步时仍然需要查文件、调用 API、运行测试、处理失败、修正路径。Planner 解决的是“长期目标分解”,ReAct 解决的是“每一步如何根据反馈落地”。
8. 分别适用于什么场景?
8.1 ReAct 适合的场景
ReAct 适合 高不确定性、强反馈、需要动态探索 的任务。
典型场景:
- 代码 Debug
Bug 的根因通常不知道,需要先读日志、搜代码、跑测试、定位,再决定修复方式。
- RAG 问答
用户问题可能需要多轮检索、重写查询、读取文档、比对证据,再生成答案。
- 线上排障
需要看监控、查日志、读配置、调用命令,每一步结果都会改变下一步。
- 代码库探索
陌生项目无法一开始就写出完整计划,需要先理解目录、依赖、调用链。
- 工具结果不可预测的任务
例如浏览网页、调用第三方 API、执行 shell、跑测试、访问数据库。
ReAct 的优势是:
不依赖一次性计划的正确性,能够根据 observation 及时修正。
它的劣势是:
容易局部最优、步骤变长、token 成本增加,且如果没有 todo / memory / summary,长任务中可能丢失全局目标。
8.2 Plan-and-Execute 适合的场景
Plan-and-Execute 适合 目标明确、结构稳定、步骤可预期、需要人审或并行 的任务。
典型场景:
- 大型重构
例如把 REST API 迁移到 GraphQL,涉及模块多,需要先设计迁移顺序。
- 批量迁移
例如从 Jest 迁到 Vitest、从 Webpack 迁到 Vite、从旧 SDK 迁到新 SDK。
- 多 Agent 协作
Planner 拆分任务,多个 Executor 并行处理不同模块。
- 强合规 / 强审计任务
需要先产出明确计划,让人确认风险点,再执行。
- 成本敏感任务
强模型负责少量规划,弱模型或规则程序负责大量执行。
Plan-and-Execute 的优势是:
全局视角更强,计划更容易审查,也更容易做并行和成本优化。
它的劣势是:
初始计划一旦基于错误假设,执行会产生级联偏差;而且真实环境反馈复杂时,频繁 replan 可能让架构变重。
9. 为什么项目里通常会选择 ReAct 作为默认主循环?
原因一:真实世界不是静态任务列表
代码库、文件、测试、接口、权限、网络、用户反馈都不是静态的。Plan-and-Execute 假设“先规划出大体路径”,但在代码 Agent 里,很多关键信息只有工具调用后才知道。
例如:
ReAct 对这类变化天然友好,因为它每一步都允许更新策略。
原因二:工具调用本身需要闭环
成熟 Agent 的关键不是“会写计划”,而是“能安全、可靠地调用工具”。Claude Code 的工具系统包含读文件、搜索、编辑、shell、LSP、WebFetch、WebSearch、Plan mode 等能力,并通过权限规则控制工具使用。(Claude Code) OpenCode 的工具注册也展示了一个面向工程任务的完整工具面:shell、read、glob、grep、edit、write、task、todo、fetch、search、skill、patch、plan 等。(GitHub)
这些工具都不是“计划写完就能自动完成”的,它们需要:
调用 → 获得结果 → 判断结果是否符合预期 → 失败重试 → 改变策略 → 继续调用。
这就是 ReAct 的强项。
原因三:更容易接入权限、安全与人类确认
ReAct 的每一步都可以被权限系统拦截:
这和 Claude Code / OpenCode 的 Plan mode 并不冲突。Plan mode 负责让用户先审方案;ReAct tool loop 负责让每一步执行都能被权限、沙箱、hook、policy 检查。
Claude Code 的 Plan mode 明确会在批准后退出 plan mode,并切换到批准选项对应的权限模式开始编辑。(Claude Code) 这说明真实产品里“规划”和“执行权限”是两个层面的设计。
原因四:适合 RAG 和代码 Agent 的“检索—验证—修正”范式
RAG 中一个常见问题是:第一次检索结果不一定够好。ReAct 可以这样做:
Plan-and-Execute 当然也能做,但 RAG 任务经常需要根据检索结果改写 query、补充检索、排除噪声、重排证据。ReAct 的即时反馈循环更自然。
原因五:实现成本更低,工程复杂度更可控
一个 ReAct loop 的最小闭环是:
而 Plan-and-Execute 至少需要:
在早期项目中,如果直接上复杂 planner,很容易变成“计划很漂亮,执行很脆弱”。所以更稳妥的路径是:
先实现可靠 ReAct loop,再加 Todo、Plan mode、Subagent、Workflow。
LangChain 新版 middleware 也提供了 todo list 能力,用于复杂多步任务、长时间运行任务和进度可见性;它会给 agent 自动提供
write_todos 工具和相关系统提示。(LangChain 文档) 这说明业界也在向“ReAct 主循环 + 显式任务跟踪”靠拢,而不是简单用一个大 planner 替代 ReAct。10. 推荐的项目架构:ReAct Core + Plan Layer
我更推荐的生产架构如下:
这套架构里:
ReAct Core:负责实际工具闭环。Plan Layer:负责复杂任务前的人审和全局分解。Todo / Memory:负责跨步骤目标保持。Subagent:负责隔离上下文和并行探索。Policy / Sandbox:负责安全边界。Observability:负责 trace、回放、评估。
11. 一个更接近生产的代码骨架
下面是一个组合式实现:复杂任务先生成 plan,然后每个 step 交给 ReAct executor。
关键点有三个:
- Plan 只做任务分解,不直接替代执行器。
- Executor 内部仍使用 ReAct,因为执行阶段需要工具反馈。
- Replan 是异常路径,不是每一步都重新大规划。
12. 如何判断该用哪种模式?
可以用下面这个决策表:
问题 | 推荐模式 |
用户只是问“这段代码做什么?” | ReAct,读文件 + 解释 |
用户要修一个未知 bug | ReAct |
用户要实现一个小功能,范围明确 | ReAct + 简短 todo |
用户要做跨模块重构 | Plan-and-Execute + ReAct executor |
用户要迁移框架 / SDK | Plan-and-Execute |
用户要处理线上告警 | ReAct |
用户要多个 agent 并行研究 | Planner + Subagents + ReAct |
用户要高风险数据库变更 | Plan mode + 人审 + ReAct |
用户要长期自动化任务 | ReAct loop + memory + scheduler |
用户要可审计流程 | Plan-and-Execute + trace |
13. 为什么“项目中选择 ReAct”通常是合理的?
如果你的项目是 RAG、代码 Agent、运维 Agent、数据分析 Agent 或个人助理 Agent,我会优先把 ReAct 作为默认执行模式,原因是:
第一,真实任务的信息不完整,ReAct 可以边查边修正。第二,工具结果不可预测,ReAct 可以把 observation 变成下一步决策。第三,权限控制更自然,每一步工具调用都能被拦截和审计。第四,实现更轻,先跑通闭环,再叠加 plan/todo/subagent。第五,复杂任务也可以在 ReAct 上方加 planning,而不是替换 ReAct。
这也是为什么成熟 Agent 看起来都在走类似路线:
Claude Code:Plan mode 用于改动前审查,执行仍依赖工具循环。OpenCode:Plan agent 和 Build agent 分离,但工具系统、TodoWrite、Task、Edit、Bash 等仍构成执行闭环。OpenClaw:长生命周期、多通道、多 session 的 agent loop,本质需要持续接收事件、调用工具、持久化状态和处理 observation。
最终结论可以概括成一句话:
Plan-and-Execute 解决“我要怎么拆任务”,ReAct 解决“我在真实环境里下一步该怎么做”。工程项目里通常先选 ReAct 做底座,再把 Plan-and-Execute 作为复杂任务的上层策略。
分享
