最近在做一个企业办公 Agent 项目,过程中花了不少时间研究 Agent 的推理架构该怎么选。市面上最主流的两种模式------ReAct 和 Plan-and-Execute------看起来都能用,但深入了解后我发现它们的设计哲学完全不同,适用场景也差异很大。
一、先说一个最基本的问题:Agent 为什么需要"推理"?
LLM 本身就能回答问题,为什么还要给它加推理框架?
因为 LLM 只会"说",不会"做"。当用户说"帮我创建一个明天截止的任务",LLM 可以生成一段漂亮的文字描述应该怎么做,但它没有手去操作数据库。Tool(或者叫 Skill)就是给 LLM 装上了手脚------它可以调用接口、查询数据、执行操作。
但问题来了:LLM 什么时候该用哪只手?先用左手还是右手?用完之后下一步该干嘛?
这就是推理框架要解决的问题。它本质上是一套"决策流程",告诉 LLM 如何思考、何时行动、怎么判断任务完成了没有。
ReAct 和 Plan-and-Execute 就是两套不同的决策流程。
二、ReAct:边想边做的演员
ReAct 的全称是 Reasoning + Acting,来自 2022 年 Google 和普林斯顿大学联合发表的论文(Yao et al., 2022)。
它的核心思想用一句话概括:让 LLM 交替进行"思考"和"行动",每做一步就停下来想想,然后决定下一步。
工作流程
ReAct 的运行方式像一个循环:
思考 → 行动 → 观察 → 思考 → 行动 → 观察 → ... → 完成
拿一个具体的场景来说,用户问:"张三这周有多少个未完成的任务?"
- 思考:用户要查张三的任务,我需要先知道张三的用户 ID。
- 行动:调用用户查询工具,搜索"张三"。
- 观察:返回了 user_id = 12345。
- 思考:好,现在我有了 ID,需要查他本周的未完成任务。
- 行动:调用任务查询工具,参数是 user_id=12345, status=未完成, 时间=本周。
- 观察:返回了 8 个任务。
- 思考:信息够了,可以回答了。
- 输出:"张三这周有 8 个未完成的任务。"
整个过程就像一个人在自言自语------"我现在知道了什么?还缺什么?下一步该做什么?"------每一步都是临时决定的。
为什么 ReAct 能流行起来
ReAct 的优雅之处在于简单。它不需要任何复杂的架构设计,只需要在 Prompt 里告诉 LLM 三件事:
- 你可以思考(Thought)
- 你可以使用这些工具(Action)
- 工具会给你返回结果(Observation)
LLM 天然就会按照这个模式运行。这也是为什么几乎所有 Agent 框架的入门示例都是 ReAct------它的概念直觉、实现简单、容易理解。
而且 ReAct 的适应性很强。如果某一步工具调用失败了,LLM 可以立即反应:"这个工具报错了,让我换一种方式试试。"这种灵活性是其他架构不容易做到的。
ReAct 的致命缺陷
但当我真正在项目中使用 ReAct 时,问题开始暴露。
第一个问题:它没有全局视野。
ReAct 是"走一步看一步"的。它优化的是"下一步做什么最好",而不是"整个任务怎么做最优"。这就像一个人在迷宫里,每到一个路口只看眼前的三条路选一条,从不翻看地图。
当任务简单时(比如"查一下张三的任务"),这没有问题------两三步就完事了,不需要地图。但当任务复杂时(比如"生成本周的团队工作总结"),ReAct 可能走出一条非常曲折的路径:先查了任务列表,然后突然想起还要查项目进度,查完项目进度又忘了还要统计延期情况,最后生成的总结遗漏了关键信息。
第二个问题:上下文污染。
ReAct 的每一步"思考"都需要把之前所有的历史(包括思考过程、工具调用、返回结果)全部发送给 LLM。执行 5 步之后,上下文里充斥着各种中间数据、报错信息、调试噪声。LLM 的注意力被这些无关信息稀释,推理质量明显下降。
这在业界有个形象的说法叫"上下文越长,模型越笨"。我在实际测试中观察到,同一个 LLM 在 3 步以内的任务上表现优秀,但超过 6 步后,它开始"忘记"最初的目标,或者在几个相似的状态之间反复跳转。
第三个问题:成本失控。
每一步"思考"都是一次完整的 LLM 调用,而且每次调用都要携带越来越长的历史上下文。一个 10 步的任务,到第 10 步时,prompt_tokens 可能已经是第 1 步的 5 倍以上。更要命的是,这些 token 大部分花在了"让 LLM 重新理解之前发生了什么"上------这是纯粹的浪费。
第四个问题:链式崩塌。
这是知乎上有人提到的一个很直观的数学问题。假设每一步的成功率是 95%(已经很高了),连续 10 步全部成功的概率是 0.95 的 10 次方,等于 59%。也就是说,即便每一步都很靠谱,走完一个 10 步任务的成功率还不到六成。一旦中间某一步产生了微小的幻觉(LLM 编造了一个不存在的参数),后面所有步骤都会基于这个错误继续执行------雪球越滚越大。
三、Plan-and-Execute:先计划再行动的指挥官
Plan-and-Execute 的思路完全不同:先想好要做什么,再一步一步去做。
它的思想受到了 Wang et al., 2023 的论文"Plan-and-Solve Prompting"的启发------该论文证明了让 LLM "先规划再解决"能显著提升推理准确率。但 Plan-and-Solve 本身只是一种提示词技术(单次 LLM 调用,无工具),而 LangChain 团队将"先规划再执行"这个理念重新设计为完整的 Agent 架构------独立的 Planner、Executor、Replanner 节点,支持多模型协作和工具调用------并内置到了 LangGraph 框架中。
工作流程
Plan-and-Execute 把一次任务拆成三个角色:
Planner(规划者)→ Executor(执行者)→ Replanner(重规划者)
还是那个场景:"生成本周的团队工作总结"。
Planner 先思考全局,生成一个计划:
步骤 1:查询团队所有成员的本周任务列表
步骤 2:统计每个成员的完成率
步骤 3:查询延期未完成的任务
步骤 4:汇总以上数据,生成工作总结
Executor 拿到计划后,逐步执行:
- 执行步骤 1:调用任务查询工具 → 拿到任务列表
- 执行步骤 2:调用统计工具 → 拿到完成率
- 执行步骤 3:调用延期查询工具 → 拿到延期列表
Replanner 在执行过程中或执行完毕后检查:
- 原始计划的步骤都完成了吗?
- 执行结果和预期一致吗?需要调整计划吗?
- 如果某一步失败了,怎么修正后续步骤?
这三个角色背后的设计哲学
Planner 是"大脑"。它只负责战略决策------把一个复杂的需求拆解成可执行的步骤序列。它不关心每一步具体怎么实现,只关心"应该做哪些事、按什么顺序做"。
Executor 是"手脚"。它拿到一个具体的步骤描述(比如"查询本周延期任务"),然后选择合适的工具去执行。它不需要知道全局,只需要把当前这一步做好。
Replanner 是"复盘者"。它站在全局视角,回顾已经完成的步骤和结果,判断是否需要调整后续计划。如果步骤 2 的结果显示某个成员一个任务都没有(可能是数据异常),Replanner 可以插入一个"确认该成员是否在职"的步骤。
这种分离带来的好处是深刻的。
为什么 Plan-and-Execute 在复杂任务上更强
第一,它有全局视野。
Planner 在开始执行之前就已经想好了整个路径。这意味着它不会像 ReAct 那样走到第 5 步突然发现"哦,我忘了还要查延期情况"。所有需要做的事情在一开始就被识别出来了。
用之前那个迷宫的比喻:Plan-and-Execute 是先看地图规划好路线,再沿着路线走。即使走的过程中发现某条路不通(工具调用失败),Replanner 也会重新规划路线而不是瞎撞。
第二,上下文更干净。
这是我认为最被低估的优势。
在 ReAct 中,执行到第 8 步时,LLM 需要处理一个巨大的上下文------包含前 7 步的所有思考过程和工具返回值。但在 Plan-and-Execute 中,Executor 在执行第 3 步时,它的上下文只包含"当前步骤的描述"和"必要的上下文信息",不需要看到步骤 1 和步骤 2 的完整执行细节。
信息是隔离的。每个步骤的执行环境是相对干净的。这大幅减少了"上下文污染"问题。
第三,成本更可控。
Planner 只调用一次(或者加上 Replanner 的几次),它消耗的 token 是固定的。Executor 的每次调用只需要处理当前步骤的少量上下文。相比 ReAct 那种"每一步都要重新发送完整历史"的模式,Plan-and-Execute 的总 token 消耗通常低 40-60%。
而且,由于 Executor 的任务更简单(只需要根据步骤描述调用正确的工具),理论上可以用更小、更便宜的模型来执行,进一步降低成本。虽然在实际项目中出于简化考虑,我选择了全部使用同一个模型,但这个优化空间始终保留着。
第四,可追溯、可审计。
Plan-and-Execute 天然产出一份"计划书"。这在企业场景中非常有价值------用户甚至可以在 Agent 开始执行之前审核计划:"你打算这么做?好,我同意"或者"不对,你不需要查项目进度,直接查任务就行"。
ReAct 没有这个能力。它的推理过程是隐式的、即兴的,你只能事后从日志里拼凑出它的决策路径。
第五,链式崩塌被缓解。
Replanner 的存在让系统具备了"自我纠错"的能力。即使步骤 3 执行失败或者返回了异常结果,Replanner 可以选择跳过、重试或者修改后续计划。这打断了错误累积的链条------不再是"一步错、步步错",而是"一步错、纠正、继续"。
UC 伯克利的研究显示,通过 Plan-and-Act 框架(Plan-and-Execute 的增强版),在长任务上的规划能力提升了 54%。
四、Plan-and-Execute 不是银弹
公平起见,我也要说说它的不足。
对简单任务过度设计。
如果用户只是说"帮我建个任务",Plan-and-Execute 会先规划("步骤 1:创建任务"),再执行,再检查------对于一个一步就能完成的操作,这多出了两次 LLM 调用(规划 + 检查),纯粹浪费。
我的解决方式是在 Planner 中加入判断:如果任务足够简单,直接生成一个单步计划甚至跳过规划阶段。
规划质量依赖模型能力。
Planner 需要很强的任务分解能力。如果模型的推理能力不够,生成的计划可能本身就有问题------步骤遗漏、顺序错误、粒度不当。而且这种错误比 ReAct 的错误更隐蔽:ReAct 的错误通常在执行中就会暴露,但一个"看起来合理但实际上有缺陷"的计划可能执行到最后才发现方向错了。
这也是为什么 Planner 必须用最强的模型。规划是整个系统的基石,如果基石有裂缝,上面的一切都不稳固。
适应性不如 ReAct。
ReAct 的"边想边做"让它对意外情况的反应非常快------这一步失败了,下一步立刻换策略。Plan-and-Execute 则需要等到 Replanner 介入才能调整,响应不够即时。对于那些环境高度不确定、每一步的结果都可能彻底改变后续方向的任务,ReAct 可能更合适。
五、真正的智慧:不是选择一个,而是理解何时用哪个
在我的实际项目中,我的结论是:Plan-and-Execute 作为主架构,在 Executor 内部保留 ReAct 的能力。
具体来说:
- 全局层面,用 Plan-and-Execute 管理任务的整体流程
- 每个步骤的执行中,Executor 本身可以是一个轻量的 ReAct Agent------它在执行当前步骤时,可以思考、调用工具、观察结果,如果需要的话甚至可以多步完成一个子任务
这不是我独创的思路。LangGraph 官方的 Plan-and-Execute 示例就是这么做的------Planner 用一个强模型规划全局,Executor 本身就是一个 ReAct Agent 执行每个步骤。
这种混合架构结合了两者的优势:有全局规划的稳定性,也有局部执行的灵活性。