Agent 工具调度设计 是指为 AI Agent(智能体)设计一套机制,使其能够根据用户任务需求,自主选择、编排、调用外部工具(函数/API),并处理调用结果,从而完成复杂目标的工程方案。它是实现"LLM + 工具执行"闭环的核心。
一、为什么需要工具调度设计?
- 能力边界:LLM 本身只有语言理解与生成能力,无法执行实时计算、访问数据库、操作软件、控制硬件。
- 任务分解:复杂任务往往需要多个步骤、多种工具组合(如:搜索 → 计算 → 发送邮件)。
- 动态决策:Agent 需要根据中间结果判断下一步该调用什么工具,而不是硬编码流程。
二、核心设计要素
| 要素 | 说明 | 示例 |
|---|---|---|
| 工具描述 | 给 LLM 提供每个工具的名称、参数、功能说明(类似 API 文档) | search(query: str) -> list |
| 意图解析 | LLM 理解用户需求,决定调用哪个工具及其参数 | 用户:"今天北京天气"→ 决定调用 get_weather(city="北京") |
| 参数提取 | 从对话中提取符合工具 schema 的参数 | 从"明天下午3点开会"提取 time="2025-05-14 15:00" |
| 执行与反馈 | 实际调用工具,将结果返回给 LLM | 调用天气 API 返回 JSON,LLM 将其转化为自然语言 |
| 错误处理 | 工具调用失败、超时、参数缺失时的恢复策略 | 缺失参数则反问用户 |
| 多步编排 | 支持顺序、并行、条件分支、循环等执行模式 | 先搜索,再对搜索结果做摘要,最后发送 |
| 状态管理 | 维护整个任务执行过程的上下文(已调用的工具、中间结果) | 记忆上一轮搜索关键词 |
三、常见调度模式
1. 单步调用(基础)
Agent 单次响应中决定调用一个工具,将返回值直接作为最终回答。
ini
用户: 告诉我 2+2 等于几
Agent: 调用 calculator(expression="2+2") → 4 → 回答"等于4"
2. 多步顺序调用(Chain)
Agent 执行完一个工具后,将结果作为上下文继续决定下一个工具。
css
用户: 搜索最新的 AI 新闻,然后翻译成中文
Agent:
Step1: search("AI news 2025") → 返回5条英文新闻
Step2: translate(text=上一步结果, target="zh") → 中文新闻
回答: 中文新闻列表
3. 并行调用
当任务可以分解为相互独立的子任务时,同时调用多个工具以提升效率。
css
用户: 比较北京和上海的天气
Agent: 同时调用 get_weather("北京") 和 get_weather("上海") → 合并结果 → 回答
4. 条件分支
根据中间结果决定下一步调用的工具或是否提前终止。
yaml
用户: 检查用户 ID 123 的积分是否大于100,如果是则发送优惠券
Agent:
Step1: query_points(user_id=123) → 80
Step2: 80 < 100 → 不调用 send_coupon,回答"积分不足"
5. 循环迭代(ReAct 模式)
Agent 在"思考-行动-观察"循环中反复调用工具,直到获得足够信息再生成最终答案。
yaml
用户: 帮我找到一家离我最近且评分高于4.5的咖啡店
Agent:
Thought: 需要先获取用户位置,然后搜索附近的咖啡店
Action: get_user_location() → {lat: 40.7128, lng: -74.0060}
Observation: 位置在纽约时代广场
Thought: 现在搜索附近咖啡店
Action: search_nearby(lat, lng, query="咖啡店", radius=1000)
Observation: 返回12家咖啡店
Thought: 需要筛选评分>4.5的
Action: filter_by_rating(shops, min=4.5) → 3家店
Thought: 已找到足够信息,可回答
Answer: "以下是距离您最近且评分高于4.5的三家咖啡店..."
6. 错误恢复与重试
工具调用可能失败,Agent 需自主处理。
调用天气 API 超时 → Agent 尝试备用天气 API → 仍失败 → 回答"暂时无法获取天气,请稍后再试"
四、典型技术实现:函数调用(Function Calling)
现代 LLM(如 GPT-4、Claude、DeepSeek)原生支持函数调用,极大简化了工具调度设计。
伪代码流程
- 定义工具 Schema(JSON 格式)
- 将用户消息 + 工具描述一起发给 LLM
- LLM 返回:
{ name: "get_weather", arguments: { city: "Beijing" } } - 执行对应函数,获得结果
- 将结果再次发给 LLM,让其生成最终回答
示例(Python + OpenAI)
python
import openai
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称"}
},
"required": ["city"]
}
}
}]
# 用户消息
messages = [{"role": "user", "content": "北京今天天气怎么样?"}]
# 第一次调用 LLM
response = openai.ChatCompletion.create(
model="gpt-4",
messages=messages,
tools=tools,
tool_choice="auto"
)
# 检查是否需要调用工具
if response.choices[0].message.tool_calls:
tool_call = response.choices[0].message.tool_calls[0]
if tool_call.function.name == "get_weather":
args = json.loads(tool_call.function.arguments)
weather = get_weather(args["city"]) # 实际函数调用
# 将工具结果添加到对话
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": weather
})
# 第二次调用 LLM 生成最终回答
final = openai.ChatCompletion.create(model="gpt-4", messages=messages)
print(final.choices[0].message.content)
五、高级调度设计模式
| 模式 | 描述 | 适用场景 |
|---|---|---|
| 计划-执行 | 先由 LLM 生成整个步骤计划(如 JSON 列表),再依次执行 | 步骤固定、可预测的任务 |
| 反思 (Reflexion) | 执行结果不理想时,LLM 根据错误反馈修改计划重试 | 编程、数学推理 |
| 多智能体协作 | 多个 Agent 各有工具集,通过调度器通信协作 | 复杂工作流(如客服 + 技术 + 财务) |
| 人机回环 | 遇到不确定或高风险操作时,请求用户确认 | 发邮件、转账、删除数据 |
| 资源感知调度 | 根据工具调用成本、延迟、配额动态选择工具 | 低成本优先、快速响应 |
六、设计时的关键考量
- 工具粒度 :工具不宜过细(如
add_one)也不宜过粗(如do_everything),保持单一职责。 - 冲突解决:多个工具都可能满足需求时,LLM 如何选择?可通过描述优先级或增加约束。
- 安全边界:高危操作(发送邮件、写入数据库)应加确认或权限校验。
- 上下文长度:工具返回结果可能很长,需截断或摘要后再送入 LLM。
- 可观测性:记录每一次工具调用(输入、输出、耗时),便于调试和优化。
七、总结
Agent 工具调度设计 本质上是一套 "决策 + 执行 + 反馈" 的闭环系统。它让 LLM 从"聊天机器人"进化为"行动机器人",能够操控外部世界。设计时需综合考虑任务复杂度、实时性、稳定性和成本,选择适当的调度模式(单步/链/并行/循环/多智能体等),并借助函数调用机制快速落地。