博客.
博客.
(联系方式)

保持联系

如果你想联系我,无论是讨论合作机会、分享想法,还是只是打个招呼,都可以通过以下方式找到我。

(最后更新)

版权所有 / 2026

(快捷键)C
返回学习路线
(02 · Agent 开发)2026年8月

规划与推理策略

ReAct 边想边做,Plan-and-Execute 先想后做,Tree of Thoughts 想多条路——三种规划范式怎么选?论文里的数字很漂亮(24 点 4%→74%,HumanEval 80%→91%),但规划本身烧 token、计划还赶不上变化。这一章把证据和反方都摆上桌。

规划与推理策略

开场:规划决定 Agent 的能力上限

上一章讲过,Agentic Loop 让模型「边开边看路况」。这对短任务没问题,但任务一复杂就会暴露一个硬伤:只看眼前一步的 Agent,走不出需要全局视野的迷宫。

类比一下:砌砖工人可以边干边看,但盖一栋楼不能没有图纸。没有图纸的施工队会盖到三楼才发现一楼承重墙位置错了——Agent 世界里对应的剧情是:写到第 15 步才发现第 3 步选的方案根本走不通,前面十几步的 token 全部白烧。

这就是规划(Planning)要解决的问题:在行动之前(或之中)显式地管理「接下来要做什么」这个状态。 它不改变模型的单步能力,但决定了这些能力能被组织成多长的链条。所以业内的共识是:模型的智力决定 Agent 能力的下限,规划策略决定能力的上限——同一个模型,配不同的规划策略,在复杂任务上的表现可以差出一个数量级(后面你会看到 4% 和 74% 这种夸张差距)。

但也要把丑话说在前面:规划不是免费的。 画图纸要花时间,图纸画错了要返工,环境变了图纸还会过期。这一章我们把主流的规划范式逐个拆开,既给论文里的硬证据,也给「过度规划」的反方观点——因为在工程实践里,选错规划策略的代价往往比不规划还大。


任务分解:规划的原材料

所有规划策略的底层动作都是同一个:把大任务拆成小任务。 为什么分解有效?三个原因,前两个上一章已经埋过伏笔:

  • 缩短错误累积链。 单步决策准确率会随步数幂次衰减(0.95^n),把 30 步的任务拆成 3 个 10 步的子任务,每条链的全程无错概率从 21% 升到 60% 左右——而且子任务之间还可以插入验证点。
  • 降低单步认知负荷。 让模型「一步只做一件事」,比「一口气想完所有事」的犯错率低得多。这也是 CoT(思维链)有效的根本原因。
  • 让错误可定位。 一条 30 步的单线轨迹失败了,你很难说是哪步错了;拆成子任务后,失败被隔离在某一段里,重跑这一段就行。

分解手法里最值得一提的是 Least-to-Most Prompting(Google 2022,arXiv:2205.10625):不让模型边答边拆(CoT 的做法),而是先显式列出全部子问题,再按顺序逐个求解,后面的子问题可以利用前面的答案。在 SCAN 组合泛化基准上(考验「学会 jump 和 turn left,能不能推出 jump turn left」这类组合能力),普通提示只有约 6% 准确率,CoT 约 16%,Least-to-Most 直接干到 99% 以上。这个数字揭示了一个后来被所有 Planner 继承的思想:「拆」这个动作本身值得单独花一次模型调用,拆得好比执行得好更重要。

工程上的分解通常分两层:Planner 负责拆出步骤清单(语义层),Executor 负责把每一步变成具体的工具调用(动作层)。这个分层就是 Plan-and-Execute 的雏形。


三种范式一张表:边想边做、先想后做、想多条路

在深入细节前,先把三种主流范式的关系说清楚,它们不是替代关系,而是在「思考的时机和宽度」上的三个不同取点

  • ReAct:边想边做。 每走一步看一次路况再决定下一步。思考的时机是「每步」,宽度是「一条路」。灵活、省 token,但没有全局观。
  • Plan-and-Execute:先想后做。 先把整条路线画出来,再照着走,走不通才停下来重画。思考的时机是「开局 + 必要时」,宽度仍是「一条路」。有全局观,但计划可能过期。
  • Tree of Thoughts:想多条路。 每一步同时想好几个候选方向,评估打分后选最好的展开,走死了还能回溯。宽度是「一棵树」。探索能力最强,token 成本也爆炸。

