第 13 节 · Plan-and-Solve:先规划再执行
一句话回答
Plan-and-Solve 把"思考"和"行动"切成两个阶段:先让 LLM 把任务拆成一个有序步骤列表,再逐步执行。
跟 ReAct 反过来——ReAct 是走一步看一步,Plan-and-Solve 是先在脑里把整盘棋画出来,再开始下。
三段架构

用户问题
│
▼
┌──────────┐ 步骤列表
│ Planner │ ───────────► [
└──────────┘ "查北京天气",
│ "推荐景点",
│ "汇总输出",
│ ]
▼
┌──────────┐
│ Executor │ ── 步骤 1 ──► 调工具 ──► 结果 1
│ │ ── 步骤 2 ──► 调工具 ──► 结果 2
│ │ ── 步骤 3 ──► 调工具 ──► 结果 3
└──────────┘
│
▼
┌──────────┐
│Aggregator│ ──► 最终答案
└──────────┘3 个角色:
- Planner:一次 LLM 调用,输出一个步骤数组(通常要求 JSON 格式)
- Executor:每个步骤一次小循环(可以复用 Day2 的最小 Agent Loop)
- Aggregator:一次 LLM 调用,把所有步骤结果汇总成最终答案
跟 ReAct 的核心区别
| 维度 | ReAct | Plan-and-Solve |
|---|---|---|
| 决策时机 | 每一步看了 Observation 再决定 | 先生成初始计划,再按计划执行 |
| 灵活度 | 高(随机应变) | 低(按计划走) |
| token 消耗 | 步多 = token 多 | 一次规划 + 多次小执行 |
| 适用任务 | 信息收集型(不知道下一步要查什么) | 流程明确型(知道大致要做哪几步) |
| 失败时 | 自然在循环里换路 | 静态计划容易失效,工业版要 Replan |
Planner 的关键:让 LLM 输出结构化步骤
最容易翻车的点:Planner 输出的不是结构化数据。
# 错误的 Planner prompt
"请帮用户拆解这个问题,告诉我要做几步"
# 模型可能输出
"我觉得这个问题可以分三步:第一步查天气,然后..."
# ↑ 你怎么 parse?正确做法:强约束 JSON 数组:
PLANNER_PROMPT = """...
严格输出 JSON 数组,每项一个字符串描述子任务。
不要任何其他文字。
输出:"""但即使这样,模型还是可能:
- 用
```json ... ```包裹(要剥掉) - 在数组前后多写一段(要找到
[和]) - 输出对象而不是数组(要做容错)
工程版本通常用 Pydantic、Zod、JSON mode 或 JSON Schema Structured Outputs,今天的 demo 用最朴素的"找 [ 找 ] 然后 json.loads"。
TIP
2024 年起,OpenAI 等平台支持基于 JSON Schema 的 Structured Outputs / strict: true。它能显著降低 Planner 输出解析失败的概率,但只能保证形状符合 schema,不能保证计划一定合理。今天 demo 故意不用,让你体会一下"模型不规矩"时的容错有多烦。
计划赶不上变化:Replan

静态版 Planner 会在最开始定下所有步骤——但执行中发现实际情况跟规划不符怎么办?
例子:
- 计划:1. 查北京天气 → 2. 推荐户外景点 → 3. 输出
- 实际:第 1 步查到"今天大雨" → 第 2 步还按"户外景点"执行就没意义了
两种应对:
- 静态 Plan-and-Solve(今天 demo 的做法):每个步骤的 Executor 拿到上一步结果作为 context。Executor 自己有一定的"应变能力"——比如 Executor 看到"大雨"会自动改推荐室内景点。
- 动态 Replan(更工业的做法):执行中发现失败 / 关键假设变了 → 回到 Planner 重新规划,或者只替换后续未执行的步骤。
今天为简化只做静态版。你可以先把计划理解成一份假设,不是一份不会变的合同。
2026 年怎么看 Planning
Anthropic 的 agent workflow 总结和 OpenAI Agents SDK 都把 planning 看成一种编排方式,而不是必须塞进 prompt 的固定格式。生产里更常见的是:
| 能力 | 为什么重要 |
|---|---|
| 原子化步骤 | 每一步越小,失败后越容易重试或替换 |
| 显式依赖 | 知道哪一步依赖前一步结果,避免乱并行 |
| Replan 触发条件 | 工具失败、关键事实变化、预算不足时重新规划 |
| Trajectory tracing | 记录计划、执行、重试和最终答案,方便评测 |
| Human approval | 高风险步骤先暂停,让人确认再执行 |
所以,Plan-and-Solve 的重点不是"先写一个漂亮计划",而是让任务结构可见、可检查、可重排。
Plan-and-Solve 适合什么任务?
适合:
- 步骤多但流程明确(如"分别查 A/B/C 三家公司的财报,汇总对比")
- 步骤之间弱依赖——后一步不太依赖前一步的具体结果
- token 预算有限——在步骤清晰时通常比 ReAct 省
不适合:
- 信息收集型("查一下这个 bug 是怎么造成的"——你根本不知道要拆几步)
- 步骤之间强依赖——前一步结果决定后一步该不该做
一种常见的混合架构
工业里经常这样组合:
Planner 拆任务
│
▼
对每个子任务:
- 如果能用工具直接搞定 → 用 Function Calling 一发即中
- 如果是"探索性"的 → 在子任务内部跑一个 ReAct 小循环这就是很多 Coding Agent 的"双层架构"思路——Plan-and-Solve 在外层做 macro 规划,ReAct / tool loop 在内层做 micro 探索。
动手试试
cd labs/03-agent-patterns
python demo_13_plan_and_solve.py跑 5 个测试任务,观察:
- 每个任务 Planner 拆出了几步? 任务 1("查天气推荐景点")和任务 2("算三个商品总价")拆出来的形态会很不同
- Executor 第 i 步用到 i-1 步的结果了吗? 看 system prompt 是怎么把前序结果传给当前步的
- 任务 5("2099 年世界杯") 的 Planner 会拆出哪些步骤?这种问题它本来就拆不出"能干的活"
小结
| 概念 | 一句话理解 |
|---|---|
| Plan-and-Solve | Planner → Executor → Aggregator 三段流水线 |
| 跟 ReAct 比 | 先规划再执行 vs 走一步看一步 |
| Planner 的关键 | 让模型输出结构化 JSON 数组 |
| 痛点 | 计划可能与现实不符,工业版要做 Replan / tracing / eval |
| 适合 | 步骤多但流程明确 / token 预算紧的任务 |
下一节:ReAct 和 Plan-and-Solve 都是先产出答案。如果再加一层审阅与修订,什么时候会更可靠?什么时候只是更贵?→ Reflection。