Agent工具编排
多工具编排:让 Agent 自主选择工具
·约 7 分钟阅读
当 Agent 只有 2-3 个工具时,选择很简单。但当工具数量达到 10+,甚至 50+,Agent 如何可靠地选择正确的工具?本文讲解工具描述优化、智能路由和并行调用策略。
你将学到什么
- 工具描述的编写技巧(决定 Agent 能否选对工具)
- Tool Search:大量工具时的动态发现机制
- 工具组合策略与并行调用
- 处理工具之间的依赖关系
工具描述是关键
Claude 选择工具的依据是 description 字段。好的描述 = 高准确率。
# 差的描述——模糊,Claude 不知道什么时候用
bad_tool = {
"name": "process_data",
"description": "处理数据",
"input_schema": {"type": "object", "properties": {}}
}
# 好的描述——明确场景、输入、输出
good_tool = {
"name": "analyze_csv_sales",
"description": "分析 CSV 格式的销售数据。输入:CSV 文件路径。输出:销售总额、TOP 产品、月度趋势。适用于需要从销售报表中提取关键指标的场景。",
"input_schema": {
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "CSV 文件的完整路径"
},
"date_range": {
"type": "string",
"description": "可选,日期范围如 '2024-01 to 2024-06'"
}
},
"required": ["file_path"]
}
}
描述优化原则:
- 说明什么场景使用这个工具
- 明确输入什么、输出什么
- 与其他类似工具区分边界
- 用具体例子而非抽象概念
工具数量多时的策略
当工具超过 20 个,把所有工具都放在 tools 数组里会导致两个问题:
- 占用大量 token(每个工具描述 ~200 token)
- Claude 可能选错工具
方案一:工具分组
按功能领域将工具分组,根据用户意图只加载相关组:
tool_groups = {
"文件操作": [read_file, write_file, list_dir],
"数据分析": [query_db, analyze_csv, plot_chart],
"通信": [send_email, send_slack, create_ticket],
"搜索": [web_search, doc_search, code_search],
}
def select_tools(user_message):
"""根据用户意图选择工具组"""
# 用一次轻量 Claude 调用来分类意图
intent = client.messages.create(
model="claude-haiku-4-5",
max_tokens=50,
messages=[{"role": "user", "content": f"将以下请求分类到这些类别之一: {list(tool_groups.keys())}\n请求: {user_message}"}]
)
category = intent.content[0].text.strip()
return tool_groups.get(category, [])
方案二:Tool Search(语义搜索)
将工具描述做成向量索引,根据用户查询动态检索最相关的工具:
# 伪代码 — 实际实现需要向量数据库
def tool_search(query, all_tools, top_k=5):
"""语义搜索最相关的工具"""
query_embedding = embed(query)
scored = []
for tool in all_tools:
tool_embedding = embed(tool["description"])
score = cosine_similarity(query_embedding, tool_embedding)
scored.append((score, tool))
scored.sort(reverse=True)
return [t for _, t in scored[:top_k]]
并行工具调用
Claude 可以在一次回复中调用多个工具。当多个操作之间没有依赖关系时,Claude 会自动并行调用:
# Claude 可能返回多个 tool_use block
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=4096,
tools=tools,
messages=[{"role": "user", "content": "同时查一下北京和上海的天气"}]
)
# response.content 可能包含两个 tool_use block:
# [tool_use: get_weather(city="北京"), tool_use: get_weather(city="上海")]
# 你可以并行执行这些工具调用
import asyncio
async def execute_parallel(tool_calls):
tasks = [execute_tool_async(tc.name, tc.input) for tc in tool_calls]
return await asyncio.gather(*tasks)
处理工具依赖
有些场景工具之间有顺序依赖(如先搜索再总结)。Claude 会自然地处理这种依赖——在第一次工具调用返回结果后,它会决定下一步调用什么工具。
关键是在 system prompt 中说明依赖关系:
你有以下工具可用:
- search_docs: 搜索文档库
- summarize: 总结搜索到的内容
- send_report: 发送报告
工作流程建议:先搜索相关文档,然后总结,最后发送报告。
实战练习
Tip: 设计一个多工具 Agent。
- 创建 5 个以上工具(搜索、计算、文件、通信等)
- 优化每个工具的 description,确保 Claude 能准确选择
- 测试一个需要多个工具配合完成的复杂任务
关键要点
Note: 本文核心总结
- 工具描述质量直接决定 Agent 的工具选择准确率
- 工具数量多时,使用分组或语义搜索来缩小范围
- Claude 原生支持并行工具调用,利用 asyncio 并行执行
- 通过 system prompt 引导工具之间的调用顺序