一个生活类比:ReAct 是凭路感开车,Plan-and-Execute 是先用导航规划全程再出发,ToT 是把所有候选路线都模拟跑一遍再选最优。市区通勤用导航纯属浪费电,但穿越无人区不规划就是玩命——范式之争的答案是任务结构,不是信仰。

三种规划范式对比:ReAct 边想边做每步想一次,Plan-and-Execute 开局先画完整计划再逐步执行、失败才重画,Tree of Thoughts 每步生成多个候选评估后逐层展开


Plan-and-Execute:先画图纸再施工

机制:三个角色

Plan-and-Execute 的思想可以追溯到 BabyAGI 和 Plan-and-Solve Prompting(ACL 2023,arXiv:2305.04091),后来 LangChain 的 Plan-and-Execute agent 把它工程化。架构上是三个角色:

  • Planner:通常用大模型,输入目标,输出一份完整的多步计划(一般是结构化的步骤列表)。Plan-and-Solve 论文的核心发现可以浓缩成一句提示词——「先理解问题、制定计划,再按计划逐步执行」,仅靠这个指令就让 Zero-shot 推理在 GSM8K 等算术基准上稳定超过 Zero-shot-CoT。显式的「先规划」本身就是免费的准确率。
  • Executor:逐步执行计划。每一步内部可以是一个小的 ReAct 循环(因为单步执行时仍然需要根据工具结果现场反应)。Executor 可以用更便宜的小模型——计划已经给了,执行是局部决策。
  • Replanner:每步执行完(或在检查点)对比「实际进展」和「原计划」,决定继续、调整还是推翻重来。

一个最小骨架(TypeScript):

type Step = { title: string; status: "todo" | "done" | "failed" };

// 1. Planner:一次性产出结构化计划
let plan: Step[] = await planner.makePlan(goal);

for (const step of plan) {
  try {
    await executor.run(step); // 2. Executor:步内是小 ReAct 循环
    step.status = "done";
  } catch (e) {
    step.status = "failed";
    // 3. Replanner:只在失败或检查点触发,不是每步都重排
    plan = await replanner.revise(goal, plan, String(e));
  }
}

看一个具体的计划长什么样。任务「给博客加暗色模式」,Planner 可能输出:

1. 读主题配置文件,确认当前颜色方案的组织方式
2. 新增 dark 配色变量,改造全局样式
3. 加一个切换按钮,状态存 localStorage
4. 跑构建和截图对比,验证两种模式都正常

注意好计划的两个特征:每一步都可执行、可验证(不是「优化一下样式」这种空话),且步骤之间传递了上下文假设(第 2 步依赖第 1 步的发现)。如果 Planner 输出的步骤含糊,别急着执行——让 Planner 重写计划,远比让 Executor 在执行中补救便宜。

Plan-and-Execute 架构:Planner 生成结构化计划,Executor 逐步执行,失败、偏差或检查点触发时 Replanner 修订计划

何时重规划:规划与执行的节奏控制

这是 Plan-and-Execute 最核心的工程参数,没有之一。两个极端都是错的:

  • 每步都重规划:等于退化成一个巨贵的 ReAct——每执行一步都要让大模型把全文重读一遍重出一份计划,token 成本翻好几倍,延迟翻倍,而且频繁重排会让 Agent 显得「朝令夕改」,上下游步骤的衔接反复被打断。
  • 从不重规划:计划腐化。环境是非平稳的,第 8 步执行时,当初制定计划依据的信息可能已经过时(文件被改了、接口返回变了、用户的需求澄清了)。抱着过期地图走到黑,比没有地图更危险。

合理的节奏是事件驱动 + 里程碑检查点的混合:

  1. 失败触发:单步连续失败 N 次(经验值 2-3 次),说明计划对现实的假设错了,必须重规划;
  2. 偏差触发:工具返回与计划预期明显不符(预期搜到接口 A,实际发现接口已下线),立即重规划;
  3. 检查点触发:每完成一个里程碑(比如计划的 1/3 处)例行对照一次,低成本纠偏;
  4. 预算兜底:限制最大重规划次数(经验值 3-5 次),超过就升级给人类——反复重规划本身就是「这条路走不通」的信号。

一句话总结:重规划的频率应该和环境的「意外率」正相关。 静态环境(写纯函数、做数学题)一次规划走到底;高动态环境(操作真实系统、和外部 API 交互)多设检查点。


