Plan-Execute-Replan 和 ReAct 的区别是什么?

面试 AI Agent 相关岗位的时候,经常会遇到一个问题:
Plan-Execute-Replan 和 ReAct 有什么区别?
很多同学第一次听到这个问题,第一反应可能是:
这俩不都是 Agent 的工作模式么?
好像都是:
- 先想一下
- 再调用工具
- 根据结果继续做
那为什么还要分成两个名字?
这个问题其实挺典型的。因为很多人在学习 Agent 的时候,会先接触到一堆名词:
- ReAct
- Plan and Execute
- Plan-Execute-Replan
- Reflection
- Multi-Agent
- Tool Calling
看起来每个词都不一样,但真正落到代码里,好像又都在做类似的事情。
于是最后就会形成一种很模糊的理解:反正都是让模型边想边干。
这个理解不能说完全错,但它不够精确。
如果你真的要做 Agent 系统,或者在面试里把这个问题讲清楚,就需要知道它们真正的差别不在于“有没有思考”,也不在于“有没有工具调用”,而在于:谁负责决定下一步?
- ReAct 是模型在每一步执行后,现场决定下一步。
- Plan-Execute-Replan 是先有一个整体计划,执行过程中再根据结果修正计划。
这两个模式的差别,本质上是 Agent 的“控制流”不一样。
1. 先看 ReAct
ReAct 这个名字其实是两个词拼在一起:
- Reasoning:推理
- Acting:行动
也就是说,ReAct 的核心思想是:模型不是一次性给出最终答案,而是在解决问题的过程中,一边推理,一边行动。
一个典型的 ReAct 流程大概长这样:
Thought: 我需要先知道当前项目有哪些文件 Action: list_files Observation: 返回文件列表 Thought: 我看到 package.json,需要查看依赖 Action: read_file(package.json) Observation: 返回 package.json 内容 Thought: 项目使用 pnpm,所以应该运行 pnpm test Action: run_command(pnpm test) Observation: 测试失败 Thought: 失败原因在 userService.test.ts,我需要查看这个文件 Action: read_file(userService.test.ts) Observation: 返回测试文件内容
你会发现,ReAct 的特点非常明显:
每一步都是根据上一轮工具返回的结果,临时决定下一步做什么。
它并不会一开始就写一个完整计划:
1. 查看目录 2. 查看 package.json 3. 运行测试 4. 定位失败原因 5. 修改代码 6. 再运行测试
当然,模型心里可能有一个大概方向,但在 ReAct 模式里,真正的下一步通常是在每次 Observation 之后才决定的。
这就像你在排查线上问题。
一开始你可能只知道:
服务挂了,我要查一下原因。
然后你先看日志。日志告诉你数据库连接失败。于是你再查连接池。连接池看起来没问题。于是你再查网络。网络又提示 DNS 解析异常。
整个过程不是提前排好的,而是根据每一步的新信息不断推进。
这就是 ReAct 很适合的场景:
- 信息不完整
- 路径不确定
- 每一步都依赖工具返回结果
- 需要边查边判断
例如:
- 调试 bug
- 查资料
- 排查故障
- 浏览网页
- 分析陌生代码仓库
这些任务都有一个共同点:
你不知道下一步一定是什么,必须先看上一轮结果。
2. ReAct 的问题
ReAct 很灵活,但它也有一个明显问题:
它太容易走一步看一步。
比如你让 Agent 做一个稍微复杂一点的任务:
帮我给这个项目加一个登录功能。
如果完全用 ReAct,它可能会这样:
Thought: 我先看一下目录 Action: list_files Thought: 我看到有 src 目录,先看 src Action: list_files(src) Thought: 我看到有 components,先看 components Action: list_files(src/components) Thought: 我看到 Button.tsx,先看按钮组件 Action: read_file(Button.tsx)
看到这里你可能会有点崩溃。
因为它一直在“探索”,但没有形成一个清晰的任务结构。
这就是 ReAct 的常见问题:它很擅长局部决策,但不一定擅长全局组织。
具体来讲,会有下面几个问题。
问题 1:容易陷入工具调用循环
ReAct 每一步都要根据 Observation 决定下一步。
如果模型判断能力不够稳定,就可能一直查文件、一直搜索、一直验证,但迟迟不进入真正执行阶段。
你会看到它不停地说:
我还需要更多上下文 我再看一个文件 我再确认一下 我再搜索一下
这些动作单独看都合理,但合在一起就会变成一种“无限准备”。
问题 2:容易丢失大目标
ReAct 的注意力通常聚焦在当前这一步。
当前文件有什么?
当前报错是什么?
当前工具返回了什么?
这会导致它在复杂任务里容易被局部信息带偏。
比如原本任务是“实现登录功能”,结果它看到了一个旧的 auth 工具函数,就开始围绕这个函数展开,最后忘了还要:
- 添加页面
- 接 API
- 处理状态
- 做错误提示
- 补测试
也就是说,它可能每一步都不算错,但整体结果是散的。
问题 3:用户很难知道它准备怎么干
ReAct 的路径是在执行过程中长出来的。
这对探索型任务是好事,但对工程任务未必。
因为很多时候,用户不是只关心最终结果,也关心:
- 你准备改哪些模块?
- 你会不会影响现有功能?
- 你打算怎么验证?
- 这个任务会拆成几步?
如果 Agent 一直边走边想,用户很难在早期判断它的方向是否正确。
这时候,就需要另一种模式:Plan-Execute-Replan。
3. Plan-Execute-Replan 是什么?
Plan-Execute-Replan 从名字上就能看出来,它分成三个阶段:
- Plan:先制定计划
- Execute:按照计划执行
- Replan:根据执行结果调整计划
它的核心不是“让模型想一想”,而是把任务控制流拆开。
一个典型流程大概是:
用户任务:给项目增加登录功能 Plan: 1. 查看项目路由和页面结构 2. 找到现有请求封装和用户状态管理方式 3. 新增登录页面 4. 接入登录 API 5. 处理登录成功后的跳转 6. 添加错误提示和 loading 状态 7. 补充测试并运行验证 Execute step 1: 查看项目路由和页面结构 Result: 发现项目使用 React Router,页面在 src/pages Replan: 计划基本不变,但第 3 步需要新增 src/pages/Login.tsx,并在 routes.tsx 注册路由
你会发现,Plan-Execute-Replan 和 ReAct 最大的差别是:
它不是每一步都从零决定下一步,而是先有一个全局路线图。
执行过程中,如果遇到新信息,再修正这个路线图。
这很像真实工程里的工作方式。
比如你接到一个需求,不会马上打开文件乱改,而是会先想一下:
- 这个需求涉及哪些模块?
- 哪些地方可能有风险?
- 应该先看哪些文件?
- 做完以后怎么验证?
然后你开始执行。
执行过程中发现原本判断错了,比如项目没有现成的登录 API,或者路由不是你想的那样,这时候就重新调整计划。
所以 Plan-Execute-Replan 的关键点,不是 Plan,也不是 Execute,而是 Replan。
因为真实任务里,计划很少一次就完全正确。
如果只有 Plan-Execute,没有 Replan,那它就会变成一种很死板的流程:
计划怎么写,就必须怎么做
但工程任务经常会出现新信息:
- 文件结构和预期不一样
- API 不存在
- 测试失败原因不是一开始想的那个
- 依赖版本不支持某个写法
- 用户补充了新的约束
这时候 Agent 必须能够调整计划。
这就是 Replan 的价值。
4. 两者最核心的区别
如果用一句话来区分:
ReAct 是“边想边做”,Plan-Execute-Replan 是“先规划,再执行,执行中再修正规划”。
但面试的时候,只说这一句还不够。你还需要讲清楚它们在控制流上的差异。
我们可以从四个角度来看。
4.1 决策粒度不同
ReAct 的决策粒度更细。
它每一次工具调用之后,都会重新判断下一步。
Observation -> Thought -> Action Observation -> Thought -> Action Observation -> Thought -> Action
所以它非常适合“不知道下一步是什么”的任务。
Plan-Execute-Replan 的决策粒度更粗。
它先把任务拆成多个步骤,然后按步骤推进。
Plan -> Execute step 1 -> Execute step 2 -> Replan -> Execute step 3
所以它更适合“目标明确,但步骤较多”的任务。
4.2 是否有全局任务结构
ReAct 通常没有强约束的全局计划。
它当然也可以在 Thought 里写“我接下来要做什么”,但这个计划往往是临时的,不一定会被系统显式维护。
Plan-Execute-Replan 则会把计划当成一个明确的数据结构。
例如:
const plan = [
{ id: 1, task: "分析路由结构", status: "done" },
{ id: 2, task: "分析请求封装", status: "doing" },
{ id: 3, task: "新增登录页面", status: "pending" },
{ id: 4, task: "补充测试", status: "pending" },
];
这个计划不是随便写在 prompt 里的几句话,而是 Agent 控制循环的一部分。
它可以被更新、被标记状态、被展示给用户,也可以作为后续执行的依据。
这也是为什么 Plan-Execute-Replan 更适合复杂工程任务。
因为复杂工程任务需要一个稳定的任务骨架。
4-3. 对工具结果的使用方式不同
ReAct 里,工具返回结果通常直接影响下一步动作。
比如:
看到 A -> 去查 B 看到 B -> 去改 C 看到 C 报错 -> 去查 D
工具结果像方向盘,决定 Agent 立刻往哪儿走。
而 Plan-Execute-Replan 里,工具结果不仅影响下一步,还会影响整个计划。
比如原计划是:
1. 修改登录页面 2. 接入登录接口 3. 添加用户状态
结果执行时发现项目已经有登录页面,只是缺少鉴权守卫。
那计划就应该变成:
1. 复用现有登录页面 2. 补充鉴权守卫 3. 修正跳转逻辑 4. 补充测试
也就是说,ReAct 更像是在更新“下一步动作”,Plan-Execute-Replan 更像是在更新“任务地图”。
4.4 可控性不同
ReAct 的优势是灵活,缺点是可控性弱一点。
因为它的路径是在执行中不断生成的。
Plan-Execute-Replan 的优势是可控性更强。
用户或系统可以看到当前计划,也可以干预计划:
- 这一步不要做
- 先做第三步
- 这个文件不要改
- 验证方式换一下
对于真实产品里的 Agent 来说,这一点非常重要。
因为 Agent 不是 demo。它真的会改文件、跑命令、调接口、影响业务数据。
越是高风险任务,越需要计划层。
5. 用一个例子对比一下
假设用户说:
帮我修复订单列表页面加载很慢的问题。
如果是 ReAct,流程可能是:
Thought: 我先看订单列表页面代码
Action: read_file(OrderList.tsx)
Observation: 页面里有 useEffect 请求订单数据
Thought: 我需要看请求方法
Action: read_file(orderApi.ts)
Observation: 接口返回了完整订单详情
Thought: 我需要看渲染逻辑
Action: search("OrderItem")
Observation: 找到了 OrderItem.tsx
Thought: 可能是列表渲染太重,我看一下组件
Action: read_file(OrderItem.tsx)
Observation: 每个 item 都计算了很多派生字段
这个过程很自然,也很适合排查问题。
因为你一开始并不知道慢在哪里,只能一步一步查。
但如果是 Plan-Execute-Replan,它会先形成一个排查计划:
Plan: 1. 确认慢发生在请求阶段还是渲染阶段 2. 检查订单列表接口是否返回过多字段 3. 检查页面是否存在重复请求 4. 检查列表组件是否存在昂贵计算 5. 根据定位结果做最小修改 6. 运行测试或构建验证
然后开始执行。
执行第 1 步后发现:
接口请求 300ms,页面渲染 2500ms
这时候 Replan:
更新计划: 1. 跳过接口字段优化 2. 重点检查列表渲染和派生计算 3. 考虑 memo、虚拟列表或计算缓存
这就是两者的区别。
ReAct 更像一个经验丰富的排查者,根据线索不断推进。
Plan-Execute-Replan 更像一个项目负责人,先拆任务,再根据事实调整任务。
6. 到底什么时候用 ReAct?
ReAct 适合探索型任务。
所谓探索型任务,就是你一开始不知道路径,只能根据外部信息一步一步推进。
典型场景包括:
- 搜索资料
- 浏览网页
- 排查未知 bug
- 阅读陌生代码
- 分析日志
- 根据命令输出决定下一步
这些任务的特点是:
信息在工具里,不在模型脑子里。
模型必须先调用工具拿到 Observation,然后才能继续判断。
例如你让 Agent:
这个项目为什么测试过不了?
它不可能凭空知道答案。它必须:
- 运行测试
- 看报错
- 找文件
- 分析代码
- 修改
- 再验证
这类任务用 ReAct 很自然。
因为每一步都高度依赖上一轮结果。
7. 到底什么时候用 Plan-Execute-Replan?
Plan-Execute-Replan 适合复杂工程任务。
所谓复杂工程任务,就是目标相对明确,但中间涉及多个步骤、多个模块、多个约束。
典型场景包括:
- 实现一个新功能
- 重构一组模块
- 迁移技术方案
- 修复跨模块问题
- 生成一份完整报告
- 搭建一个小型应用
这些任务的特点是:
不是不知道怎么开始,而是需要把事情组织好。
比如用户说:
把项目里的 fetch 请求统一迁移到 requestClient。
这时候如果完全用 ReAct,Agent 可能会一边搜索一边改,最后容易漏文件,也容易不知道当前进度。
但如果用 Plan-Execute-Replan,就可以先拆:
1. 搜索所有 fetch 使用点 2. 按模块分类 3. 确认 requestClient 的调用方式 4. 逐个模块迁移 5. 处理类型和错误逻辑 6. 运行测试 7. 根据失败结果修正遗漏点
这个计划会让整个任务更稳。
尤其是当任务要持续很久的时候,计划本身就是一种状态管理。
8. 它们不是互斥关系
这里要特别注意一点:
ReAct 和 Plan-Execute-Replan 不是二选一。
很多真实 Agent 系统里,它们会组合使用。
比如外层是 Plan-Execute-Replan:
Plan: 1. 分析项目结构 2. 实现功能 3. 补充测试 4. 验证结果
但每一个 Execute step 内部,又可以使用 ReAct。
例如执行“分析项目结构”这一步时,Agent 仍然需要:
Thought: 我先查看目录 Action: list_files Observation: 返回目录 Thought: 我看到有 routes.tsx,需要查看路由 Action: read_file(routes.tsx) Observation: 返回路由配置
也就是说:
- Plan-Execute-Replan 负责全局任务管理;
- ReAct 负责单个步骤里的动态探索。
这其实是非常常见的组合方式。
因为复杂任务既需要全局计划,也需要局部灵活性。
如果只有计划,没有 ReAct,执行会很死。
如果只有 ReAct,没有计划,复杂任务会散。
更合理的方式是:
外层用计划控制方向,内层用 ReAct 处理不确定性。
9. 面试时怎么回答?
如果面试官问:
Plan-Execute-Replan 和 ReAct 有啥区别?
你可以这样回答:
ReAct 是一种推理和行动交替进行的 Agent 模式。模型每次根据当前观察结果进行思考,然后选择一个工具或动作,再根据工具返回结果继续下一步。它适合信息不完整、路径不确定的探索型任务,比如查资料、排查 bug、分析日志。
Plan-Execute-Replan 则是先把目标拆成一个整体计划,再按计划执行。执行过程中如果发现新信息或原计划不合理,就重新规划。它适合目标明确但步骤复杂的工程任务,比如实现功能、重构模块、迁移代码。
两者的核心区别在于控制流:
- ReAct 的控制流是局部的,强调每一步根据 Observation 动态决策
- Plan-Execute-Replan 的控制流是全局的,强调先有任务计划,再在执行中修正计划
实际系统里两者经常组合使用:外层用 Plan-Execute-Replan 管理复杂任务,内层用 ReAct 完成每个步骤里的探索和工具调用。
10. 总结
最后总结一下。
ReAct 解决的是:
Agent 如何根据环境反馈,一步一步做出行动。
Plan-Execute-Replan 解决的是:
Agent 如何管理一个复杂任务,并在执行中动态调整任务结构。
所以它们不是同一个层面的东西。
ReAct 更偏“动作循环”。
Plan-Execute-Replan 更偏“任务管理”。
如果用一句更直白的话来说:
ReAct 让 Agent 不至于闭着眼睛回答,Plan-Execute-Replan 让 Agent 不至于走到哪算哪。
真正好用的 Agent,往往不是只会 ReAct,也不是只会 Plan,而是能够在全局计划和局部探索之间切换。
这也是为什么 Agent 工程化越往后走,大家越会发现:模型能力只是基础,真正决定 Agent 稳不稳的,是控制流设计。
以上关于Plan-Execute-Replan 和 ReAct 的区别是什么?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » Plan-Execute-Replan 和 ReAct 的区别是什么?
微信
支付宝