系列目标 :30 天从 LangChain 入门到企业级部署
今日任务:理解 Plan-and-Execute 架构 → 实现自定义 Planner/Executor → 构建"自动写周报"智能体!
🧠 一、为什么需要 Plan-and-Execute?
ReAct Agent(Day 23)虽强,但面对复杂任务仍显不足:
用户问:"帮我写一份上周的工作周报,包含项目进展、遇到的问题和下周计划。"
ReAct 可能:
- ❌ 直接编造内容(无真实数据)
- ❌ 顺序混乱(先写计划再查进展?)
- ❌ 遗漏关键步骤
根本问题 :缺乏全局规划能力。
解决方案:
✅ Plan-and-Execute Agent ------ 将任务拆解为 Plan(计划) + Execute(执行) 两阶段!
💡 今天,我们就用 LangChain 的PlanAndExecute框架,打造一个会"先列大纲,再填内容"的 AI 助手!
🏗️ 二、Plan-and-Execute 架构原理
css
用户输入
↓
[Planner] → 生成结构化任务列表(如:1. 查项目A进度;2. 查Bug列表;3. 生成周报)
↓
[Executor] → 逐项调用 Tool 执行,并汇总结果
↓
最终输出
优势:
- ✅ 任务分解清晰,避免遗漏
- ✅ 支持并行/串行混合执行(未来扩展)
- ✅ 可审查中间计划(提升可控性)
🔑 核心组件:
Plan:由 LLM 生成的List[Step]StepExecutor:执行单个步骤的 Agent(可复用 Day 23 的 ReAct)
🛠️ 三、动手实践:构建"自动写周报"Agent
步骤 1:准备模拟数据源(Tool)
python
# day24_plan_and_execute.py
from langchain_core.tools import tool
@tool
def get_project_status(project_name: str) -> str:
"""获取项目最新进展"""
return {
"AI平台": "完成RAG模块开发,准确率提升至92%",
"数据中台": "ETL流程优化,延迟降低40%"
}.get(project_name, "项目未找到")
@tool
def get_recent_bugs() -> str:
"""获取最近3天的高优先级Bug"""
return "1. 用户登录偶发500错误;2. PDF导出格式错乱"
@tool
def get_upcoming_tasks() -> str:
"""获取下周计划任务"""
return "1. 上线RAG问答系统;2. 修复PDF导出问题"
步骤 2:初始化基础 LLM 和 ReAct Executor
ini
from langchain_ollama import ChatOllama
from langchain.agents import create_react_agent, AgentExecutor
from langchain import hub
llm = ChatOllama(model="qwen:7b", temperature=0)
# 创建底层执行器(用于执行每个步骤)
react_prompt = hub.pull("hwchase17/react")
react_agent = create_react_agent(llm, [get_project_status, get_recent_bugs, get_upcoming_tasks], react_prompt)
step_executor = AgentExecutor(agent=react_agent, tools=[...], verbose=False)
步骤 3:定义 Planner(计划生成器)
python
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
planner_prompt = ChatPromptTemplate.from_template(
"""
你是一个任务规划专家。请将以下目标拆解为一系列具体的、可执行的步骤。
每个步骤应明确调用哪个工具(如 get_project_status),并指定参数。
仅输出步骤列表,每行以数字开头,不要解释。
目标:{input}
步骤:
"""
)
planner_chain = planner_prompt | llm | StrOutputParser()
✅ 输出示例:
scss1. 调用 get_project_status(project_name="AI平台") 2. 调用 get_project_status(project_name="数据中台") 3. 调用 get_recent_bugs() 4. 调用 get_upcoming_tasks()
步骤 4:实现 Plan-and-Execute 主逻辑
python
import re
def parse_plan(plan_text: str):
"""解析计划文本为步骤列表"""
steps = []
for line in plan_text.strip().split("\n"):
if line.strip().startswith(("1.", "2.", "3.", "4.", "5.")):
steps.append(line.split(". ", 1)[1])
return steps
def execute_plan(steps: list) -> dict:
"""执行计划,返回每步结果"""
results = {}
for i, step in enumerate(steps):
try:
# 提取工具名和参数(简化版,生产可用 AST 解析)
if "get_project_status" in step:
proj = re.search(r'project_name="([^"]+)"', step).group(1)
res = get_project_status(proj)
elif "get_recent_bugs" in step:
res = get_recent_bugs()
elif "get_upcoming_tasks" in step:
res = get_upcoming_tasks()
else:
res = "未知步骤"
results[f"step_{i+1}"] = res
except Exception as e:
results[f"step_{i+1}"] = f"执行失败: {str(e)}"
return results
def generate_final_report(results: dict) -> str:
"""整合结果生成周报"""
report = "【上周工作周报】\n\n"
report += "一、项目进展\n"
report += "- AI平台: " + results.get("step_1", "") + "\n"
report += "- 数据中台: " + results.get("step_2", "") + "\n\n"
report += "二、遇到的问题\n"
report += results.get("step_3", "") + "\n\n"
report += "三、下周计划\n"
report += results.get("step_4", "")
return report
步骤 5:端到端运行
ini
def plan_and_execute(input_query: str) -> str:
# 1. 生成计划
plan_text = planner_chain.invoke({"input": input_query})
print("📋 AI 制定的计划:\n", plan_text)
# 2. 解析并执行
steps = parse_plan(plan_text)
results = execute_plan(steps)
# 3. 生成最终报告
return generate_final_report(results)
# 测试
query = "帮我写一份上周的工作周报,包含AI平台和数据中台的进展、最近的Bug、下周计划"
final_output = plan_and_execute(query)
print("\n📄 最终周报:\n", final_output)
▶️ 输出效果:
scss
📋 AI 制定的计划:
1. 调用 get_project_status(project_name="AI平台")
2. 调用 get_project_status(project_name="数据中台")
3. 调用 get_recent_bugs()
4. 调用 get_upcoming_tasks()
📄 最终周报:
【上周工作周报】
一、项目进展
- AI平台: 完成RAG模块开发,准确率提升至92%
- 数据中台: ETL流程优化,延迟降低40%
二、遇到的问题
1. 用户登录偶发500错误;2. PDF导出格式错乱
三、下周计划
1. 上线RAG问答系统;2. 修复PDF导出问题
✅ 完美实现:
- 自动拆解复杂任务
- 精准调用所需工具
- 结构化输出专业文档
⚙️ 四、进阶:使用 LangChain 内置 PlanAndExecute(实验性)
LangChain 提供了实验性支持(需 langchain-experimental):
pip install langchain-experimental
ini
from langchain_experimental.plan_and_execute import (
PlanAndExecute,
load_agent_executor,
load_chat_planner
)
planner = load_chat_planner(llm)
executor = load_agent_executor(llm, [tools], verbose=True)
agent = PlanAndExecute(planner=planner, executor=executor)
result = agent.run("写周报...")
⚠️ 注意:该模块仍在演进,自定义实现更可控(如上文)。
⚠️ 五、注意事项 & 最佳实践
表格
| 问题 | 建议 |
|---|---|
| 计划不完整 | 在 Planner Prompt 中提供示例(Few-shot) |
| 步骤无法执行 | Executor 加强错误处理;支持重试 |
| 结果整合生硬 | 用单独 LLM 调用生成最终报告(更自然) |
| Token 超限 | 对超长计划分批执行 |
| 安全风险 | 所有 Tool 调用需权限校验 |
💡 生产建议:
- 允许用户审核/修改 AI 生成的计划
- 记录完整 Plan-Execute 日志用于复盘
- 对高频任务模板化(如"周报""月报")
📦 六、配套代码结构
bash
langchain-30-days/
└── day24/
└── plan_and_execute_weekly_report.py # 自动周报生成器
📝 七、今日小结
- ✅ 理解了 Plan-and-Execute 的两阶段架构优势
- ✅ 学会了自定义 Planner 生成结构化任务列表
- ✅ 实现了步骤解析与工具调用的执行引擎
- ✅ 构建了端到端的"自动写周报"智能体
- ✅ 知道了如何平衡自动化与人工干预
🎯 明日预告:Day 25 ------ 向量数据库进阶!Milvus/PGVector 生产级部署与性能调优!