Tree of Thoughts:把推理变成搜索

ToT(Princeton + Google DeepMind,2023,arXiv:2305.10601)是把「想多条路」形式化的代表作。它把推理过程建模成一棵搜索树,四个组件缺一不可:

  • 状态(State):当前的部分解,比如 24 点游戏里「已经算出的中间数字序列」;
  • Thought 生成器:每一步让模型产生 k 个候选下一步(论文里 k=5);
  • 状态评估器:让模型给每个状态打分——论文用了两种方式,独立打分(value:这个中间结果离答案还有多远)和跨状态投票(vote:几个候选里哪个最有戏);
  • 搜索算法:BFS(逐层展开保留 b 个最优)或 DFS(深入一条路,评估低于阈值就回溯)。

24 点实验:数字值得细看

论文的招牌实验是 Game of 24:给 4 个数字,用加减乘除凑出 24。这个任务选得很刁钻——它需要「lookahead」(当前这一步算错,后面全盘皆输)和「回溯」(发现走死要能换路),恰好是单线推理的死穴。

实验设计:随机抽 100 道题(来自 4nums.com 的 1362 题中的索引 901-1000),同一批题、同一个 GPT-4,只改推理结构:

  • 直接给答案(IO prompting):成功率 4%
  • CoT(分步推理):4%——思维链在这个任务上几乎没用,因为一旦第一步算错,后面只是错得更有条理
  • CoT-SC(采 100 条链取多数投票):约 9%
  • ToT(宽度 b=5):成功率 74%

从 4% 到 74%,模型一个字都没改,改的只是 Harness 层的搜索结构——这是「规划决定能力上限」最震撼的实证。

状态评估器在 24 点里是这么干活的:每算一步,让模型判断剩余数字「确定 / 可能 / 不可能」凑出 24——剩 6 和 4 标「确定」优先展开,剩 10 和 13 标「不可能」直接剪枝。这个看似粗糙的三档评分就是整棵搜索树的导航系统。评估器比生成器更重要:候选想得再多,打分不靠谱,树搜索就只是在错误的方向上越走越远。

但成本的账必须算。 ToT 每道题要发起几十次模型调用(生成候选 × 评估 × 多层搜索),token 消耗是单线 CoT 的几十倍。论文的另一个实验(创意写作)里,ToT 让 GPT 自动评估的连贯性得分明显高于 CoT,但同样是靠百倍级的采样换来的。所以工程结论非常清晰:

  • 值得用 ToT 的场景:单步价值极高、错了不可逆、且中间状态可被评估(数学证明、复杂规划、24 点这类「能算中间值」的任务)。「可评估性」是隐藏前提——24 点能检查中间数字是否可能凑出 24,代码能不能跑、单测过不过也是天然评估器。
  • 不值得用的场景:对话、开放式写作、无法给中间状态打分的任务——树搜索退化成「花几十倍的钱随机游走」。

Reflexion:用错题本做「言语强化学习」

Reflexion(2023,arXiv:2303.11366)上一章提过一句,这里把机制拆透。它的全称思路是 verbal reinforcement learning(言语强化学习):传统 RL 用数值奖励更新权重,Reflexion 用自然语言的反思更新上下文。三个角色:

  • Actor:干活的 Agent(通常是个 ReAct 循环);
  • Evaluator:裁判,判断这一轮尝试成功还是失败。HumanEval 上用单元测试当裁判,ALFWorld 上用环境反馈;
  • Self-Reflection 模型:失败后生成一段文字反思——「我错在哪、下次应该怎么改」,存进一个外部记忆(episodic memory),下一轮带着这段反思重跑。

Reflexion 循环:Actor 作答、Evaluator 用单测或环境反馈当裁判,失败后 Self-Reflection 写反思进错题本,下一轮带着反思重试

最小实现(Python):

memory = []  # 错题本:历轮反思
for _ in range(3):                      # 熔断:最多试 3 轮
    code = actor.solve(task, memory)    # 带着历史反思作答
    failed = run_tests(code)            # Evaluator:单测当裁判
    if not failed:
        break
    note = reflect(task, code, failed)  # 生成文字版反思
    memory.append(note[:500])           # 截断后进记忆,防上下文膨胀

HumanEval 实验:91% vs 80%

