[控场AI]
· 5 分钟阅读· 2,715 字

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

工具描述即协议: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个检查问题

  1. 触发 —— 第一句话是否说明了何时调用,且命名的是任务而非功能?
  2. 边界 —— 是否说明了不适用于什么,包括最接近的相似任务?
  3. 输入 —— 每个参数是否能在不阅读其他文档的情况下正确填写?
  4. 返回 —— 输出schema是否命名了返回内容,包括哪些字段始终存在、哪些是条件性的?
  5. 延迟与成本 —— 描述是否说明了调用可能需要多长时间,以及再次调用是否有代价?
  6. 恢复 —— 调用截断或失败后,是否有除"再调一次"之外的明确路径?
  7. Annotations —— 你声明的hint是否属实?在会计费或写入的调用上标注idempotentHint: true是客户端会当真的一次谎言。

这套清单有两个值得保留的特性。第一,它可以在没有模型参与的情况下检查:第1-3和第5-7项本质上就是"这句话是否出现在描述中"。第二,它在失败时可测试:每个问题都对应一种可复现的错误调用形态,因此描述变更可以像其他契约一样做回归测试。

为什么公开描述而非依赖提示技巧

以远程MCP服务器为例:一个只回答单一问题的端点——给它两个可辩护的选项,返回它偏好哪个、判断差距多大以及原因——其完整契约存在于模型读取的位置:工具描述、参数描述和输出schema。准确性范围、样本量和方法另行发布,因为模型关于自身的报告除非有模型外部的检查,否则毫无价值。

一个回答了上述七个问题的描述让工具可被调用。一个都没回答的描述让它沦为带schema的抛硬币。

MCP 远程服务器指工具逻辑运行在你自己的进程之外、由模型通过网络调用的一类实现。相比本地工具,远程调用多了网络延迟、超时、部分失败和计费这些现实约束,因此描述里关于延迟、成本和恢复路径的信息更加不可省略。文章举的例子——一个只回答"两个选项中你偏好哪个、差距多大、为什么"的端点——其价值恰恰在于:它的正确性依赖的是可被外部检查的输出契约,而不是模型对自己判断的自我描述。把范围、样本量和方法单独发布,就是为了让模型的回答能有模型之外的证据来对照,避免"模型自证"的循环。

#MCP工具描述#AI工具调用协议#MCP server设计#工具schema优化#AI Agent工具调用#tool description最佳实践#模型工具协议
分享:

相关推荐