任务规划器的三种范式对比:ReAct、Plan-and-Execute 与 Tree-of-Thought 在真实业务中的取舍

一、为什么任务规划是 Agent 的分水岭

上一篇文章讲 Function Calling,解决的是"模型如何调用工具";但工具再多,没有规划能力,Agent 就只能做"一次调用"的简单问答。真正复杂的业务诉求------"帮我对比三家供应商的报价并生成采购建议"------需要 Agent 自己拆解成多个子任务、决定执行顺序、根据中间结果调整后续步骤。这个"拆解与决策"的过程,就是任务规划。

目前业界主流的规划范式有三条路线:ReAct (边想边做)、Plan-and-Execute (先计划后执行)、Tree-of-Thought(多路径搜索)。很多人把三者当成"选一个用",实际上它们解决的是不同层次的问题,适用场景、成本、稳定性差异巨大。这篇文章用三个最小实现把三者讲透,再给出一张真实的选型决策表。

二、三种范式速览

维度 ReAct Plan-and-Execute Tree-of-Thought
核心思想 推理与行动交替 先规划后逐步执行 同时探索多条推理路径
规划时机 边走边规划(动态) 一次性规划(静态) 每步分支搜索
LLM 调用次数 每步 1 次,总次数不定 计划 1 次 + 每步 1 次 每步多次(分支×候选)
成本
可解释性 强(每一步可审计) 强(计划先于行动) 中(并行路径难追踪)
最适合 需要查工具/环境的动态任务 步骤明确的多阶段任务 高难度推理、试错型问题

一句话概括:ReAct 适合"环境会变"的任务,Plan-and-Execute 适合"步骤固定"的任务,Tree-of-Thought 适合"一步错全盘错"的难题

三、ReAct:边想边做

ReAct(Reasoning + Acting)是三者里最接近"人"的工作方式:每一步先思考(Thought)、再决定动作(Action)、观察结果(Observation),循环往复。它的核心优势是动态性------计划可以随环境反馈实时修正。

python 复制代码
def react_agent(task: str, tools: dict, max_steps: int = 6) -> str:
    """
    ReAct 最小实现:Thought -> Action -> Observation 循环
    tools: {"search": fn, "calc": fn, ...}
    """
    history = []   # 保留 Thought/Action/Observation 三元组

    for step in range(max_steps):
        # 1) 让模型基于历史产出"下一步思考+动作"
        prompt = f"""任务:{task}
可用工具:{list(tools.keys())}
已执行步骤:{history}
请输出 JSON:{{"thought": "你的推理", "action": "工具名", "args": {{...}}}}
如果任务已完成,action 输出 "finish",args 里放最终答案。"""
        resp = llm(prompt)   # 结构化输出

        if resp["action"] == "finish":
            return resp["args"]["answer"]

        # 2) 执行工具,观察结果
        try:
            obs = tools[resp["action"]](**resp["args"])
        except Exception as e:
            obs = f"工具错误:{e}"

        # 3) 把三元组写回历史,供下一轮推理
        history.append(f"Thought:{resp['thought']} | Action:{resp['action']} | Observation:{obs}")

    return "已达最大步数,未能完成任务"

生产中的关键点:

  • history 要截断:ReAct 每步都往上下文追加内容,长任务下 token 会爆炸,务必保留最近 N 步(通常 4~6 步);
  • 步骤上限必须设:没有 max_steps,模型可能陷入"搜索→观察→再搜索"的死循环,成本失控;
  • 结构化输出是前提:要求模型输出 JSON,而不是自由文本,否则解析成本极高。

ReAct 在"需要实时查数据"的场景(客服查单、多轮检索)表现最好,因为每步都能利用最新环境信息修正方向。代价是步数不可控,长任务成本线性上涨。

四、Plan-and-Execute:先计划,后执行

Plan-and-Execute 把规划从执行中剥离:先用一次 LLM 调用生成完整计划(计划器),再按计划逐条执行(执行器)。规划是静态的,执行是线性的------计划器不参与每步执行,只在下游规划失败时才介入。

python 复制代码
def plan_and_execute(task: str, tools: dict, max_steps: int = 8) -> str:
    # 阶段一:计划器,一次性产出步骤清单
    plan = llm(f"""任务:{task}
可用工具:{list(tools.keys())}
请输出分步执行计划,每步一个 JSON 对象,
格式:[{{"step": 1, "action": "工具名", "args": {{...}}, "goal": "这一步的目的"}}]
最多 {max_steps} 步。""")

    # 阶段二:执行器,线性执行,可带局部重规划
    results = []
    for step in plan:
        try:
            out = tools[step["action"]](**step["args"])
            results.append(f"Step{step['step']}({step['goal']}): {out}")
        except Exception as e:
            # 失败时只重规划"后续步骤",不重跑已完成的
            plan = replan_remaining(task, step["step"], results, e)
    return finalize(task, results)

相比 ReAct 的三个优势:

  1. 成本低且可预测:计划 1 次 + 每步 1 次调用,总调用次数 ≈ 1 + 步数,上限确定;
  2. 可解释性强:先给你看完整计划,再开始干活------这在需要审批、审计的业务里是刚需;
  3. 失败隔离:某一步失败,只需重规划剩余步骤,已完成的结果不浪费。

但它有一个致命弱点:计划是静态的 。如果第一步执行后环境发生了变化(比如库存没了),而计划还是按旧假设编排的,后续步骤就会基于错误前提执行。所以生产上几乎都用它的变体------Plan-and-Solve / 带重规划的 Plan-and-Execute:执行器每完成 N 步,让计划器核对"计划是否仍然成立",不成立就重新规划。