论文在代码生成基准 HumanEval 上,GPT-4 裸跑 pass@1 是 80%,加上 Reflexion 后达到 91%——靠的是失败后读单测报错、写反思、重写代码,最多重试若干轮。在 ALFWorld 决策任务上更夸张:Reflexion 把 ReAct 的成功率一路推到 97%(134 个任务只失败 4 个)。

机制上有两个细节决定了它好不好用:

  • 反思的质量取决于报错的信息量。 单测失败信息(哪条断言、期望值实际值)是高质量的「梯度信号」;如果 Evaluator 只能给「成功/失败」一个 bit,反思就很容易变成瞎猜。这也是为什么 Reflexion 在「有自动验证器」的任务上效果拔群,在开放任务上大打折扣。
  • 记忆要管理。 反思越积越多会挤爆上下文,工程上需要截断、压缩、甚至只保留「最近一次 + 最高频错误」。

同时要警惕它的边界:Reflexion 也可能把错误「合理化」——模型写出一篇逻辑自洽但方向全错的反思,带着它越跑越偏。而且 token 成本直接乘上重试轮数。它适合「有可验证标准答案」的任务,不适合「没有裁判」的任务。


过度规划:反方的声音

讲完了规划的收益,必须给反方同等篇幅,因为「过度规划」是 Agent 新手最常踩的坑。

反方论点一:规划本身烧 token、烧延迟。 Planner 是一次额外的大模型调用,Replanner 每次触发都要重读全文再出一份计划,ToT 更是几十倍的成本。如果一个任务本来 3 步 ReAct 就能搞定,套 Plan-and-Execute 等于为了点一份外卖先开了个项目立项会。Anthropic 在《Building Effective Agents》里的原话精神就是:找到能用的最简单的方案,只在证明有效的前提下增加复杂度。

反方论点二:计划赶不上变化。 军事上有句老话:「没有任何计划在遭遇敌人后还能幸存。」Agent 的环境是非平稳的——网页改版、接口超时、用户中途改需求。计划越长,它基于的信息越陈旧,腐化越严重。一份 20 步的精细计划,可能走到第 5 步就整体作废,前期制定计划的 token 全部沉没。环境变化越快,计划的保质期越短,越应该倾向 ReAct 式的现场决策。

反方论点三:简单任务上规划是负资产。 大量真实请求其实是「一问一答」级别的:查个天气、改一行代码、总结一段话。这类任务上规划不仅浪费,还引入新的失败模式——Planner 幻觉出不可执行的步骤、把简单任务拆碎后反而放大了累积错误率。社区在多个基准上观察到,Plan-and-Execute 相对纯 ReAct 的提升经常很有限,有时甚至下降,原因多是「计划的质量不如模型的现场判断」。

那么什么时候规划真的有正收益? 一张决策清单:

  • 任务步骤可预先穷举 → 别用 Agent,用 Workflow 写死流程,最便宜最可控;
  • 步骤不可预知、需要边看边走 → ReAct,不要规划;
  • 有全局约束或长程依赖(预算、先后顺序、资源分配)→ Plan-and-Execute;
  • 单步错了不可逆、中间状态可评估 → 才轮到 ToT;
  • 有可自动验证的答案 → Reflexion 几乎总是划算的。

工程实践要点

把上面的理论落到代码里,有几条实战建议:

  • 计划要存成结构化数据,不要只活在上下文里。 用 JSON 数组记录每个步骤的状态(todo/done/failed),而不是让计划以自然语言散落在对话历史里。结构化的计划才能被 Replanner 可靠地 diff 和修改,也方便打日志做可观测。
  • Planner 和 Executor 可以用不同的模型。 规划是全局推理,值得用大模型;单步执行是局部决策,小模型往往够用。这个组合能把成本砍掉一半以上,效果几乎不掉。
  • 给规划加预算。 最大计划步数、最大重规划次数、最大 token 预算,三层熔断缺一不可。重规划次数超限本身就是一个信号:任务定义有问题,该升级给人类了。
  • Executor 内部保留 ReAct 的灵活性。 Plan-and-Execute 不是「先想后做就无脑执行」,每一步内部仍然要根据工具结果现场反应——全局靠计划,局部靠反应,两条腿走路。
  • 评估优先。 想上 ToT 或 Reflexion 之前,先问自己:这个任务的中间状态/最终结果能不能自动评估?不能的话,先造评估器,否则搜索和反思都没有方向。

