第 15 章 规划 Planning
本章要解决的问题
复杂任务要先列计划再执行------计划生成后环境变了怎么办?ReAct 和 Plan-and-Execute 怎么选?
章节大纲
- 15.1 任务分解:从目标到子任务
- 15.2 计划生成与动态修正
- 15.3 ReAct vs Plan-and-Execute 对比
- 15.4 主流框架对照与变体
- 🛠 解决方案:计划过期失效的动态重规划
15.1 模式原理:从目标到子任务
15.1.1 一句话定义
规划(Planning)是让模型在动手前先产出执行计划------把一个大目标分解成有序的、可执行的子任务序列,然后按计划推进。 它与提示链(第 10 章)的本质区别在于:提示链的步骤是预先写死的,规划模式的步骤是模型按任务动态生成的。
提示链:步骤固定(开发者写死)── 适合可预见的流程
规划: 步骤动态(模型按任务生成)── 适合每次任务都不同的场景
15.1.2 为什么需要规划:不规划的三个代价
让模型直接"蒙头执行"复杂任务,会踩三个坑:
- 漏步骤:目标隐含多个环节,模型顺着答只覆盖了一部分(比如"筹备产品发布会"只写了文案,漏了场地、预算、排期)。
- 顺序错乱:步骤之间有依赖(先调研再定方案),模型可能先做后置步骤。
- 不可审计:没有计划就没有"预期路径",无法判断执行是否偏离。
规划的收益正是:把"黑盒执行"变成"有清单、可检查、可修正"的推进过程。这也是为什么大型任务(项目交付、报告产出、多步骤 Agent)几乎都离不开规划。
15.1.3 任务分解的粒度控制
计划不是越细越好,两条经验法则:
| 粒度 | 特点 | 适用 |
|---|---|---|
| 粗粒度(3~5 步) | 灵活、抗变化、步骤易失效 | 开放式任务、环境多变 |
| 中粒度(5~10 步) | 平衡 | 大多数业务任务 |
| 细粒度(10+ 步) | 清晰但僵化、易过期 | 流程稳定的任务 |
计划的粒度应与环境的不确定性成反比:环境越动态,计划越要粗,留出调整空间。
15.2 计划生成与动态修正
15.2.1 计划的结构化输出
计划必须结构化,否则无法校验和执行。推荐格式(JSON):

图 1:计划 JSON 结构
python
PLAN_PROMPT = """你是任务规划器。把用户目标分解成执行计划,只输出 JSON:
{
"objective": "对目标的一句话重述",
"steps": [
{"id": 1, "action": "做什么", "depends_on": [0],
"output": "这一步产出什么", "verify": "怎么确认做对了"}
],
"risks": ["可能的风险"]
}
目标:{goal}"""
关键设计点:
depends_on显式声明依赖------为并行化留口子(呼应第 12 章:无依赖的步骤可并行执行)。verify每步自检方式------为执行中的校验留钩子(呼应第 13、17 章)。risks提前暴露风险------让执行器对已知风险有预案。
15.2.2 计划的动态修正:Plan-and-Execute 的"重规划"机制
计划最大的敌人是环境变化 :原计划假设"数据源可用",执行时发现挂了;假设"预算 5 万",中途被告知只有 3 万。此时必须重规划。

图 2:动态重规划机制

