ReWOO 与计划执行:解耦规划


文档摘要

ReWOO 与计划执行:解耦规划 本节摘要:ReAct 把思考和行动交错在一条流里。ReWOO(Reasoning Without Observation)把它们拆开:先一次性规划,再执行。结果是 HotpotQA 上 token 用量降至 1/5、准确率反而提升 4 个百分点,还能把规划器蒸馏进一个 7B 小模型。Plan-and-Execute 把这个思路泛化成模式名,Plan-and-Act 又把它扩展到网页与移动端的长程任务。本节是「规划-执行解耦」这条线的核心:讲透为什么「规划阶段不看观察」能同时省 token、提升鲁棒性、并打开小模型蒸馏的大门,再用标准库手写一个带依赖解析的 ReWOO 计划 DAG。

ReWOO 与计划执行:解耦规划

本节摘要:ReAct 把思考和行动交错在一条流里。ReWOO(Reasoning Without Observation)把它们拆开:先一次性规划,再执行。结果是 HotpotQA 上 token 用量降至 1/5、准确率反而提升 4 个百分点,还能把规划器蒸馏进一个 7B 小模型。Plan-and-Execute 把这个思路泛化成模式名,Plan-and-Act 又把它扩展到网页与移动端的长程任务。本节是「规划-执行解耦」这条线的核心:讲透为什么「规划阶段不看观察」能同时省 token、提升鲁棒性、并打开小模型蒸馏的大门,再用标准库手写一个带依赖解析的 ReWOO 计划 DAG。读完本节,你能为一个结构化任务在 ReAct 与 ReWOO 之间做出有依据的选择。

对应原课程:Phase 14 · Lesson 02 · rewoo-plan-and-execute(原英文 phases/14-agent-engineering/02-rewoo-plan-and-execute/docs/en.md)。

学习目标

阅读完本节,你应当能够:

  1. 解释为什么 ReWOO 的「规划器 / 执行器 / 求解器」三分能在 token 效率和鲁棒性上同时胜过 ReAct 的交错循环。
  2. 用标准库实现一个计划 DAG、一个按依赖顺序执行的执行器、一个把各执行结果拼合起来的求解器。
  3. 借助 2026 年 Anthropic「五种工作流模式」的框架,判断一个任务该跑「先规划后执行」还是交错 ReAct。
  4. 识别长程网页或移动任务何时需要 Plan-and-Act 的合成计划数据。

一、问题与直觉

ReAct 的「思考-行动-观察」交错循环简单、灵活,但每次工具调用都得携带全部前序上下文——包括之前每一步的思考。token 用量随深度二次增长。更糟的是:循环中途某个工具一旦失败,模型得从那条错误观察出发,把整个计划重新推导一遍。

ReWOO(Xu 等人,arXiv:2305.18323,2023 年 5 月)注意到了这一点,下了一个赌注:先把整个事情规划好,并行取证据,最后再拼答案。一次 LLM 调用做规划,N 次工具调用取证据(可并行),再一次 LLM 调用求解。代价是灵活性降低(计划是静态的),换回的是显著更好的 token 效率和更清晰的失败模式。

💡 一句话区分:ReAct 是「边走边想」,ReWOO 是「先想清楚再走」。前者灵活但贵,后者便宜但僵硬。生产系统往往混用——结构化部分用 ReWOO,异常分支用 ReAct。

三个角色

规划器 Planner: 用户问题 -> [计划 DAG] 执行器 Worker: [计划 DAG] -> [证据] (工具调用,可并行) 求解器 Solver: 用户问题 + 计划 DAG + 证据 -> 最终答案