python 复制代码
def plan_execute_with_replan(task, tools, replan_every: int = 3):
    plan = make_plan(task, tools)
    for i, step in enumerate(plan):
        out = execute(step, tools)
        if (i + 1) % replan_every == 0 and not plan_still_valid(task, plan, i):
            plan = make_plan(task + f"\n已完成:{i+1} 步,请基于最新情况重排剩余计划", tools)
    return final_answer(plan, results)

适用场景 :报表生成、数据管道、多阶段审批流------步骤明确、顺序固定、每步结果可预期的任务。它也是三种范式里最容易做产品化的:计划本身就是一份可以给用户看、给审批人看的工作清单。

五、Tree-of-Thought:多路径搜索

Tree-of-Thought(ToT)不是"规划器"本身,而是一种推理增强框架:每一步不是只走一条路,而是让模型生成多个候选思路,评估打分,保留最有希望的若干分支继续探索。适合"一步错、全盘错"的高难度问题(数学证明、逻辑谜题、复杂代码调试)。

python 复制代码
def tree_of_thought(problem: str, branches: int = 3, depth: int = 3) -> str:
    """
    最小 ToT:每层生成 branches 个候选,保留 top-1 继续
    完整版应保留 top-k 并做宽度优先搜索
    """
    frontier = [{"path": [], "state": problem}]

    for level in range(depth):
        new_frontier = []
        for node in frontier:
            # 1) 基于当前状态,生成 branches 个不同思路
            candidates = llm(f"""问题:{problem}
当前推理路径:{node["path"]}
请给出 {branches} 种不同的下一步解法,分别用编号列出。""")
            # 2) 评估每个候选的价值(用一次 LLM 打分)
            for cand in candidates:
                score = llm(f"给这个思路的可行性打分(0-10):{cand}")
                new_frontier.append({
                    "path": node["path"] + [cand],
                    "score": float(score),
                })
        # 3) 保留分数最高的分支继续
        new_frontier.sort(key=lambda n: -n["score"])
        frontier = new_frontier[:max(1, len(new_frontier) // 2)]

    # 对最终保留的分支做收敛
    return llm(f"基于这些思路给出最终答案:{frontier[0]['path']}")

成本是它的硬伤 :每层调用次数 = 分支数 × (生成 + 打分),三层 3 分支就是 18 次调用起步,而且每个候选的评估本身也不可靠------LLM 给自己打分,经常"觉得自己都对"。生产上 ToT 通常只用在:

  • 复杂推理类任务(数学、代码难题、策略分析);
  • 前端给用户展示"多种方案对比"的场景;
  • 结合 ReAct 做"规划+搜索"混合(即 ReAct + 分支探索)。

六、真实业务选型:一张决策表

前面是原理,下面是实战。我按"任务类型"给出推荐组合,这三条几乎覆盖了绝大多数 AI 应用:

业务场景 推荐范式 理由
客服查单、多轮检索问答 ReAct 环境实时变化,需要每步修正
报表生成、数据管道、审批流 Plan-and-Execute(带重规划) 步骤固定、成本可控、计划可审计
复杂代码调试、数学/逻辑难题 Tree-of-Thought 需要多路径试错,容忍高成本
采购分析、方案对比(输出多种建议) ReAct + ToT 混合 主干用 ReAct,关键决策点用 ToT 分支

三个最容易踩的坑:

  1. 拿 ToT 处理简单任务:普通问答用 ToT,成本翻十几倍,收益为零------先问自己"这个任务真的需要多路径试错吗";
  2. 纯 Plan-and-Execute 不加重规划:计划一旦过期,整条执行链全错,必须做"计划健康检查";
  3. ReAct 不做步数上限和上下文截断:线上 80% 的"Agent 失控"都来自这两个缺失。

成本与质量的最终权衡 :预算敏感选 Plan-and-Execute,质量敏感选 ReAct+重规划,只有难题才值得 ToT。生产上更常见的做法是三级路由:先意图分类,简单任务直接问答,中等任务走 Plan-and-Execute,复杂任务才升级到 ReAct/ToT------让 90% 的请求跑在便宜路径上,把贵的算力留给真正需要的地方。

七、总结

  • ReAct = 动态修正,适合环境会变的交互型任务,注意步数上限;
  • Plan-and-Execute = 静态计划 + 线性执行,适合步骤明确的流程型任务,记得加重规划;
  • Tree-of-Thought = 多路径搜索,适合高难度推理,成本最高,慎用;
  • 三者不是互斥的,生产中按"任务难度 × 成本预算"组合使用,才是工程化的正确姿势。

规划器没有银弹,只有"在正确的场景用正确的范式,并控制好成本与失败边界"。

相关推荐
shehuiyuelaiyuehao20 分钟前
算法31,前缀和,可被k整除的子数组
数据结构·python·算法
宸津-代码粉碎机41 分钟前
AI攻防战升级!基于Spring AI构建Java应用自动免疫安全体系
java·大数据·开发语言·人工智能·python·安全·spring
测试19981 小时前
如何用appium搭建Android自动化测试框架?
自动化测试·软件测试·python·测试工具·职场和发展·appium·测试用例
程序员大雄学编程1 小时前
微积分46. 无穷级数四大核心性质:从理论到实践的全方位解析
python·学习·微积分·学习工具
hzxpaipai1 小时前
企业官网技术架构拆解:前端、后台、数据库、服务器如何协同
前端·数据库·架构
数字化转型分享点滴2 小时前
## 工厂数字化管理系统的价值体现:构建制造全流程数据闭环
python
小磊哥er2 小时前
深入解构Claude Code - 第 12 篇 · 整体串起来
javascript·ai编程
小磊哥er2 小时前
深入解构Claude Code - 第 11 篇 · 工程上的讲究
javascript·ai编程
2301_800074212 小时前
map,list简单方法
windows·python·list