(单)计划执行智能体 (Plan and Execute Agent)
概述
计划执行智能体(Plan and Execute Agent)是一种采用"先规划,后执行"策略的智能体模型。它将复杂任务分解为两个主要阶段:首先使用语言模型制定详细计划,然后逐步执行这些计划步骤。这种方法特别适合处理需要多步骤推理和工具使用的复杂问题,使整个过程更加结构化和可控。
计划执行智能体的核心思想是将任务分解为更小、更易管理的步骤,然后针对每个步骤使用最适合的工具或方法来解决。这种方法模拟了人类解决复杂问题的方式,先制定策略,再逐步实施。
工作原理
计划执行智能体的工作流程如下:
计划阶段: 智能体分析任务并生成详细的步骤计划
执行阶段: 智能体逐步执行计划中的每个步骤
监控与调整: 在执行过程中监控进度,必要时调整计划
整合结果: 将各步骤的结果整合为最终输出
优势
结构化问题解决: 将复杂问题分解为可管理的步骤
更好的任务分解: 明确区分计划和执行阶段,使每个阶段更专注
减少迭代次数: 通过预先规划减少执行阶段的试错
适应长期任务: 能够处理需要多个步骤才能完成的长期任务
提高可解释性: 通过明确的计划使推理过程更透明
基本用法示例
以下是创建和使用基本计划执行智能体的完整示例:
from langchain_openai import ChatOpenAI
from langchain.agents import load_tools
from langchain.agents.plan_and_execute.agent import PlanAndExecute
from langchain.agents.plan_and_execute.planners.chat_planner import load_chat_planner
from langchain.agents.plan_and_execute.executors.agent_executor import load_agent_executor
# 初始化LLM
model = ChatOpenAI(temperature=0)
# 加载工具
tools = load_tools(["serpapi", "llm-math"], llm=model)
# 加载计划器和执行器
planner = load_chat_planner(model)
executor = load_agent_executor(model, tools, verbose=True)
# 创建计划执行智能体
agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)
# 执行复杂查询
result = agent.invoke({
"input": "今天的日期是多少?2020年美国GDP是多少?如果将美国GDP除以当年人口,人均GDP是多少?"
})
print("最终回答:", result["output"])
高级用法
自定义计划器
from langchain.prompts import PromptTemplate
from langchain.agents.plan_and_execute.planners.base import BasePlanner
from typing import List, Dict, Any
# 自定义计划提示模板
custom_planning_template = """你是一个任务规划专家。给定一个目标,你的任务是制定详细的步骤计划来完成目标。
目标: {input}
请提供一个详细的步骤计划,包括:
1. 每个步骤应该具体且可执行
2. 明确每个步骤可能需要的工具或信息
3. 确保步骤之间有逻辑顺序
4. 计划应该全面,覆盖实现目标的所有必要环节
你的计划:"""
custom_prompt = PromptTemplate.from_template(custom_planning_template)
# 创建自定义计划器类
class CustomPlanner(BasePlanner):
def plan(self, inputs: Dict[str, Any]) -> List[str]:
user_input = inputs["input"]
planning_llm = ChatOpenAI(model="gpt-4", temperature=0) # 使用强大的模型进行规划
# 获取计划
plan_result = planning_llm.predict(custom_prompt.format(input=user_input))
# 将计划分解为步骤列表
steps = []
for line in plan_result.split("\n"):
line = line.strip()
# 过滤出实际步骤(通常以数字开头)
if line and (line[0].isdigit() or line.startswith("- ") or line.startswith("* ")):
# 移除步骤编号或列表符号
cleaned_step = line
for prefix in ["- ", "* ", ". "]:
if ".") > 0:
cleaned_step = line[line.find(".")+1:].strip()
break
elif prefix in line:
cleaned_step = line[line.find(prefix)+len(prefix):].strip()
break
if cleaned_step:
steps.append(cleaned_step)
return steps
# 使用自定义计划器
custom_planner = CustomPlanner()
# 创建带自定义计划器的智能体
custom_plan_agent = PlanAndExecute(
planner=custom_planner,
executor=executor,
verbose=True
)
# 执行复杂查询
result = custom_plan_agent.invoke({
"input": "我需要为一个家庭四口规划为期三天的巴黎旅行,包括景点安排和餐厅推荐。"
})
print("最终回答:", result["output"])
自定义执行器
from langchain.agents import create_react_agent, AgentExecutor
from langchain.agents.plan_and_execute.executors.base import BaseExecutor
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
class CustomExecutor(BaseExecutor):
"""一个自定义的步骤执行器,使用ReAct智能体来执行每个步骤。"""
def __init__(self, llm, tools, verbose=False):
# 创建用于执行的ReAct智能体
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个执行专家,负责精确执行给定的任务步骤。\
你有权访问以下工具来帮助完成任务:{tools}\
专注于当前步骤,确保完全完成它,而不是考虑其他步骤。"),
("human", "需要执行的步骤: {step}\n当前状态: {context}"),
MessagesPlaceholder(variable_name="agent_scratchpad")
])
agent = create_react_agent(llm, tools, prompt)
self.agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=verbose)
def execute_step(self, step: str, context: list, **kwargs) -> str:
# 将上下文转换为字符串
context_str = "\n".join([f"- {s}: {r}" for s, r in context])
if not context_str:
context_str = "这是第一个步骤,尚无前序结果。"
# 执行当前步骤
result = self.agent_executor.invoke({
"step": step,
"context": context_str
})
return result["output"]
# 创建自定义执行器实例
custom_executor = CustomExecutor(
llm=ChatOpenAI(model="gpt-3.5-turbo", temperature=0),
tools=tools,
verbose=True
)
# 创建带自定义执行器的智能体
custom_execution_agent = PlanAndExecute(
planner=planner,
executor=custom_executor,
verbose=True
)
复杂任务处理
from langchain.tools import WikipediaQueryRun, YouTubeSearchTool
from langchain_community.utilities import WikipediaAPIWrapper
# 创建更多样的工具集
complex_tools = load_tools(["serpapi", "llm-math"], llm=model)
complex_tools.extend([
WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper()),
YouTubeSearchTool(),
])
# 创建用于复杂任务的智能体
complex_task_agent = PlanAndExecute(
planner=load_chat_planner(ChatOpenAI(model="gpt-4", temperature=0)), # 使用更强大的模型进行规划
executor=load_agent_executor(
ChatOpenAI(model="gpt-3.5-turbo-16k", temperature=0), # 使用更大上下文窗口的模型执行
complex_tools,
verbose=True
),
verbose=True
)
# 处理复杂研究任务
complex_task = """
我需要研究人工光合作用技术的最新进展,并撰写一份简短的研究摘要,要求:
1. 确定该领域最新的科学突破
2. 比较不同研究团队的方法
3. 分析其潜在的环境影响和能源应用
4. 计算如果这项技术达到自然光合作用30%的效率,每平方米每天可以产生多少能量(假设平均每平方米太阳辐射量为5kWh/天)
"""
result = complex_task_agent.invoke({"input": complex_task})
print("研究摘要:\n", result["output"])
实际应用场景
1. 旅行规划助手
from langchain.memory import ConversationBufferMemory
from langchain.agents.plan_and_execute.planners.chat_planner import load_chat_planner
from langchain.agents.plan_and_execute.executors.agent_executor import AgentExecutor
from langchain.tools import tool
# 创建旅行相关工具
@tool
def search_attractions(location: str) -> str:
"""搜索特定位置的旅游景点"""
# 实际应用中连接到旅游API或搜索引擎
return f"在{location}找到的热门景点:卢浮宫、埃菲尔铁塔、凯旋门、圣母院、蒙马特高地"
@tool
def search_restaurants(location: str, cuisine: str = "local") -> str:
"""在特定位置搜索餐厅,可以指定菜系"""
# 实际应用中连接到餐厅数据库
if cuisine == "local" or cuisine == "法国":
return f"在{location}找到的法国餐厅:Le Jules Verne、L'Ambroisie、Le Cinq"
else:
return f"在{location}找到的{cuisine}餐厅:相关餐厅列表"
@tool
def check_weather(location: str, date: str) -> str:
"""查询特定位置特定日期的天气预报"""
# 实际应用中连接到天气API
return f"{location}在{date}的天气预报:晴朗,温度18-25°C")
@tool
def find_hotels(location: str, check_in: str, check_out: str, guests: int = 2) -> str:
"""在特定位置寻找酒店"""
# 实际应用中连接到酒店预订系统
return f"在{location}找到的酒店,入住日期{check_in},离店日期{check_out},{guests}位客人:
- Grand Hotel Paris:4星级,¥1200/晚
- Boutique Marais:3星级,¥800/晚
- Luxury Seine View:5星级,¥2000/晚"
# 组合旅行工具
travel_tools = [search_attractions, search_restaurants, check_weather, find_hotels]
# 创建旅行规划智能体
travel_planner = PlanAndExecute(
planner=load_chat_planner(ChatOpenAI(model="gpt-4", temperature=0.1)),
executor=load_agent_executor(
ChatOpenAI(model="gpt-3.5-turbo", temperature=0.2),
travel_tools,
verbose=True
),
verbose=True
)
# 处理旅行规划请求
travel_request = "我计划下个月带家人去巴黎旅游3天,需要一个包括景点、酒店和餐厅的详细行程安排。我们是2个大人和2个孩子(7岁和10岁)。"
travel_plan = travel_planner.invoke({"input": travel_request})
print("旅行计划:\n", travel_plan["output"])
2. 研究与报告生成
from langchain.tools import tool
from datetime import datetime
@tool
def search_academic_papers(query: str, max_results: int = 5) -> str:
"""搜索学术论文"""
# 实际应用中连接到学术数据库
return f"关于'{query}'的论文搜索结果(最新5篇):\n各种论文标题和简短摘要"
@tool
def analyze_trends(topic: str) -> str:
"""分析特定主题的研究趋势"""
# 实际应用中连接到趋势分析API
return f"'{topic}'的研究趋势:该领域近年来发表论文数量增长了30%,主要关注点包括..."
@tool
def generate_chart(data_description: str) -> str:
"""根据描述生成图表(返回图表描述)"""
# 实际应用中会生成实际图表或图表代码
return f"已根据'{data_description}'生成图表,显示了主要趋势和数据分布"
# 创建研究工具集
research_tools = [search_academic_papers, analyze_trends, generate_chart]
research_tools.extend([WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())])
# 创建研究与报告智能体
research_agent = PlanAndExecute(
planner=load_chat_planner(ChatOpenAI(model="gpt-4", temperature=0)),
executor=load_agent_executor(
ChatOpenAI(model="gpt-3.5-turbo-16k", temperature=0.1),
research_tools,
verbose=True
),
verbose=True
)
# 处理研究请求
research_request = """为我准备一份关于量子计算近五年发展的简短研究报告,包括:
1. 主要技术突破
2. 领先研究机构
3. 潜在商业应用
4. 未来五年的发展趋势预测
请包含一个关于研究论文发表趋势的图表描述。
"""
research_report = research_agent.invoke({"input": research_request})
print(f"研究报告(生成于{datetime.now().strftime('%Y-%m-%d')}):\n", research_report["output"])
最佳实践
任务分解策略:指导智能体如何最有效地分解复杂任务。
# 在计划提示中指导任务分解 planning_template = """将复杂任务分解为以下几类步骤: 1. 信息收集步骤:获取必要数据和上下文 2. 分析步骤:处理和分析收集的信息 3. 创建步骤:生成新内容或解决方案 4. 验证步骤:检查结果是否满足要求 任务: {input} 详细步骤计划:"""
步骤依赖管理:确保步骤之间的逻辑顺序和依赖关系。
# 为执行器提供上下文管理 class ContextAwareExecutor(BaseExecutor): def execute_step(self, step: str, context: list, **kwargs) -> str: # 分析当前步骤需要哪些前序步骤的结果 required_context = self._identify_dependencies(step, context) context_str = self._format_context(required_context) # 执行步骤并返回结果 # ...
错误恢复机制:实现步骤失败后的恢复策略。
# 在执行器中添加错误处理 try: step_result = self.agent_executor.invoke({"step": step, "context": context_str}) return step_result["output"] except Exception as e: # 尝试重新规划或采用备选方案 recovery_result = self._handle_step_failure(step, context, e) return f"原始步骤执行失败,已采用替代方案。结果: {recovery_result}"
提供足够上下文:确保每个步骤都有足够的前序信息。
选择合适的模型:规划阶段使用强大的模型(如GPT-4),执行阶段可以使用更轻量级的模型。
限制步骤数量:将复杂任务分解为5-7个步骤,避免过度分解或步骤过少。
步骤结果验证:在执行阶段实现结果验证机制,确保每个步骤都产生有用输出。
与其他智能体类型的对比
常见问题与解决方案
计划过于笼统
解决方案:改进计划提示,要求更具体的步骤
实施计划评估机制,在执行前评估计划质量
执行偏离计划
解决方案:加强执行器对计划的遵循
实现计划-执行对齐检查
步骤间上下文丢失
解决方案:改进上下文传递机制
实现更完善的步骤依赖管理
处理计划失效
解决方案:实现动态重新规划功能
允许执行器在必要时请求计划修正
总结
计划执行智能体通过将复杂任务分解为计划和执行两个独立阶段,提供了一种结构化的问题解决方法。这种方法特别适合处理需要多步骤、多工具协作的复杂任务,如研究报告生成、旅行规划或项目管理。
计划执行智能体的主要优势在于其对任务的明确分解和结构化处理,使得即使是非常复杂的任务也能被分解为可管理的步骤。通过分离计划和执行阶段,这种智能体还提高了推理过程的透明度和可靠性。
对于需要处理复杂、多步骤任务的应用场景,计划执行智能体提供了比传统智能体更强大和可靠的解决方案。通过遵循本文档中的最佳实践和实施建议,开发者可以充分利用这种智能体模型的优势,构建高效、可靠的智能系统。
- 感谢你赐予我前进的力量