Planner-Executor架构
核对日期:2026-05-09。
1. 定义与边界
Planner-Executor 架构将“制定计划”和“执行步骤”拆成两个角色:
- Planner:理解目标、拆分步骤、声明依赖、设定完成标准。
- Executor:按步骤调用工具、收集结果、汇报状态。
它不等于 Tree-of-Thoughts。Planner-Executor 更偏系统架构;ToT 是搜索式推理策略,可作为 Planner 的内部算法之一。
2. 为什么重要
单 Agent 在长任务中容易边做边忘、局部最优、重复工具调用。显式计划可以提升可审计性,让系统在执行前检查权限、成本、风险和依赖。
适用:
- 编码修改、研究报告、数据迁移、复杂客服处理。
- 执行前需要展示计划供用户审批。
- 子任务间存在依赖、回滚或验收标准。
不适用:
- 简单一次性问答。
- 计划在每一步都会剧烈变化的探索任务。
- 工具结果不可预测到无法预先拆分。
3. 核心机制
计划对象示例:
{
"goal": "生成供应商风险分析报告",
"steps": [
{
"id": "s1",
"description": "读取供应商合同与历史采购数据",
"depends_on": [],
"tools_allowed": ["file_search", "sql_read"],
"done_when": "合同和采购摘要已形成结构化 facts"
}
],
"risk_level": "medium",
"requires_approval_before": ["external_email", "database_write"]
}
4. 架构模式
| 模式 | 描述 | 优点 | 风险 |
|---|---|---|---|
| Static plan | 一次生成完整计划后执行 | 可审计、易审批 | 工具反馈后不适配 |
| Replan loop | 每步后判断是否重规划 | 更稳健 | 成本和时延高 |
| Hierarchical plan | 粗计划下挂子计划 | 支持大任务 | 状态复杂 |
| Plan + workflow | 计划经代码状态机执行 | 可控性强 | 灵活度下降 |
5. 工程实现
Planner 输出必须结构化,不要让 Executor 从自然语言段落里解析步骤。
class Step:
id: str
instruction: str
depends_on: list[str]
allowed_tools: list[str]
done_when: str
status: str = "pending"
def run_plan(goal):
plan = planner.generate(goal, output_schema=Plan)
validate_plan(plan)
for step in topo_sort(plan.steps):
if step_requires_approval(step):
human_approve(step)
result = executor.run(step)
if not judge_done(step.done_when, result):
plan = planner.replan(goal, plan, failed_step=step, observation=result)
return synthesize(plan)
工程约束:
- Planner 只能生成计划,不直接调用高风险工具。
- Executor 只能执行当前步骤允许的工具。
- 每个步骤有
done_when,避免“做一点就算完成”。 - 重规划要带上失败原因、已完成步骤、不可重复副作用。
- 计划版本化:
plan_version、parent_plan_id、replan_reason。
6. 生产实践
- 在计划执行前做静态检查:权限、成本、预计时长、外部系统影响。
- 对长计划设置里程碑,而不是一次执行 50 步。
- 对写操作添加 preview/commit 两阶段。
- 对执行结果使用 verifier,而不是只让执行器自报成功。
- 将计划与 trace 绑定,支持事后审计“为什么调用这个工具”。
7. 常见反模式
- Planner 生成空泛步骤:“分析问题”“执行任务”“总结结果”。
- Executor 自己改计划,导致计划审计失效。
- 每一步都重规划,成本高且行为漂移。
- done_when 不可验证,例如“确保质量很好”。
- 把计划暴露给不可信网页或工具返回改写。
8. 评测方法
- Plan Validity:步骤是否覆盖目标、顺序是否合理、依赖是否完整。
- Execution Fidelity:Executor 是否严格按当前步骤与工具权限执行。
- Replan Quality:失败后是否保留已完成事实并避免重复副作用。
- End-to-end Success:最终交付是否满足用户验收标准。
- Cost/Latency:显式规划带来的额外成本是否换来成功率提升。
9. 安全与治理
- Planner 不应授予自己新权限;权限来自策略层。
- 计划中出现外发、删除、支付、生产变更时强制人工审批。
- 防止间接 prompt injection 改写计划:外部内容只能作为 facts,不作为指令。
- 对重规划次数设上限,避免被恶意输入拖入无限执行。
10. 工程手册补充
10.1 控制流、状态流、工具流
| 流 | 设计要点 | 必须落库的字段 |
|---|---|---|
| 控制流 | Planner 产出候选计划,Policy 校验后 Executor 逐步执行;失败后只能通过 replan 或 abort 改变路径 | run_id、plan_id、plan_version、step_id、transition |
| 状态流 | 每步读写统一 PlanState,不得把完成状态只藏在对话文本里 | step_status、artifacts、facts、blocked_reason |
| 工具流 | Executor 只拿到当前步骤白名单工具;写操作必须 preview/commit 分离 | tool_name、tool_args_hash、permission_scope、side_effect |
| 观测流 | 每次计划、执行、评审、重规划都产生日志事件 | event_type、latency_ms、cost、model、verdict |
10.2 失败恢复策略
| 失败类型 | 识别信号 | 恢复动作 |
|---|---|---|
| 计划不可执行 | 缺少输入、循环依赖、工具不存在 | 停在 validation,要求澄清或重新规划 |
| 执行失败 | 工具超时、权限拒绝、测试失败 | 标记 step failed,保留 artifacts,进入局部 replan |
| 计划漂移 | 新计划丢失原始约束或越过审批 | 回滚到上一版计划,强制人工确认 |
| 副作用不一致 | 写操作部分成功、外部系统状态未知 | 进入 reconciliation 步骤,不允许继续下游步骤 |
上线清单:
- 计划 schema 有版本号、父版本、变更原因和不可重复副作用清单。
- 每个步骤都有
done_when、allowed_tools、rollback_hint。 - 评测集同时覆盖“正常完成、工具失败、重规划、用户改需求、权限拒绝”。
- 生产监控至少看成功率、平均重规划次数、计划漂移率、人工审批命中率、单位成功成本。
- 高风险工具默认只允许 Executor 触发,且必须带上当前
step_id和审批令牌。
11. 权威资料
- Anthropic, Building effective agents: https://www.anthropic.com/engineering/building-effective-agents
- Plan-and-Solve Prompting: https://arxiv.org/abs/2305.04091
- ReAct paper: https://arxiv.org/abs/2210.03629
- LangGraph graph API: https://docs.langchain.com/oss/python/langgraph/graph-api
- LangGraph durable execution: https://docs.langchain.com/oss/python/langgraph/durable-execution
- OpenAI Agents SDK tracing: https://openai.github.io/openai-agents-python/tracing/