ReAct 与 Plan-and-Execute:Agent 推理的两种思路
假设你让一个 AI Agent 帮你查”特斯拉 2024 年第四季度的毛利率,和比亚迪比怎么样”。
这个任务拆开来看,需要好几步:查特斯拉的数据,查比亚迪的数据,然后做比较。问题是——Agent 怎么组织这些步骤?
两种完全不同的做法。
一种:边想边做。Agent 先想”我需要查特斯拉的数据”,去搜索,看到结果后想”还需要比亚迪的数据”,再去搜,最后做比较。每走一步,都看上一步的结果来决定下一步。
另一种:先把计划想清楚。Agent 先花时间规划:”第一步查特斯拉财报,第二步查比亚迪财报,第三步对比”,然后按计划执行。
前者叫 ReAct,后者叫 Plan-and-Execute。这是构建 AI Agent 最基本的两种推理范式,也是做 Agent 架构设计时绕不开的一个选择。
下面我会分别拆开讲它们怎么工作,各自的强项和短板,最后聊聊实际中怎么选。
ReAct:边推理,边行动
它在做什么
ReAct 这个名字来自 2022 年的一篇论文(Yao et al., 2022),是 Reasoning 和 Acting 的合写。想法直白:让大模型在”想”和”做”之间交替进行。
每次循环三个环节:
- Thought:模型分析当前状况,判断下一步怎么办
- Action:调用一个工具或执行一个操作
- Observation:拿到行动的结果
拿到结果后,回到 Thought,开始新一轮循环,直到任务完成。
完整走一遍
还是那个”特斯拉 vs 比亚迪毛利率”的问题,ReAct 的处理过程大概长这样:
Thought: 我需要查特斯拉 2024Q4 毛利率,先搜一下
Action: search("特斯拉 2024年第四季度 毛利率")
Observation: 特斯拉 2024Q4 毛利率为 16.6%,低于市场预期
Thought: 拿到特斯拉数据了,接下来查比亚迪
Action: search("比亚迪 2024年第四季度 毛利率")
Observation: 比亚迪 2024Q4 汽车业务毛利率约 20.3%
Thought: 两组数据齐了,可以对比
Action: finish("特斯拉 16.6%,比亚迪约 20.3%,比亚迪高出约 3.7 个百分点...")
注意看 Thought 那几行。模型在每一步都在”自言自语”——分析当前状态,决定下一步。这些思考过程用户平时看不到(除非开 debug 模式),但它们是 ReAct 的核心:正因为每步都在思考,模型才能根据实际看到的结果来调整策略。
如果第一次搜索”特斯拉毛利率”没拿到 Q4 的数据,模型会在 Thought 中发现这个问题,换个关键词再搜。这种”走一步看一步,不对就换方向”的能力,是 ReAct 最大的特点。
强在哪,弱在哪
动态适应是 ReAct 最突出的优势。每一步都基于最新观察做决策,天然能处理不确定的情况。搜索结果不理想?换个词。API 返回报错?换个方式。这种灵活性在和信息源交互的场景下特别有用。
可解释性也不错。Thought-Action-Observation 链条就是完整的推理记录,出了问题可以追溯每一步的决策逻辑,看哪一步走偏了。
但 ReAct 有几个让人头疼的地方:
Token 消耗大。每步都有一个 Thought,复杂任务可能十几轮循环,token 花得快。在按量计费的场景下,这笔开销不能忽视。
容易兜圈子。模型在某一步走了弯路之后,可能反复尝试相似的 Action,陷入死循环。实际使用中通常要设最大循环次数来兜底。
缺乏全局视野。整个过程中,模型是”走一步看一步”,没有对任务的宏观理解。对于需要协调多个步骤的复杂任务,这可能导致效率很低——它可能先查了 A,然后查 B,查完 B 才发现需要换个角度重新查 A。
运作机制
用伪代码来描述 ReAct,大概是这样:
while not done:
thought = LLM.think(context + history)
action = LLM.choose_action(thought)
result = execute(action)
history.append(thought, action, result)
一个循环,每轮都让模型基于当前上下文和历史来思考和行动。简单是简单,但效果出奇地好。
Plan-and-Execute:先想好,再做
换一种思路
Plan-and-Execute 和 ReAct 截然相反。它不急着动手,而是先把计划想清楚,然后按计划走。
两个阶段:
- Plan:分析任务,生成一个有序的子任务列表
- Execute:按顺序执行每个子任务
执行过程中某个步骤失败了?触发 Replan——重新审视计划,做出调整。
同一个问题,Plan-and-Execute 怎么做
还是那个毛利率的问题:
─── Plan 阶段 ───
任务:对比特斯拉和比亚迪 2024Q4 毛利率
计划:
Step 1: 搜索特斯拉 2024Q4 财报,提取毛利率
Step 2: 搜索比亚迪 2024Q4 财报,提取毛利率
Step 3: 对比两者毛利率,生成分析
─── Execute 阶段 ───
执行 Step 1: search("特斯拉 2024Q4 毛利率")
→ 16.6%
执行 Step 2: search("比亚迪 2024Q4 毛利率")
→ 约 20.3%
执行 Step 3: 对比分析
→ 比亚迪高出约 3.7 个百分点...
和 ReAct 对比一下,区别在哪?
Plan-and-Execute 在一开始就确定了三步走策略,然后按部就班地执行。它不需要每步都”想”,因为计划已经定好了。Execute 阶段甚至可以不调用 LLM,直接把参数传给工具就行。
但这也恰恰是它的弱点。如果 Step 1 的搜索结果里没有毛利率呢?Plan 阶段生成的计划基于模型对任务的初始理解,它还没看到 Step 1 的搜索结果。这时候要么硬着头皮按原计划走(可能后面的步骤都建在错误的基础上),要么停下来 Replan(额外的 LLM 调用,也有时间成本)。
几种变体
Plan-and-Execute 不是一种固定的模式,有几种常见的变体:
单次规划。一口气生成完整计划,执行到底不调整。简单粗暴,适合步骤明确、不确定性低的场景。
多次重规划。执行过程中遇到问题就停下来重新规划。灵活性强,但代价是额外的 LLM 调用。
层级规划。先定大方向,再逐层细化。比如大计划是”完成竞品分析”,子计划分别是”收集数据→分析对比→撰写报告”,每个子计划下面还有更细的步骤。复杂任务中,这种层级结构比一维的列表好管理。HuggingGPT 就是这个思路——先用 ChatGPT 做任务规划,然后把子任务分给 HuggingFace 上的专业模型。
运作机制
plan = LLM.generate_plan(task)
for step in plan:
result = execute(step)
if failed:
plan = LLM.replan(task, plan, failed_step, error)
对比 ReAct 的 while 循环,Plan-and-Execute 是线性的、有序的。执行阶段不需要每步都调 LLM,这在 Token 成本上有优势。
逐项对比
聊完了各自的机制,现在做一个系统对比。
本质区别
一句话:ReAct 是在线推理,Plan-and-Execute 是离线规划。
“在线”不是说联网,是说决策是边执行边做的,每步都依赖最新信息。ReAct 的 LLM 调用贯穿整个执行过程。
“离线”是说计划在执行之前一次性生成,基于模型对任务的初始理解。Plan-and-Execute 的 LLM 调用集中在 Plan 阶段,Execute 阶段轻很多。
这个区别会渗透到方方面面。
多维度对比表
| 维度 | ReAct | Plan-and-Execute |
|---|---|---|
| 决策方式 | 增量式,逐步决策 | 一次性,全局规划 |
| 对新信息的适应 | 天然适应,每步都看新结果 | 需要显式 Replan 才能调整 |
| LLM 调用次数 | 多(每步都调) | 少(计划 + 可选 Replan) |
| 执行效率 | 低(每步都要”想”) | 高(按计划走) |
| 上下文窗口压力 | 大(要记住完整历史) | 小(计划本身就是压缩的历史) |
| 错误恢复 | 自然(下一步自动调整) | 需要机制支持(Replan) |
| 适合的任务类型 | 探索性、不确定性高 | 结构化、步骤明确 |
各自擅长的场景
ReAct 更适合:
- 信息检索。不确定搜索会返回什么,需要根据结果动态调整
- 多轮对话。用户每一轮回复都是新信息,需要实时响应
- 调试排错。需要不断观察输出,灵活调整策略
Plan-and-Execute 更适合:
- 工作流编排。步骤明确,比如 ETL 流程、数据处理 pipeline
- 多工具协作。需要把不同工具按特定顺序串起来
- 并行执行。计划中互相独立的步骤可以同时跑,Plan-and-Execute 天然支持这种并行性
Benchmark 里的表现
在 Yao et al. 的原始论文中,ReAct 在 HotPotQA(多跳问答)和 ALFWorld(文字游戏)上优于纯推理(Chain-of-Thought)和纯行动(Act-only)。”边想边做”确实比”只想不做”或”只做不想”好。
但 Plan-and-Execute 类方法在某些结构化任务上表现更好。WebArena(网页操作基准测试)中,先规划再执行的方法完成率高于纯 ReAct——因为网页操作通常是确定性的步骤序列,全局规划的优势很明显。
一个有意思的发现:ReAct 在简单任务上容易”过度思考”,花很多 token 在 Thought 上却不如直接做;Plan-and-Execute 在简单任务上反而高效,因为计划阶段可以一步到位。
Function Calling 和这两者是什么关系
这点容易混淆,值得单独讲。
Function Calling ≠ ReAct
不少人的理解是”我用了 Function Calling,就是在用 ReAct”。
这个想法不对。
Function Calling 是大模型的一种能力——它知道什么时候该调用外部工具,能生成符合格式的调用参数。这是基础设施层面的东西。
ReAct 是推理范式——它规定的是”先思考再行动,看到结果后再思考”的循环模式。这是架构层面的东西。
打个比方:Function Calling 是”手”,ReAct 和 Plan-and-Execute 是”脑子指挥手的方式”。你可以用手去执行 ReAct 的 Action 步骤,也可以用手去执行 Plan-and-Execute 的 Execute 步骤。手本身不关心你用的是哪种指挥方式。
三层架构
把它们的层级关系画出来:
┌───────────────────────────────────┐
│ 应用层(Agent) │
│ 对话助手 / 数据分析 / 编程助手 │
├───────────────────────────────────┤
│ 范式层(推理策略) │
│ ReAct / Plan-and-Execute / ... │
├───────────────────────────────────┤
│ 基础层(核心能力) │
│ LLM 推理 + Function Calling │
└───────────────────────────────────┘
三层各管各的。基础层:LLM 提供推理能力,Function Calling 提供工具调用能力。范式层:决定推理和行动的时序——交替进行(ReAct)还是先规划再执行(Plan-and-Execute)。应用层:基于范式层构建具体的 Agent。
说”用了 Function Calling 就是 ReAct”,就好比说”有了手就是在做菜”——手是必要条件,不是充分条件。关键是怎么指挥这双手。
两个常见误区
“Plan-and-Execute 不需要 Function Calling”——不对。Plan-and-Execute 的 Execute 阶段同样要调工具。Plan 阶段说”Step 1:搜索特斯拉毛利率”,Execute 阶段就需要 Function Calling 来实际执行搜索。区别只在于调用的决策方式:ReAct 是实时决策,Plan-and-Execute 是按计划执行。
“ReAct 是 Function Calling 的升级版”——也不对。它们不在同一层。Function Calling 解决”怎么调用工具”,ReAct 解决”什么时候调、调完怎么处理”。两者互补,不互相替代。
融合:现实中的做法
纯 ReAct 和纯 Plan-and-Execute 都有短板,实际项目中很少只用一种。
为什么要混着来
纯 ReAct 的问题:缺乏全局规划。想象你在陌生城市找餐厅——走一步看一步,绕弯路是难免的。先看地图规划路线,遇到封路再灵活调整,效率会高得多。
纯 Plan-and-Execute 的问题:对变化反应迟钝。计划基于初始理解,但现实经常不按计划走。第一步搜索就返回了意外结果,原计划可能直接废了。
几种融合方式
Plan-and-Execute + ReAct 混合。Plan-and-Execute 定大方向,每个步骤的执行用 ReAct 模式处理。LangGraph 的 Plan-and-Execute Agent 就是典型实现——先规划,执行时保留灵活性。
Reflexion(Shinn et al., 2023)在 ReAct 上加了自我反思。Agent 完成任务后会复盘执行过程,总结经验,下一轮做得更好。相当于给 ReAct 加了一个跨回合的”元规划”能力。
ReWOO(Xu et al., 2023)走了另一条路。让模型在不看任何工具结果的情况下,先把所有需要的工具调用推理出来,然后批量执行。LLM 调用次数少了,上下文窗口压力也小了。代价是如果前置推理有误,后面可能全部白费。
一个趋势
2024 年以来的 Agent 框架越来越倾向于混合架构。Claude 的 tool use、OpenAI 的 Assistants API,底层都不是纯粹的 ReAct 或 Plan-and-Execute,而是根据任务特征动态选择策略。
这也符合直觉:简单问题不需要做计划,复杂问题不能只靠走一步看一步。好的 Agent 系统,应该能自己判断当前任务适合哪种方式。
怎么选
如果你在构建自己的 Agent:
从 ReAct 开始。 实现简单,一个 while 循环加几个工具定义就能跑,大部分场景够用。
出现以下情况时引入 Plan-and-Execute:
- 任务超过 5-6 步,ReAct 开始”迷路”
- 步骤之间有依赖关系,需要全局协调
- 需要并行执行多个子任务
- Token 成本成了瓶颈(Plan-and-Execute 的 Execute 阶段不需要每次都调 LLM)
最终用混合方案。 先规划大方向,执行细节用 ReAct 处理。遇到重大偏差时 Replan,然后继续。
一句话:ReAct 是默认选项,Plan-and-Execute 是优化手段,融合是最终形态。
延伸阅读
- ReAct 原始论文:Yao et al., “ReAct: Synergizing Reasoning and Acting in Language Models”, 2022
- Reflexion:Shinn et al., “Reflexion: Language Agents with Verbal Reinforcement Learning”, 2023
- ReWOO:Xu et al., “ReWOO: Decoupling Reasoning from Observations for Efficient Augmented Language Models”, 2023
- Plan-and-Solve:Wang et al., “Plan-and-Solve Prompting: Improving Zero-Shot Chain-of-Thought Reasoning by Large Language Models”, 2023