规划器产出一个 DAG。每个节点写明:用哪个工具、参数是什么、依赖哪些更早的节点(用 #E1#E2 这样的引用)。执行器按拓扑序跑节点。求解器把一切缝合成最终答案。

为什么 token 少 5 倍

ReAct 的提示长度随步数线性增长。到第 10 步,提示里塞着思考 1 + 行动 1 + 观察 1 + 思考 2 + 行动 2 + 观察 2 + ……,而且每个中间步骤都冗余地重复了原始提示。

ReWOO 只付一次规划器提示(较大)、N 次小执行器提示(每次只有工具调用本身,没有思考链)、一次求解器提示。论文在 HotpotQA 上测得 token 用量约为 ReAct 的 1/5,同时绝对准确率还 4 个百分点。

为什么更鲁棒

在 ReAct 里,执行器 3 失败时,循环得在半途中从错误里把推理接上。在 ReWOO 里,执行器 3 返回一条错误字符串;求解器在原始计划的上下文里看到它,可以优雅降级。失败定位是按节点,不是按步骤。

规划器蒸馏

论文的第二个结果:因为规划器看不到观察,你可以在一个大教师模型(比如 175B)产出的规划轨迹上,微调一个 7B 小模型。小模型负责规划,推理时不再需要大模型。这在 2026 年已是标配——许多生产 Agent 用「小规划器 + 大执行器」,或反过来。

Plan-and-Execute(2023 年)

LangChain 团队 2023 年 8 月的博文把 ReWOO 泛化成一个模式名:Plan-and-Execute。前置规划器吐出一个步骤列表,执行器跑每一步,可选的重规划器在观察到结果后修订计划。这比 ReWOO 更接近 ReAct(重规划器把观察重新引入了规划),但保留了 token 节省。

Plan-and-Act(Erdogan 等人,arXiv:2503.09572,ICML 2025)

Plan-and-Act 把这个模式扩展到长程网页与移动 Agent。关键贡献是合成计划数据:一个带标注的轨迹生成器产出训练数据,其中计划是显式的。用它微调规划器模型,使它们在 WebArena 类任务上跑到 30~50 步之后仍能保持连贯——而单条 ReAct 轨迹在那里早就失去了连贯性。

怎么选

模式 适用场景
ReAct 短任务、环境未知、需要反应式异常处理
ReWOO 结构化任务、工具已知、对 token 敏感、证据可并行
Plan-and-Execute 像 ReWOO,但部分执行后需要重规划
Plan-and-Act 长程(>30 步)、网页/移动/电脑使用
思维树 Tree of Thoughts 值得为搜索付代价时(第 04 节)

Anthropic 2024 年 12 月的指引是:从最简单的开始。如果任务只是一次工具调用加一段总结,别搭 ReWOO;如果任务是 40 步的研究作业,别只跑 ReAct。

⚠️ 反模式警示:不要为了「看起来高级」就上 ReWOO。静态计划的代价是不能应对中途冒出来的新信息。如果你的任务前 3 步的结果会改变后 3 步该做什么,那就该用 Plan-and-Execute(带重规划)或 ReAct,而不是纯 ReWOO。

二、从零实现

原课程 code/main.py 实现了一个玩具 ReWOO,核心组件如下,用伪代码展示骨架。

Step 1:规划器

把用户问题编成一个计划 DAG,节点之间用 #E1#E2 这样的引用表达依赖:

def planner(question): # 真实用 LLM 生成;这里给出 demo 问题的手写计划 # 问题:"法国首都的人口是多少(四舍五入到百万)?" return [ {"id": "E1", "tool": "search", "args": "法国的首都"}, {"id": "E2", "tool": "search", "args": "#E1 的人口", "deps": ["E1"]}, # E2 依赖 E1 的输出 ]

Step 2:执行器(按拓扑序)

按依赖顺序跑节点,把 #E1 替换成真实的前序输出:

def worker(plan, registry): evidence = {} # id -> 工具结果字符串 for node in topo_order(plan): # 拓扑序保证依赖先生成 args = substitute(node["args"], evidence) # #E1 -> 真实结果 evidence[node["id"]] = registry.call(node["tool"], args) return evidence

Step 3:求解器

读问题、计划、证据,产出最终答案:

def solver(question, plan, evidence): # 真实用 LLM 综合;demo 里是把 E2 的数字四舍五入 raw = evidence["E2"] return round_to_millions(raw)

Step 4:串起来

def rewoo(question, registry): plan = planner(question) evidence = worker(plan, registry) # 独立节点本可并行 return solver(question, plan, evidence)

运行 python3 code/main.py 会先打印完整计划,再打印执行器结果,最后打印求解器拼合。把它和一次 ReAct 风格的交错运行的字符数(token 近似)对比——在这类结构化任务上,ReWOO 明显胜出。

💡 设计要点:#E1 这种引用是 ReWOO 的精髓。它让规划器能在不知道真实观察的前提下写出依赖,执行器只需做字符串替换。这就是「不看观察的推理」的工程落点。

三、框架对比

LangGraph 把 Plan-and-Execute 作为一种配方提供(create_react_agent 走 ReAct,自定义图走 plan-execute)。CrewAI 的 Flows 直接编码了这个模式:你预先定义任务,Flow DAG 负责执行。Plan-and-Act 的合成数据思路目前主要还在研究界;但它的运行时模式(显式计划 DAG)通过 LangGraph 和 CrewAI Flows 已经进了生产。

框架 对 ReWOO/Plan-and-Execute 的支持
LangGraph 原生支持:ReAct 用 create_react_agent,plan-execute 用自定义图;每步可加检查点
CrewAI Flows 把模式直接编码:任务预先定义,Flow DAG 执行,天然支持并行
OpenAI Agents SDK 没有内置 plan-execute 原语,但可用 Handoffs 把「规划 Agent」与「执行 Agent」分开
LangChain(老版) 2023 年的原版 Plan-and-Execute 博文出处,概念命名地

对大多数 2026 年生产 Agent,选 LangGraph 或 CrewAI Flows,差别主要在编程模型(图 vs 角色流)和可观测性栈。

四、可复用产物

本节产出一份可复用技能(原课程 outputs/skill-rewoo-planner.md):

  • skill-rewoo-planner.md:给定工具目录和用户请求,生成一个 ReWOO 计划 DAG。它在移交给执行器之前会校验计划:无环、每个引用都能解析、每个工具都存在。这份技能可以作为任何 Agent 的「规划前置步骤」加载。

Python 代码(code/main.py)是独立可运行的玩具,核心三件套(规划器、执行器、求解器)与依赖替换逻辑都是厂商无关的;把脚本式规划器换成真实 LLM 调用即可投入生产。

五、练习

  1. (Easy) 为相互独立的计划节点并行化执行器。在一个有 2 个并行组的 6 节点 DAG 上,你能换来什么?
  2. (Medium) 加一个重规划节点:只要任一执行器返回错误就触发。把 ReWOO 改成 Plan-and-Execute 的最小改动是什么?
  3. (Medium) 把规划器换成小模型(7B 级),求解器留在前沿大模型上。对比端到端质量——这个切分在哪里失败?
  4. (Hard) 读 ReWOO 论文第 4 节关于规划器蒸馏的内容。从概念上复现 175B → 7B 的结果:你需要什么训练数据?怎么给计划质量打分?
  5. (Hard) 把玩具移植成 Plan-and-Act 的轨迹形态:计划是一个序列,而不是 DAG。哪些权衡发生了变化?

本节要点回顾

  1. ReAct 的代价是 token 二次增长:每次工具调用都得携带全部前序思考,深度越深越贵。
  2. ReWOO = 规划器 + 执行器 + 求解器:规划阶段不看观察,执行可并行,最后一次性求解。
  3. 5 倍 token 节省是真的:HotpotQA 上 token 用量约为 ReAct 的 1/5,绝对准确率还高 4 个百分点。
  4. 更鲁棒是因为失败按节点定位:执行器失败返回错误字符串,求解器在原始计划上下文里看到它,可优雅降级。
  5. 规划器可蒸馏进 7B 小模型:因为规划器不看观察,大教师模型产出的规划轨迹可用来微调小模型,推理时不再需要大模型。
  6. Plan-and-Execute 是带重规划的 ReWOO:执行后可选地修订计划,介于 ReWOO 与 ReAct 之间。
  7. Plan-and-Act 用合成计划数据扩展到长程网页/移动任务,保持 30~50 步后的连贯性。
  8. 选型心法:从最简单的开始——短任务用 ReAct,结构化任务用 ReWOO,需要重规划用 Plan-and-Execute,长程用 Plan-and-Act。
  9. 引用(如 #E1)是 ReWOO 的工程精髓:让规划器在不知观察的前提下写依赖,执行器只做字符串替换。
  10. 反模式:不要为「看起来高级」而上 ReWOO;如果前几步结果会改变后几步该做什么,就用带重规划的版本。

下一节,我们将进入「Reflexion:言语强化学习」——把失败变成一段自然语言反思,存进记忆,让下一轮尝试看到它,用零梯度实现传统 RL 要上千次试验才能做到的自我修正。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U