工具描述即协议:MCP工具设计中的7个关键问题

模型调用工具时只见名称、描述与schema,描述即协议,必须写清触发、边界、成本与重试。
文章指出,模型在决定是否调用工具时,上下文中只有名称、描述和参数 schema,README 与文档都不在其中,因此工具描述本质上是运行时协议。最昂贵的失败不是崩溃,而是静默失败:模型从未调用、错误调用或重复调用,都不会抛异常,却产出看似合理的错误答案。修复点不在代码,而在模型能看到的字段里。作者逐字段说明 name、description、参数描述、annotations 和输出 schema 各自应回答的问题,并特别强调最常被跳过的两行——否定边界与重试规则。最后给出发布前的 7 个检查问题,它们可独立于模型验证,且每种失败都可复现、可回归测试。
当模型判断是否调用你发布的工具时,它手中只有三样东西:名称、描述和参数schema。README、文档站点、代码注释——这些都不在模型的上下文中。这个事实从根本上改变了工具描述应当包含什么内容。

代价高昂的是静默失败
一个崩溃的工具反而是廉价的:你会得到错误码、退出状态和行号。真正昂贵的是那些模型基于手头信息做出了"合理"决策的失败场景:
- 模型从未调用工具,因为描述中没有任何内容说明何时应该调用它;
- 模型在不适用的输入上调用了工具,因为描述没有说明工具不适用于什么;
- 模型把三个选项塞进一个参数,因为schema只写了
string; - 模型在超时后重新调用,因为描述从未提及重试意味着一次新的付费调用。
这些失败都不会抛出异常。它们用错误的工具产出了一个看似合理的答案,而你可能在数周后才偶然发现。修复点几乎从不在代码中,而在模型真正能看到的字段里。
每个字段应承载什么信息
| 字段 | 它为模型回答的问题 | 应该放什么 | 通常放了什么 |
|---|---|---|---|
| name | 这是什么,一个词概括? | 动词+对象 | 内部代号 |
| description开头 | 什么时候该用它? | 触发条件,第一句话,无前言 | "This tool allows you to…" |
| description否定部分 | 什么时候不该用? | 最接近但不适用的任务 | 无 |
| description机制 | 调用后会发生什么? | 延迟、成本、重试规则、结果出现的位置 | 功能列表 |
| 参数描述 | 有效形状是什么? | 单位、是否必填、每字段一个值 | 重述参数名 |
| annotations | 能自由调用吗? | readOnlyHint、idempotentHint、openWorldHint——如实填写 | 省略,或期望性地填"true" |
| 输出schema | 返回什么,什么形状? | 字段名、类型、哪些始终存在 | 缺失,模型只能猜测 |
每一行都是模型无法通过其他方式回答的问题。如果某行为空,你不是在做选择——你把决定权交给了采样。
MCP(Model Context Protocol) 是这里频繁暗示但未点名的底层协议。它由 Anthropic 于 2024 年底提出,初衷是统一大语言模型与外部工具、数据源之间的接口,让模型无需为每个服务定制集成代码。在 MCP 中,工具通过一份 JSON schema 向模型自描述:名称、描述、参数定义以及可选的输出 schema 和 annotations。模型在推理时拿到的正是这份自描述,而不是你的仓库或官网。理解这一点很关键——工具描述在 MCP 下不是给人看的说明文档,而是运行时的机器可读契约,任何缺失的信息都会直接变成采样时的随机性。
最常被跳过的两行
否定边界。 一个没有边界的触发条件等于邀请模型过度调用。说明工具不适用于什么只需一句话,却能消除一整类误用。
重试规则。 如果调用可能超时,描述必须说明超时后该怎么做——否则模型的默认行为(再试一次)恰恰是你最承受不起的。无论你的工具是否付费,句子的形状是一样的:调用被截断后,模型应该做什么?
幂等性(idempotency) 是理解重试规则的底层概念。一个操作若执行一次和执行多次产生相同结果,就是幂等的,例如查询天气、读取文件。反之,扣款、发送邮件、写入记录则是非幂等的,重复执行会带来副作用。模型在超时后默认会重试,而它无法自己判断这次调用是否已经生效,所以这个判断必须由你在描述里给出。idempotentHint: true 的语义正是"重试是安全的",一旦标注错误,客户端可能据此自动重试,把小故障放大成重复扣费或重复写入。这就是文章强调 annotations 必须如实填写的原因。
发布工具前的7个检查问题
- 触发 —— 第一句话是否说明了何时调用,且命名的是任务而非功能?
- 边界 —— 是否说明了不适用于什么,包括最接近的相似任务?
- 输入 —— 每个参数是否能在不阅读其他文档的情况下正确填写?
- 返回 —— 输出schema是否命名了返回内容,包括哪些字段始终存在、哪些是条件性的?
- 延迟与成本 —— 描述是否说明了调用可能需要多长时间,以及再次调用是否有代价?
- 恢复 —— 调用截断或失败后,是否有除"再调一次"之外的明确路径?
- Annotations —— 你声明的hint是否属实?在会计费或写入的调用上标注
idempotentHint: true是客户端会当真的一次谎言。
这套清单有两个值得保留的特性。第一,它可以在没有模型参与的情况下检查:第1-3和第5-7项本质上就是"这句话是否出现在描述中"。第二,它在失败时可测试:每个问题都对应一种可复现的错误调用形态,因此描述变更可以像其他契约一样做回归测试。
为什么公开描述而非依赖提示技巧
以远程MCP服务器为例:一个只回答单一问题的端点——给它两个可辩护的选项,返回它偏好哪个、判断差距多大以及原因——其完整契约存在于模型读取的位置:工具描述、参数描述和输出schema。准确性范围、样本量和方法另行发布,因为模型关于自身的报告除非有模型外部的检查,否则毫无价值。
一个回答了上述七个问题的描述让工具可被调用。一个都没回答的描述让它沦为带schema的抛硬币。
MCP 远程服务器指工具逻辑运行在你自己的进程之外、由模型通过网络调用的一类实现。相比本地工具,远程调用多了网络延迟、超时、部分失败和计费这些现实约束,因此描述里关于延迟、成本和恢复路径的信息更加不可省略。文章举的例子——一个只回答"两个选项中你偏好哪个、差距多大、为什么"的端点——其价值恰恰在于:它的正确性依赖的是可被外部检查的输出契约,而不是模型对自己判断的自我描述。把范围、样本量和方法单独发布,就是为了让模型的回答能有模型之外的证据来对照,避免"模型自证"的循环。
相关推荐

Claude Pro不含API权限?Max与Team计划新增API额度详解
Claude Pro订阅不含API访问权限,API需单独计费。但Max和Team计划现已包含每月API额度:Max 5x为100美元,Max 20x为200美元,Team每席位最高合计500美元。本文详解各档位额度、领取方式及对开发者的影响。

隔离环境实测35万星REA:4秒装完,但两个坑要当心
隔离实验室实测35万星开源逆向工程工具REA:4秒安装、15秒列出截图工具全部外联地址、梳理565个通信通道,同时暴露写入用户级设置与31个高风险工具权限两个坑,附三条安全使用规则。
逆向工程+AI Agent:几周克隆Adobe应用的技术真相
逆向工程+AI Agent:几周克隆Adobe应用的技术真相
一位开发者因Adobe提前取消费转向逆向工程,用AI Coding Agent几周内做出7款开源替代品。本文解析逆向工程原理、Reverse Engineer Anything这个MCP Server六天破10万星的原因,以及AI克隆应用在性能、专有数据和法律层面的真实边界。