1. 为什么我们需要Agent执行计划?
在当今大模型开发领域,Agent执行计划正成为开发者必须掌握的核心技能。想象一下,你正在构建一个智能客服系统,当用户提出"我想订一张明天从北京到上海的高铁票"这样的复杂请求时,系统需要自动分解为查询余票、选择车次、填写乘客信息、完成支付等一系列子任务——这正是Agent执行计划的典型应用场景。
Agent执行计划本质上是大模型"思考过程"的结构化呈现。与传统的单次问答不同,它使大模型能够像人类一样进行多步推理和任务分解。我曾在实际项目中遇到过这样的情况:一个简单的订单查询功能,在没有执行计划的情况下,大模型会直接返回"无法完成此操作";而引入执行计划后,模型能够自动拆解为身份验证、订单检索、结果格式化三个步骤,成功率提升了近70%。
当前主流的大模型开发框架(如LangChain、AutoGPT等)都深度集成了执行计划功能。以LangChain为例,其Plan-and-Execute架构允许开发者通过以下方式控制模型行为:
- 任务分解(Task Decomposition):将复杂问题拆解为可执行的子任务
- 工具调用(Tool Use):为每个子任务选择适当的API或函数
- 状态跟踪(State Tracking):维护执行上下文和中间结果
- 异常处理(Error Recovery):在步骤失败时尝试替代方案
提示:执行计划不是银弹。在简单问答场景中引入复杂计划反而会增加延迟和成本。根据我的经验,当任务满足以下任一条件时才需要考虑执行计划:1) 需要调用外部工具/API 2) 包含超过3个逻辑步骤 3) 需要维护对话状态。
2. Agent执行计划的核心组件解析
2.1 计划生成器(Planner)
计划生成器是执行计划的大脑,负责将用户输入转化为可执行的任务序列。目前主要有三种实现方式:
- LLM直接生成:通过Prompt工程让大模型输出步骤
python复制# 示例:使用GPT-4生成旅行规划
prompt = """
请将以下请求分解为具体步骤:
用户请求:计划一次为期3天的北京文化之旅
要求:包含交通、住宿、景点三个维度
"""
优点:灵活度高,适合开放域任务
缺点:结果不可控,可能需要多次调试Prompt
- 模板匹配:预定义常见任务的流程模板
json复制{
"电商售后流程": [
"验证订单信息",
"确认问题类型",
"提供解决方案",
"记录服务工单"
]
}
优点:执行稳定,响应快
缺点:扩展性差,需维护模板库
- 混合方法:结合LLM创意性和规则约束
python复制def generate_plan(user_input):
# 先用分类器确定领域
domain = classifier.predict(user_input)
# 加载该领域的基础模板
template = load_template(domain)
# 用LLM填充模板细节
return llm.fill_template(template, user_input)
2.2 执行引擎(Executor)
执行引擎负责按计划逐步调用工具并处理结果。关键设计考量包括:
- 并发控制:并行执行独立步骤(如同时查询天气和机票)
python复制with ThreadPoolExecutor() as executor:
futures = {
"weather": executor.submit(get_weather, destination),
"flights": executor.submit(search_flights, dates)
}
results = {k: f.result() for k, f in futures.items()}
-
错误处理:我建议实现三级回退机制:
- 重试当前工具(瞬时错误)
- 尝试替代工具(如Google搜索代替特定API)
- 请求人工干预或返回部分结果
-
上下文管理:维护跨步骤的共享变量
python复制class ExecutionContext:
def __init__(self):
self._storage = {}
def set(self, key, value):
self._storage[key] = value
def get(self, key, default=None):
return self._storage.get(key, default)
2.3 监督模块(Monitor)
监督模块常被新手忽视,却是生产环境稳定的关键。它需要实现:
- 成本控制:记录各步骤的token消耗
python复制def track_cost(step_name, input_tokens, output_tokens):
cost = (input_tokens * 0.0015 + output_tokens * 0.002) / 1000 # GPT-4定价
redis_client.hincrby("usage:monthly", step_name, int(cost*100))
-
性能指标:
- 步骤耗时百分位图(P50/P95/P99)
- 工具调用成功率
- 计划完成率
-
异常检测:
- 突然增加的失败率
- 异常输出模式(如重复内容)
- 敏感信息泄露(自动过滤身份证号等)
3. 实战:构建机票预订Agent
3.1 环境准备
推荐使用以下技术栈:
- 开发框架:LangChain 0.1+
- 大模型:GPT-4 Turbo(API版本)
- 工具服务:
- 航班API(如Skyscanner)
- 支付网关(Stripe测试环境)
- 邮件服务(SendGrid)
bash复制# 最小化依赖安装
pip install langchain openai requests python-dotenv
3.2 核心实现
步骤1:定义工具集
python复制from langchain.tools import tool
from datetime import datetime
@tool
def search_flights(departure: str, destination: str, date: str):
"""查询可用航班"""
# 调用真实API时建议添加重试和缓存
mock_data = [
{"flight_no": "CA123", "dep_time": "08:00", "price": 680},
{"flight_no": "MU456", "dep_time": "12:30", "price": 720}
]
return sorted(mock_data, key=lambda x: x["price"])
@tool
def book_flight(flight_no: str, passenger_info: dict):
"""预订指定航班"""
return {
"confirmation_no": f"BK{datetime.now().timestamp()}",
"total_charge": passenger_info.get("seat_class", "economy") == "business" and 1200 or 600
}
步骤2:创建Planner
python复制from langchain.chat_models import ChatOpenAI
from langchain_experimental.plan_and_execute import PlanAndExecute, load_agent_executor
llm = ChatOpenAI(model="gpt-4-1106-preview", temperature=0)
planner = load_chat_planner(llm)
executor = load_agent_executor(llm, tools, verbose=True)
agent = PlanAndExecute(planner=planner, executor=executor)
步骤3:执行测试
python复制result = agent.run(
"帮我订明天北京到上海最便宜的航班,乘客张三经济舱"
)
print(result)
3.3 常见问题排查
问题1:工具选择错误
症状:Planner选择了不合适的工具(如用搜索代替预订)
解决方案:
- 在工具描述中添加明确边界
python复制@tool(return_direct=True)
def search_flights(...):
"""【仅查询】返回可用航班列表,不执行预订"""
问题2:参数格式错误
症状:Executor传递了错误的参数类型
解决方案:
- 添加输入验证
python复制def book_flight(flight_no: str, passenger_info: dict):
assert isinstance(passenger_info, dict), "乘客信息必须是字典"
assert "name" in passenger_info, "必须包含name字段"
问题3:循环执行
症状:步骤陷入无限循环
解决方案:
- 设置最大迭代次数
python复制agent = PlanAndExecute(
planner=planner,
executor=executor,
max_iterations=5 # 默认10次可能过多
)
4. 生产环境优化策略
4.1 性能调优
缓存策略:
- 对频繁查询的静态数据(如城市列表)使用内存缓存
python复制from functools import lru_cache
@lru_cache(maxsize=1000)
def get_city_code(city_name: str):
return db.query("SELECT code FROM cities WHERE name = ?", city_name)
异步执行:
- 对IO密集型工具使用async/await
python复制@tool
async def check_weather(city: str):
async with aiohttp.ClientSession() as session:
async with session.get(f"https://api.weather.com/{city}") as resp:
return await resp.json()
4.2 安全防护
输入过滤:
python复制import re
def sanitize_input(text: str):
# 移除SQL特殊字符
text = re.sub(r"[\'\";]", "", text)
# 截断超长输入
return text[:500]
权限控制:
- 为不同工具设置访问级别
python复制tools = [
Tool(name="public_search", func=search, access_level="guest"),
Tool(name="internal_book", func=book, access_level="admin")
]
def check_access(tool_name, user_role):
tool = next(t for t in tools if t.name == tool_name)
return user_role >= tool.access_level
4.3 监控体系
建议部署以下监控看板:
- 执行路径图:可视化常见任务流程
- 耗时热力图:识别性能瓶颈
- 异常词云:发现高频错误信息
python复制# Prometheus监控示例
from prometheus_client import Counter, Histogram
REQUEST_COUNT = Counter('agent_requests', 'Total API calls')
RESPONSE_TIME = Histogram('agent_latency', 'Response time in seconds')
@REQUEST_COUNT.time()
def process_request(input_text):
start = time.time()
# ...处理逻辑...
RESPONSE_TIME.observe(time.time() - start)
5. 进阶:多Agent协作系统
当单个Agent无法处理复杂需求时,可以采用多Agent架构:
5.1 设计模式
主从模式:
- 主Agent负责任务分配
- 子Agent专注特定领域(如航班、酒店)
mermaid复制graph TD
A[主Agent] --> B(航班Agent)
A --> C(酒店Agent)
A --> D(支付Agent)
联邦模式:
- 各Agent平等协作
- 通过消息总线通信
python复制class FederatedAgent:
def __init__(self, agents):
self.agents = agents # 预注册的Agent列表
def handle(self, request):
# 广播请求,收集响应
results = []
for agent in self.agents:
if agent.can_handle(request):
results.append(agent.process(request))
return merge_results(results)
5.2 冲突解决
场景:航班Agent选择早班机,酒店Agent推荐晚入住
解决方案:
- 约束传播:将"希望早晨抵达"作为全局约束
- 投票机制:各方案评分后选择总分最高者
- 人工干预:当自动协商失败时转人工
python复制def resolve_conflict(proposals):
# 计算每个提案的加权分
scores = []
for p in proposals:
score = p["price"] * 0.6 + p["time_fit"] * 0.4
scores.append(score)
# 返回最佳方案
return proposals[scores.index(max(scores))]
5.3 实战案例:旅行规划系统
架构:
- 用户Agent:理解自然语言请求
- 资源Agent:对接各供应商API
- 协调Agent:平衡预算、时间等约束
执行流程:
- 用户Agent解析"我想去三亚度蜜月,预算2万"
- 协调Agent制定计划:
- 航班:经济舱直飞
- 酒店:海景房5晚
- 活动:浪漫晚餐+SPA
- 资源Agent获取具体选项
- 生成PDF行程单并邮件发送
python复制class TravelPlanner:
def __init__(self):
self.agents = {
"user": UserAgent(),
"coordinator": CoordinatorAgent(),
"flight": FlightAgent(),
"hotel": HotelAgent()
}
def plan(self, request):
# 上下文传递链
context = self.agents["user"].parse(request)
plan = self.agents["coordinator"].make_plan(context)
details = {}
for resource in ["flight", "hotel"]:
details[resource] = self.agents[resource].search(plan)
return self.generate_itinerary(details)
在真实项目中,我发现多Agent系统最关键的调试点是上下文一致性。建议为每个请求分配唯一trace_id,并在所有日志中携带该ID,这样当出现"酒店选择了北京而航班去了上海"这类问题时,可以完整追溯决策链条。