图 3:Plan-and-Execute
Plan-and-Execute 架构天然支持这一点:执行器每完成一步,回看"计划是否仍成立",不成立就重新规划剩余步骤:
python
def plan_and_execute(goal, max_plan_rounds=3):
plan = generate_plan(goal) # 生成计划
for round in range(max_plan_rounds):
result = execute_plan(plan) # 按计划执行
review = check_execution(plan, result) # 检查是否偏离
if review["on_track"]:
return result
# 偏离 → 带着执行结果重规划剩余步骤
plan = replan(goal, plan, review["issues"])
return result
重规划的触发条件(三选一即可):
- 某一步执行失败且无法重试(工具挂了、数据源不可用)。
- 执行结果与计划假设冲突("市场数据"实际是"竞品数据")。
- 用户中途改需求(新增约束/缩小范围)。
重规划 ≠ 从头再来:重规划应保留已完成步骤的结果,只重排"剩余步骤"------不然就是反复烧钱(呼应第 13 章改进检测的"回退"思路)。
15.2.3 执行中的计划校验
光有计划不校验等于没有。执行器在每步完成后做三件事:
- 产出校验 :该步的
verify规则过没过(格式/字段/外部验证)。 - 计划一致性:当前结果与计划预期是否吻合,偏差是否可接受。
- 目标收敛:做完这步是否离目标更近(防止"绕路执行")。
15.3 ReAct vs Plan-and-Execute 对比
这是规划模式最重要的选型问题,直接决定架构。ReAct(Reasoning + Acting)是 Agent 领域最经典的推理-执行范式。
15.3.1 两种范式的工作原理
ReAct(思考→行动→观察,交错进行):
text
思考:我需要知道用户订单状态 → 调用查订单工具
行动:query_order("A123")
观察:{"status": "已发货", "eta": "明天"}
思考:已发货且明天到 → 可以回答用户了
行动:直接回答
每一步都是"想一步 → 做一步 → 看结果 → 再想"的紧密循环。计划藏在思考里,没有独立的计划产物。
Plan-and-Execute(先计划→再执行,两段式):
text
[计划阶段]
生成计划:①查订单 ②查物流 ③生成回复(3 步,带依赖)
[执行阶段]
第1步:查订单 → 完成
第2步:查物流 → 完成
第3步:生成回复 → 完成 → 返回
计划先行产出,执行器按清单逐项推进,偏离时重规划。
15.3.2 对比表
| 维度 | ReAct | Plan-and-Execute |
|---|---|---|
| 结构 | 单循环,思考行动交错 | 两段式,计划先行 |
| 灵活性 | 极高,随时调整 | 中,靠重规划调整 |
| 可解释性 | 每步可见但无总览 | 有计划清单,全局清晰 |
| 成本 | 思考步数多,token 高 | 路径明确时通常更省;路径频繁变化时重规划会增加成本 |
| 上下文占用 | 每步思考累积,容易长 | 计划固化后上下文干净 |
| 复杂任务 | 容易迷失,绕路 | 有清单兜底,不易漏步 |
| 适用 | 探索型任务(不确定怎么做) | 常规型任务(路径基本可知) |

