林逍遥 AI林逍遥 AI
登录
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"]
    }
}

描述优化原则:

  1. 说明什么场景使用这个工具
  2. 明确输入什么输出什么
  3. 与其他类似工具区分边界
  4. 用具体例子而非抽象概念

工具数量多时的策略

当工具超过 20 个,把所有工具都放在 tools 数组里会导致两个问题:

  1. 占用大量 token(每个工具描述 ~200 token)
  2. 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。

  1. 创建 5 个以上工具(搜索、计算、文件、通信等)
  2. 优化每个工具的 description,确保 Claude 能准确选择
  3. 测试一个需要多个工具配合完成的复杂任务

关键要点

Note: 本文核心总结

  • 工具描述质量直接决定 Agent 的工具选择准确率
  • 工具数量多时,使用分组或语义搜索来缩小范围
  • Claude 原生支持并行工具调用,利用 asyncio 并行执行
  • 通过 system prompt 引导工具之间的调用顺序
二维码
微信公众号:lingxiaoyao

关注公众号,获取最新 AI 教程和课程更新

加载评论中...