Plan-and-Execute(计划与执行)模式
概述
Plan-and-Execute 模式将 Agent 的工作流程分为两个清晰阶段:先制定完整计划,再逐步执行。这种模式模仿人类解决复杂问题的方式——先想清楚整体方案,再动手实施。
原理
flowchart TD
subgraph Phase1["Phase 1: Planning(计划)"]
分析问题 --> 分解子任务 --> 生成计划
end
subgraph Phase2["Phase 2: Execution(执行)"]
步骤1["执行步骤 1"] --> 步骤2["执行步骤 2"] --> 步骤N["... → 步骤 N"]
end
subgraph Phase3["Phase 3: Aggregation(汇总,可选)"]
汇总结果 --> 最终答案["生成最终答案"]
end
Phase1 --> Phase2
Phase2 --> Phase3
- Planning(计划阶段):Agent 将复杂任务分解为多个可独立执行的子任务,生成结构化的步骤列表
- Execution(执行阶段):Agent 按照计划顺序执行每个步骤,每个步骤可能是一个 ReAct 循环
- Aggregation(汇总阶段):将各步骤的结果整合为最终输出
关键设计在于计划与执行的解耦,计划器不需要知道执行细节,执行器专注于完成单个子任务。
使用场景
- 复杂多步任务:需要 5 个以上步骤才能完成的复杂任务(如 "写一篇关于 AI Agent 的综述博客")
- 代码生成项目:从需求分析、架构设计到编码实现的多阶段开发任务
- 数据分析报告:数据收集→清洗→分析→可视化→撰写报告
- 研究调研:需要在多个维度收集信息并整合的场景
- 可并行的子任务:步骤之间无依赖关系时,可并行执行加速
示例代码
import json
from typing import List, Dict, Optional
from dataclasses import dataclass, field
@dataclass
class Plan:
"""计划数据结构"""
goal: str
steps: List[str] = field(default_factory=list)
current_step: int = 0
results: Dict[int, str] = field(default_factory=dict)
class PlanAndExecuteAgent:
"""Plan-and-Execute 模式 Agent"""
def __init__(self, planner_llm, executor_llm, tools: Dict[str, callable]):
"""
Args:
planner_llm: 用于制定计划的 LLM
executor_llm: 用于执行步骤的 LLM(可与 planner 相同)
tools: 可用工具集
"""
self.planner = planner_llm
self.executor = executor_llm
self.tools = tools
def run(self, task: str, max_replan: int = 2) -> str:
"""
执行 Plan-and-Execute 流程
"""
# Phase 1: 制定计划
plan = self._create_plan(task)
print(f"[Plan] 目标: {plan.goal}")
for i, step in enumerate(plan.steps):
print(f" Step {i+1}: {step}")
# Phase 2: 逐步执行
for replan_count in range(max_replan + 1):
while plan.current_step < len(plan.steps):
step_desc = plan.steps[plan.current_step]
print(f"\n[Execute] Step {plan.current_step + 1}: {step_desc}")
# 构建执行上下文(包含已完成的步骤结果)
context = self._build_context(plan)
# 执行当前步骤(使用 ReAct 或直接推理)
step_result = self._execute_step(step_desc, context)
plan.results[plan.current_step] = step_result
plan.current_step += 1
# Phase 3: 评估结果,决定是否需要重新规划
if self._is_complete(plan):
break
if replan_count < max_replan:
print(f"\n[Replan] 当前结果不满足要求,重新规划...")
plan = self._replan(task, plan)
# 汇总结果
return self._aggregate(task, plan)
def _create_plan(self, task: str) -> Plan:
"""Phase 1: 生成执行计划"""
prompt = f"""你需要为以下任务制定详细的执行计划。
任务:{task}
请将任务分解为清晰的步骤序列,每个步骤应:
1. 单一职责,只完成一个明确目标
2. 可独立执行
3. 步骤间尽量解耦
以 JSON 格式返回计划:
{{
"goal": "任务目标",
"steps": [
"步骤1:具体描述",
"步骤2:具体描述",
...
]
}}
"""
response = self.planner.generate(prompt)
plan_data = json.loads(response)
return Plan(
goal=plan_data["goal"],
steps=plan_data["steps"]
)
def _build_context(self, plan: Plan) -> str:
"""构建步骤执行的上下文"""
if not plan.results:
return "这是第一个步骤,无前置结果。"
context_parts = ["已完成步骤的结果:"]
for step_idx, result in plan.results.items():
context_parts.append(
f"- Step {step_idx + 1}({plan.steps[step_idx]}): {result}"
)
return "\n".join(context_parts)
def _execute_step(self, step_desc: str, context: str) -> str:
"""执行单个步骤"""
prompt = f"""执行以下子任务。你可以使用提供的工具。
子任务:{step_desc}
前置上下文:
{context}
请完成该子任务并返回结果。只返回该步骤的结果,不要做额外的事情。
"""
return self.executor.generate(prompt)
def _is_complete(self, plan: Plan) -> bool:
"""检查任务是否完成"""
# 简单判断:所有步骤执行完
return plan.current_step >= len(plan.steps)
def _replan(self, task: str, previous_plan: Plan) -> Plan:
"""根据执行情况重新规划"""
prompt = f"""任务未完成,需要调整计划。
原始任务:{task}
原始计划:{previous_plan.steps}
已完成步骤及结果:{json.dumps(previous_plan.results, ensure_ascii=False)}
请制定新的执行计划(JSON 格式),重点关注未完成的部分。
"""
response = self.planner.generate(prompt)
plan_data = json.loads(response)
new_plan = Plan(goal=plan_data["goal"], steps=plan_data["steps"])
# 保留之前的结果作为上下文
new_plan.results = previous_plan.results
return new_plan
def _aggregate(self, task: str, plan: Plan) -> str:
"""汇总所有步骤结果"""
summary_prompt = f"""原始任务:{task}
各步骤执行结果:
{json.dumps(plan.results, ensure_ascii=False, indent=2)}
请整合以上所有结果,生成最终答案。
"""
return self.planner.generate(summary_prompt)
# ========== 使用示例 ==========
agent = PlanAndExecuteAgent(
planner_llm=YourLLM(),
executor_llm=YourLLM(),
tools={
"search": search_function,
"calculate": calc_function,
}
)
# 执行复杂任务
result = agent.run(
"写一篇 500 字的文章,比较 GPT-4、Claude 和 Gemini 三个模型在编程能力上的优劣"
)
print("\n" + "="*50)
print(result)
并行执行优化
import concurrent.futures
class ParallelPlanAndExecuteAgent(PlanAndExecuteAgent):
"""支持并行步骤执行的 Plan-and-Execute Agent"""
def _execute_parallel_steps(self, steps: List[str], context: str) -> Dict[int, str]:
"""并行执行多个独立的步骤"""
results = {}
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
future_to_step = {
executor.submit(self._execute_step, step, context): idx
for idx, step in enumerate(steps)
}
for future in concurrent.futures.as_completed(future_to_step):
idx = future_to_step[future]
results[idx] = future.result()
return results
计划生成示例
任务:分析一个 Python 项目的代码质量并生成改进报告
生成计划:
Step 1: 扫描项目结构,统计文件数量和代码行数
Step 2: 运行 linter 工具,收集代码风格问题
Step 3: 分析函数复杂度(圈复杂度 > 10 的函数)
Step 4: 检查测试覆盖率
Step 5: 识别代码重复 (DRY 违反)
Step 6: 汇总以上发现,按优先级排序生成改进建议
Step 7: 生成 Markdown 格式的改进报告
优点与局限
| 优点 | 局限 |
|---|---|
| 计划清晰,执行过程可追踪 | 初始计划可能不准确,需要重规划 |
| 步骤间解耦,便于并行执行 | 对于需要动态决策的任务不够灵活 |
| 减少 LLM 调用时的上下文压力 | 增加了额外的 LLM 调用开销 |
| 适合长周期、跨领域的复杂任务 | 计划粒度过粗或过细都影响效果 |
变体
- Hierarchical Planning:计划中的步骤本身也可以是子计划
- Adaptive Planning:每个步骤执行后评估是否需要调整后续计划
- Plan + ReAct:规划阶段用 Plan-and-Execute,单个步骤用 ReAct 执行
评论
评论加载中…