图 4:ReAct vs Plan-and-Execute
15.3.3 选型决策:一句话
知道怎么做 → Plan-and-Execute(省成本、防漏步);不知道怎么做、需要边做边探 → ReAct(灵活探索)。
工程上的常见折中是混合式:先用 Plan-and-Execute 生成粗计划,执行到某一步发现"这一步到底怎么做不确定"时,在该步内降级为 ReAct 探索("计划外带探索")。这是目前生产环境里性价比最高的形态。
15.4 完整示例:Plan-and-Execute 报告生成器
python
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.deepseek.com", api_key="<你的Key>")
def generate_plan(goal):
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": f"""把目标分解为执行计划,只输出 JSON:
{{"objective": "...", "steps": [{{"id": 1, "action": "...",
"depends_on": [], "verify": "..."}}], "risks": []}}
目标:{goal}"""}],
temperature=0.2, response_format={"type": "json_object"},
)
try:
return json.loads(resp.choices[0].message.content)
except json.JSONDecodeError:
return {"objective": goal, "steps": [], "risks": ["规划生成失败,需人工介入"]}
def execute_step(step, context):
"""执行单个计划步骤(真实场景里调工具/子链)"""
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content":
f"执行任务步骤:{step['action']}\n上下文:{json.dumps(context, ensure_ascii=False)}"}],
temperature=0.3,
)
return resp.choices[0].message.content
def replan(goal, plan, done_steps, issues):
"""保留已完成步骤的结果,重排剩余步骤。
done_steps 包含原步骤结构和执行结果,便于重规划时参考。"""
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": f"""原计划执行出现问题,请重规划剩余步骤。
目标:{goal}
已完成步骤及其结果:{json.dumps(done_steps, ensure_ascii=False)}
出现的问题:{json.dumps(issues, ensure_ascii=False)}
只输出 JSON:{{"remaining_steps": [{{"id": 1, "action": "...",
"depends_on": [], "verify": "..."}}], "risks": []}}"""}],
temperature=0.2, response_format={"type": "json_object"},
)
try:
result = json.loads(resp.choices[0].message.content)
except json.JSONDecodeError:
result = {"remaining_steps": [], "risks": ["重规划失败,需人工介入"]}
# 保留已完成步骤 + 追加重规划后的剩余步骤
result["completed"] = done_steps
return result
def run(goal, max_plan_rounds=3):
plan = generate_plan(goal)
done, issues = [], []
for round in range(max_plan_rounds):
context = {"done": done}
try:
for step in plan.get("remaining_steps", plan["steps"]):
result = execute_step(step, context)
done.append({"id": step.get("id"), "step": step["action"],
"result": result, "verify": step.get("verify", "")})
return done # 全步成功
except Exception as e:
issues.append(str(e))
plan = replan(goal, plan, done, issues) # 重规划剩余
return done
report = run("生成一份 2026 Q3 电商行业分析报告")
工程要点:
- 计划用 JSON 结构化输出,
depends_on为并行留口子。 - 执行异常 → 带着已完成结果重规划(不推倒重来)。
- 重规划次数设上限(
max_plan_rounds),防死循环(呼应第 13 章停止条件)。 - 生产加固 :每个 LLM 调用应加
timeout参数和重试逻辑(如tenacity库),API 异常时降级为人工介入而非崩溃;并行执行步骤时用信号量限流(第 12 章);用户输入的goal应做长度限制和注入检测(第 22 章)。
15.5 主流框架对照与变体
15.5.1 框架对照
| 实现方式 | 特点 | 适用 |
|---|---|---|
| 自研(本章主线) | 计划/执行/重规划三函数,完全可控 | 教学、定制化 |
LangChain PlanAndExecuteAgentExecutor |
框架内置规划器+执行器 | 快速搭建 |
| LangGraph 规划节点 | 计划节点+条件边重规划 | 复杂图结构 |
| BabyAGI / AutoGPT 式任务队列 | 动态生成任务队列,不断追加 | 探索型自动化 |
15.5.2 变体一:层级规划(Hierarchical Planning)
高层规划(大目标 → 阶段)与低层规划(阶段 → 具体步骤)分离。高层规划器不关心细节,低层规划器在阶段执行时再细化。适合超大型任务,代价是系统复杂度上升(呼应第 16 章多智能体:层级规划往往是多 Agent 协作的基础)。
15.5.3 变体二:规划 + 并行(Plan-and-Parallelize)
利用计划的 depends_on:把无依赖的步骤并行执行(呼应第 12 章)。计划阶段就标注哪些步骤可并行,执行阶段据此 Fan-out,显著缩短总时长。
15.5.4 变体三:反思型规划(Reflective Planning)
每执行完一步,用反思(第 13 章)评估"这一步的产出质量"和"计划是否仍合理",把反思结论喂给重规划。规划 + 反思 + 重规划构成完整闭环,是复杂 Agent 系统的标配。
🛠 解决方案:计划过期失效的动态重规划
常见问题
- "计划生成得很好,但执行时环境全变了":计划过期是常态不是异常。对策:Plan-and-Execute 的"重规划"机制(15.2.2),带已完成结果重排剩余步骤。
- "ReAct 走着走着迷路了":思考步累积导致上下文膨胀、目标漂移。对策:换 Plan-and-Execute(路径可预知时);或给 ReAct 加"目标重申"(每 N 步回顾原始目标)。
- "计划步骤漏了关键环节" :计划质量差。对策:计划提示词加
verify/risks字段强制自查;对高风险任务用"规划 + 反思"双模型(一个出计划、一个审计划,呼应第 13 章互评)。 - "重规划反复发生,成本爆炸":重规划也要设上限(3 次),超过直接转人工(呼应第 24 章熔断)。频繁重规划本身说明任务不适合规划模式,考虑 ReAct 或降级。
- "计划太细,一步失效全盘乱":粒度控制问题。对策:环境动态 → 计划粗粒度(15.1.3),把细化留给执行时。
解决方案速查表
| 现象 | 根因 | 解决方案 |
|---|---|---|
| 计划过期 | 环境变化 | 重规划(保留已完成) |
| ReAct 迷路 | 上下文膨胀 | 目标重申 / 换 Plan-Execute |
| 漏关键步骤 | 计划质量差 | verify/risks 字段 + 双模型审计划 |
| 反复重规划 | 任务不适合规划 | 上限 3 次 + 转人工 |
| 计划僵化 | 粒度太细 | 粗粒度 + 执行时细化 |
实战提示
- 计划的产出要可校验 :每步带
verify,没有校验的计划等于没有计划。 - 重规划是核心能力:plan-and-execute 的价值不在"计划准",而在"计划错了能快速纠偏"。
- 先粗后细:第一次生成粗计划,执行中逐步细化,别指望一次规划到底。
- 选型别纠结:路径可知用 Plan-and-Execute,路径未知用 ReAct,两者混合最高性价比。