Agent 工具系统设计六模式:从混乱到有序

2026-06-11工具调用系统设计Agent生产实践

问题:当 Agent 有 20+ 工具时

把 20 个工具的 Function Definition 全部塞进 system prompt 会导致:(1) Token 消耗爆炸(每个工具约 300-500 tokens),(2) LLM 选择困难——选项越多越容易选错,(3) 关键工具的上下文被稀释。解决方案是分层设计。

六种设计模式

模式核心思路适用场景
1. 工具网关 先用便宜模型做意图分类,只注入相关工具子集(≤8个) 工具数量 20+,多领域
2. 工具链编排 DAG 预定义依赖关系 + LLM 自由组合(混合模式) 复杂多步任务,有明确执行顺序
3. 描述工程 name/description/parameters 精心设计,让 LLM 一眼知道"何时用、怎么用" 所有场景
4. 并行调用 单次返回多个 tool_call,应用层并行执行无依赖的工具 需要同时查询多个数据源
5. 错误处理 错误信息结构化:{错误类型 + 可行建议 + 是否可重试},但不暴露内部细节 所有生产场景
6. 安全沙箱 权限检查 → 参数白名单 → 限流 → SQL注入防护 → 路径沙箱 → 审计日志 生产环境,多租户

模式一:工具网关(Tool Gateway)

最实用的模式。意图分类器用便宜的模型(GPT-3.5 / 本地小模型),只负责判断"用户想做什么",然后只注入对应分类的工具子集。

# 两级路由架构
TOOL_GROUPS = {
    "database": ["query_db", "list_tables", "describe_schema"],
    "file_system": ["read_file", "write_file", "list_dir", "search_files"],
    "web": ["web_search", "web_fetch", "browser_snapshot"],
    "communication": ["send_email", "send_message"],
}

async def route_tools(user_input: str, all_tools: list):
    # 第一步:便宜模型做意图分类
    intent = await cheap_model.classify(user_input, list(TOOL_GROUPS.keys()))

    # 第二步:只注入对应组的工具
    group_names = intent["groups"]  # 如 ["database", "web"]
    active_tools = []
    for g in group_names:
        active_tools.extend(TOOL_GROUPS[g])

    return [t for t in all_tools if t.name in active_tools]

避坑:意图分类错误会导致注入错误工具子集,任务彻底失败。建议返回 top-2 意图而非单选,增加容错。

模式三:描述工程黄金法则

工具描述的质量直接影响 Agent 的决策准确率。三条铁律:

  1. description 要比 name 更有信息量——不要写"搜索工具",要写"在已索引的知识库文档中搜索文本,支持关键词和布尔表达式,适用于查找特定主题的详细内容"
  2. 暗示"何时用"——例如:"当你需要查找具体信息时使用此工具。注意:仅搜索已索引的文档,不包含草稿。"
  3. 暗示"怎么用"——在 parameters 的 description 中给出示例值格式
{
  "name": "search_documents",
  "description": "搜索知识库文档。当你需要查找某个主题的具体信息时使用此工具。"
               + "注意:仅搜索已索引的文档,不包含草稿。支持精确匹配和模糊匹配。",
  "parameters": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "搜索关键词。支持布尔运算 AND/OR/NOT。"
                     + "示例:'RAG AND 混合检索' 或 '向量数据库 NOT Pinecone'"
      },
      "top_k": {
        "type": "integer",
        "description": "返回结果数量,默认 5,最大 20。"
                     + "数值越大结果越全面但耗时越长"
      }
    },
    "required": ["query"]
  }
}

模式五:结构化错误处理

工具返回的错误信息是给 LLM 看的,必须包含:明确错误类型 + 可行建议 + 是否可重试。但不能暴露内部细节(栈追踪、内部路径、数据库结构等)。

# ✅ 正确的错误返回
{
  "error": true,
  "error_type": "rate_limit",
  "message": "API 调用频率过高,请等待 30 秒后重试。",
  "retryable": true,
  "retry_after_seconds": 30
}

# ❌ 错误的错误返回
{
  "error": "InternalError: connection refused at /usr/lib/python3/site-packages/..."
}

总结:从原型到生产的工具系统升级路径

  1. 原型阶段:直接罗列所有 Function Definition,工具数 < 10
  2. 增长阶段(10-20 工具):引入描述工程,优化每个工具的 description
  3. 扩展阶段(20+ 工具):引入工具网关,按领域分组注入
  4. 生产阶段:加入错误处理标准化 + 安全沙箱 + 审计日志
未标记