MCP 开放治理之后:工具协议怎么写才不算半成品
人工智能约 4 分钟阅读

MCP 开放治理之后:工具协议怎么写才不算半成品

协议进基金会降低对接成本。真正拉开差距的是工具描述、身份隔离、机器可读失败语义,以及按场景裁剪工具面。

cover

模型上下文协议(MCP)被推进到 Linux Foundation 旗下的开放治理之后,讨论重心从「要不要接」悄悄变成了「怎么接才不算半成品」。热搜上仍是各家 Agent 演示,仓库里真正拉开差距的,往往是工具描述、鉴权边界和失败语义——协议层终于开始像基础设施,而不是某个客户端的私有插件格式。

我关心的不是新闻稿里的中立性表态,而是工程清单:一个工具怎么暴露、谁能调用、超时了怎么说、审计日志落在哪。

协议开放不等于能力开放

MCP 解决的是「Agent 运行时如何发现并调用工具」的接线问题。它不自动解决:

  • 工具是否幂等
  • 凭证是否按用户 / 按租户隔离
  • 输出是否大到撑爆上下文
  • 提示注入是否能借工具回传二次指令

开放治理降低的是对接成本,放大的是错误接法的传播速度。以前你接错一个专有插件,受害面是自家 bot;协议趋同以后,半吊子 schema 会随着「兼容 MCP」被复制到更多运行时。

所以第一原则很土:把 MCP server 当对外 API 来设计,不要当 prompt 的快捷方式。

工具描述比模型选择更先决定行为

Agent 看工具,先看名字、参数说明、返回值形状。含糊的描述会换来含糊的调用:

json
{
  "name": "run_query",
  "description": "Run a query against the system",
  "inputSchema": {
    "type": "object",
    "properties": {
      "q": { "type": "string" }
    }
  }
}

这种定义等于邀请模型把任意字符串塞进来。更稳的写法是收窄动词、写明副作用与限制:

json
{
  "name": "search_orders_readonly",
  "description": "Search the current tenant's orders by id or email. Read-only. Max 50 rows. Does not refund or cancel.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "orderId": { "type": "string", "pattern": "^ord_[a-z0-9]+$" },
      "email": { "type": "string", "format": "email" },
      "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 20 }
    },
    "additionalProperties": false
  }
}

描述里写清「不做什么」,往往比写清「能做什么」更能少炸生产。模型会补全意图;你要做的是把危险补全路径堵死。

鉴权:身份不能只活在对话里

常见坏味道:MCP server 用一把长期环境变量 token,所有会话共享同一后端身份。对话里写着「当前用户是 Alice」,工具层却是 God Mode。

更干净的拆法:

  1. 入站:Agent 运行时持有用户会话 / OBO(on-behalf-of)短令牌。
  2. 出站:MCP server 校验令牌,再向下调用只读或带 scope 的业务 API。
  3. 默认拒绝:未声明的 tool、未声明的字段、跨租户 id 直接 403,而不是靠模型「注意权限」。

如果工具能执行 shell、写仓库、打款,再叠一层人工确认或双人复核。协议可以标准,放权策略不能跟着 demo 走。

失败语义要机器可读

Agent 循环最怕「看起来像成功」。工具返回应区分:

  • 业务空结果(查无订单)
  • 参数错误(可修复后重试)
  • 权限错误(不应盲重试)
  • 上游超时(可有限重试)
  • 部分成功(批量接口尤其危险)

一段对循环友好的错误形如:

json
{
  "ok": false,
  "code": "RATE_LIMIT",
  "retryable": true,
  "retryAfterMs": 2000,
  "message": "upstream 429"
}

把 retryable 留给编排器,把自然语言 message 留给日志和必要时的用户可见提示。不要只丢一句散文给模型自由发挥。

图:Agent、MCP server 与业务 API 的三层边界

上下文预算:工具也是 token 税

协议一通,最容易犯的错是「多挂工具」。每多一个 tool,系统提示和决策面都变宽,误调用率会上去。

实务上我倾向于:

  • 按任务场景装配工具集,而不是全球工具超市
  • 列表类接口默认硬顶 limit,大字段改成「先返回句柄再按需 fetch」
  • 二进制 / HTML 先摘要,再决定要不要进模型上下文
  • 对高频只读工具做服务端缓存,避免 Agent 同一轮问三遍

MCP 让接线变短,但上下文窗口没有变便宜。

和评测、审计放在一起

开放协议时代,可重复的回归比单次 demo 重要:

  • 固定一批「该调用 / 不该调用」的对话脚本
  • 记录 tool name、参数哈希、时延、结果码(注意脱敏)
  • 对高危工具单独做红队:诱导越权、诱导二次注入、诱导无意义循环

行业里已经有人公开谈 prompt injection 难以「一劳永逸」。工程上的诚实态度是:假设模型会被带偏,用工具面的硬限制托底。

小结

MCP 进入更中立的治理框架,降低的是对接摩擦,不是设计责任。写好工具描述、收紧身份与 scope、给出机器可读的失败语义、按场景裁剪工具面——这四件事比追哪个前端客户端更有用。协议会继续演进;半成品 server 被标准包装之后,炸得只会更整齐。

相关文章