工具是 Agent 连接现实世界的接口。模型可以提出“查询订单”或“修改配置”的意图,但真正的系统必须把意图转换为参数,完成权限检查,执行动作,再把结果以模型能理解的方式返回。

工具设计得不好,模型越强,错误动作的速度可能越快。因此工具 API 不只是开发者接口,也是一份给模型读取的操作契约。

一、三类工具

可以先按工具影响的对象来分类:

类型例子主要风险
感知工具搜索、读文件、查数据库、获取指标数据过期、范围过大
执行工具发邮件、写文件、创建资源、部署副作用、权限和误操作
协作工具转交专家、请求审批、通知用户等待、重复执行、状态丢失

感知工具通常可以自动调用,但仍要限制查询范围和数据权限。执行工具则应该明确副作用,必要时采用“预览 → 确认 → 执行”的两阶段流程。协作工具要返回可追踪的任务 ID,让 Agent 能够在异步完成后恢复。

二、工具 schema 是运行时边界

工具名称和描述应该让模型知道“何时用、不能做什么、参数怎么填”。参数 schema 负责机器校验,描述负责语义校验,两者缺一不可:

{
  "name": "create_issue",
  "description": "在指定仓库创建问题;不会自动关闭已有问题,写入前需要确认仓库和标题",
  "inputSchema": {
    "type": "object",
    "required": ["repository", "title"],
    "properties": {
      "repository": {"type": "string", "description": "owner/name 格式"},
      "title": {"type": "string", "minLength": 1},
      "body": {"type": "string"}
    },
    "additionalProperties": false
  }
}

执行器仍然需要再次校验。模型生成的参数即使通过 JSON Schema,也可能指向错误仓库、超出用户权限或违反业务规则。

三、幂等和失败语义

网络重试、模型重复调用和用户刷新都可能让同一个工具执行多次。对于创建、扣费、发送等动作,应使用幂等键或业务唯一键,让重复请求返回原结果,而不是产生第二个副作用。

失败结果也要结构化。把所有错误都变成“执行失败”会让 Agent 无法决定下一步。至少可以区分:

invalid_input  参数不合法,修改后可重试
permission_denied  当前身份无权执行,需要授权或人工介入
conflict  外部状态已变化,需要重新读取
timeout  结果未知,重试前先查询幂等状态

“结果未知”尤其重要:超时不等于动作没有发生。

四、沙箱、权限和人工确认

工具的最小权限应当在执行层实现,而不是只写在提示词里。文件工具限制工作区,命令工具限制可执行程序和网络,数据库工具限制表与操作类型;高风险动作在真正执行前展示目标、参数和预计影响。

沙箱解决的是隔离问题,审批解决的是决策问题,两者不能互相替代。一个被批准的危险命令仍然应该在受限环境运行;一个安全沙箱中的生产写操作也可能需要用户确认。

五、MCP 解决工具连接问题

当每个 Agent 都自己实现一套工具适配器时,工具发现、schema 传递和错误格式很快会重复。MCP 提供了一种更统一的连接方式:服务端暴露资源、工具或提示能力,客户端在运行时发现并调用。

但协议统一不等于信任自动建立。接入 MCP 服务时仍要核对来源、权限、数据范围和审计策略;第三方工具返回的文本也应被视为外部数据,而不是新的系统指令。

六、工具调用的最小闭环

一个可上线的工具调用至少应留下这些证据:调用者、工具版本、参数摘要、权限判断、执行耗时、结果状态和验证结果。对副作用操作,还要记录幂等键以及是否经过确认。

当工具具备清晰的契约、可恢复的失败语义和最小权限时,Agent 才真正拥有了可控的行动能力。

参考阅读

  • 李博杰:《深入理解 AI Agent:设计原理与工程实践》,v1.3,2026-07-29。