常见误区

  • 上来就 ToT:树搜索是核武器不是常规武器,单线 ReAct 能解决的问题用它等于烧钱取暖
  • 每步都重规划:退化成一个巨贵的 ReAct,还引入了「朝令夕改」的新问题
  • 计划只写在 prompt 里:自然语言计划没法可靠更新,要存成结构化状态
  • 把 Reflexion 当微调:它不改权重,「经验」只存在上下文里,换个会话就忘了
  • 给简单任务套规划:一问一答的任务上 Planner 是纯纯的负资产——多一次调用、多一截延迟、多一个出错点
  • 以为规划能弥补模型能力不足:规划是放大器不是发电机——它能把 60 分的模型组织出 80 分的效果,但组织不出 100 分

术语表

名词定义一句话直觉常见混淆
任务分解把复杂任务拆成可独立求解子问题的过程把大象装冰箱分三步与「分治算法」混淆:分解不要求子问题同构,关键是缩短错误累积链
Least-to-Most先显式列出全部子问题、再按序逐个求解的提示技术(2022)先看完整张考卷,再从易到难答题与 CoT 混淆:CoT 边答边拆,Least-to-Most 拆和答是两次独立动作
Plan-and-Execute先由 Planner 出完整计划、Executor 逐步执行、必要时 Replanner 修订的范式先画图纸再施工,图纸错了就地改与 Workflow 混淆:Workflow 的流程是人预先写死的,Plan-and-Execute 的计划是模型现场生成的
Planner / Executor / ReplannerPlan-and-Execute 的三个角色:制定计划、执行单步、修订计划建筑师 / 施工队 / 驻场监理以为必须三个独立模型——可以是同一个模型扮演不同角色,只是调用时机不同
重规划(Replanning)执行中发现计划与现实脱节时修订计划的动作导航说「前方拥堵,已为你重新规划路线」以为越频繁越好:每步重规划 = 昂贵的 ReAct,还有朝令夕改的副作用
Tree of Thoughts把推理建模为搜索树:生成候选、评估打分、按 BFS/DFS 展开(2023)下棋时同时算多条变化再选最优与 CoT-SC 混淆:CoT-SC 是「多条独立链投票」,链之间无交互;ToT 有中间状态评估和回溯
状态评估器ToT 中给部分解打分的组件(value 打分或 vote 投票)裁判在中盘判断这盘棋谁占优以为可以省略:没有可评估的中间状态,ToT 退化成昂贵的随机搜索
Reflexion失败后生成文字反思存入记忆、带着反思重试的方法(2023)错题本:下次考试前先翻一遍与微调混淆:不改权重,「经验」只活在上下文/外部记忆里
pass@1代码生成指标:只生成一次答案就通过测试的概率一锤子买卖的命中率与 pass@k 混淆:pass@k 允许试 k 次取最好,数字天然更高,比较时别看混
言语强化学习Reflexion 的自称:用自然语言反思代替数值梯度来「更新」行为不用改大脑,改错题本就行与真 RL 混淆:没有梯度、没有权重更新,「学习成果」随会话结束而消失
计划腐化长计划在执行中因环境变化而过时的现象出门前查的路线,开了一半已经大堵车以为重规划能完全解决:重规划本身有成本,且新计划基于的仍是旧认知
过度规划给不需要规划的任务强加规划层,导致成本上升、效果反降点一份外卖先开立项会以为规划多多益善:简单任务上 Planner 是新的失败模式来源

参考材料


小结

记住三种范式的分工:ReAct 边想边做,Plan-and-Execute 先想后做,ToT 想多条路——它们不是竞争关系,是「思考的时机与宽度」上的三个取点。

再记住两组数字和一个原则。ToT 在 24 点上把 GPT-4 从 4% 拉到 74%,Reflexion 在 HumanEval 上把 pass@1 从 80% 推到 91%——规划确实决定能力上限。但规划本身烧 token,计划会腐化,简单任务上规划是负资产。那个原则是:范式之争的答案永远是任务结构——步骤可预知用 Workflow,边看边走用 ReAct,有全局约束用 Plan-and-Execute,错了不可逆且中间可评估才上 ToT。 从最简单的方案起步,痛了再加复杂度,这个顺序永远不会错。