改了20字描述,MCP工具调用准确率飙到85%

你有没有遇到过这种情况——

花了一个周末写好 MCP Server,三个工具跑得飞起。丢给 Claude Code 用,结果 AI 全程不调用你的工具。查阅日志,发现它宁可自己编答案,也不碰你精心写好的接口。

更崩溃的是反过来:改了几行描述想让 AI 多用用,第二天发现它在跟用户说"早上好"的时候也去搜你的知识库。

这不是你不会写代码。是 MCP 工具描述写错了。

我在写 kb-builder 的知识库检索工具时,前后改了三个版本。第一个版本,AI 几乎不主动调用。加了触发场景后,触发率上来了——但闲聊和问候里也开始搜。第三个版本,我加了三句话的排除边界,准确率终于稳了。

这篇文章不是文档翻译。是把这三个版本的迭代过程,拆成一套可以直接抄的模板。

工具描述不是文档,是 Prompt Engineering

理解这件事,后面的具体写法你才不会被"文档思维"带偏。

MCP 协议的 Tool 定义里有 9 个字段(规范版本 2025-11-25),但 LLM 选工具的时候,真正参与 attention 计算的只有三个:namedescriptioninputSchemadescription 被直接注入 system prompt,在工具选择的那一刻和用户 query 一起算相似度。

换句话说,description 是喂给 LLM 的推理信号,不是写给人类看的 API 文档

Anthropic 工程团队验证过这件事。他们在推出 Claude web search 功能时,发现 LLM 会在查询里自动追加"2025"导致搜索结果偏差。最后不是改模型,不是改 prompt,是改 tool description 修好的。

这就解释了一个反直觉的现象:改 20 个字的描述,效果可能比重写 200 行的 inputSchema 更大。因为 description 控制的是"选不选",schema 控制的是"选了之后怎么填"。如果连选都没选上,schema 写得再精细也没用。

一个具体的数字锚点:今年 6 月 arxiv 上有篇论文扫描了 2,214 个 MCP Server 的 19,200 对描述-代码对,发现 9.93% 存在描述-代码不一致——也就是近一成的 Server,description 说的是 A,实际代码做的是 B。AI 在这种描述下根本不知道工具到底是干什么的。

理解了这一点,我们再往下看具体怎么写。

三段式描述结构:一套可以直接复用的模板

先说结论。经过三个版本的迭代,我总结出的描述结构只有三段:

[一段话说明这个工具是干什么的——给 AI 一个"地图"]
[什么时候用——3-5 个具体触发场景]
[什么时候别用——排除边界]

以 kb-builder 的 search_kb 工具为例,最终版本的描述是这样的:

在码哥 AI 知识库中语义检索相关内容。覆盖 AI 编程工具、模型对比、RAG/Agent/MCP 架构、Prompt 工程、职场 AI 提效,以及后端技术栈:Redis/MySQL/JVM/Kafka/分布式/算法等。

当以下情况时使用此工具:

  • 需要了解某个 AI 技术概念的最新实践
  • 需要对比 AI 工具/模型的优劣
  • 需要查后端技术的实践经验
  • 需要查 Prompt 模板或 AI 工作流
  • 需要在写技术文章时引用已整理好的资料

当以下情况时不要使用此工具:

  • 聊天主题是前端 React/Vue/JS 知识 → 知识库主要为后端/AI 内容
  • 用户明确说"不用查"→ 不调用
  • 纯闲聊、问候 → 不调用

下面逐段拆开说为什么这样写,以及每一段常见的错误。

第一段:一句话说清楚这个工具是干什么的

很多 Server 的第一段是这样写的:

Search the knowledge base for relevant content.

这是文档思维——"我告诉你这个工具叫什么、干什么"。但 AI 需要的信息量远不止这个。AI 在做工具选择时,是在 21,000+ 个可用工具里做匹配。description 是它判断"这个工具能不能解决用户当前问题"的唯一信号。

第一段要回答三个问题: 这个工具操作的是什么数据/系统?覆盖了哪些领域?能产出什么结果?

我最初的版本只写了第一段,结果就是 AI 几乎不调用。因为它不知道知识库里有什么,无法判断用户的问题是否在你的覆盖范围内。用户问"RAG 的 chunk size 设多少合适",AI 不确定你的知识库有没有 RAG 相关的内容,就干脆不调用。

改完后加了覆盖领域的描述,AI 看到"覆盖 RAG/Agent/MCP 架构",就能做出判断:用户问 RAG,这个工具应该能帮上忙。

不要把"怎么用"写进第一段。 参数细节、调用方式放在 inputSchema 里。第一段的唯一任务是让 AI 判断:这个工具和用户当前的意图有关吗?

第二段:触发场景要具体到动作

这是整个描述里最值钱的一段——也是我从 30% 提到 85%+ 的关键。

v1.0 的触发场景我是这样写的:

Use this tool when you need to search.

错在哪?"when you need to search"是一个循环定义——等于没说。AI 不知道什么时候算"need to search"。用户问"Claude Code 好用吗",你"需要搜索"吗?AI 判断不了。

触发场景的正确写法是具体到动作和上下文

  • ✅ "当你需要对比两个 AI 工具的优劣时"
  • ✅ "当你需要在写技术文章时引用已整理好的资料时"
  • ✅ "当你需要了解某个 AI 技术概念的最新实践时"

注意这三个场景不是"同类换说法",是覆盖了三种不同的使用动机:调研对比、写作引用、概念查新。AI 看到这三个场景,在对应语境下就能精确匹配。

写触发场景的核心原则:不要告诉 AI"什么情况下要用",要告诉它"用户说了什么话时你应该用"。 把你自己代入 AI 的角色——如果你的用户说"Redis 和 Kafka 在消息队列场景下怎么选",你会不会觉得应该搜一下知识库?把这个判断写进 description。

第三段:排除边界决定下限

如果说第二段决定了触发率的上限,第三段决定了触发质量的下限。

没有排除边界会怎样?我踩过这个坑。v2.0 加了触发场景后,AI 调用频率上来了,但开始在完全不相关的上下文里也调用——用户在闲聊、在问前端问题、在讨论完全不在知识库覆盖范围内的话题时,AI 都去搜。这不是 AI 的错——它只是在执行你的 description 里写的指令:"当……时使用"。

排除边界的写法要精确到领域和用户意图

  • "聊天主题是前端 React/Vue/JS 知识"——精确到领域,不是泛泛的"不相关的主题"
  • "用户明确说'不用查'"——精确到用户指令
  • "纯闲聊、问候"——精确到对话意图

这三条每一条都对应用户的一个真实对话场景。AI 看到后能在 attention 计算时降低这些场景下的权重。

一个常见的反对意见是:"我的知识库也有前端内容,为什么要排除?"——如果你的知识库确实有,就不要写前端排除。排除边界不是模板填空,是你对自己工具定位的诚实判断。写进去的每一条都应该是你真的不希望 AI 调用的场景。

触发/排除边界决策流程

inputSchema 描述:被严重低估的另一半

大部分 MCP Server 开发者把精力花在 tool level 的 description,参数描述随便写个变量名。但参数级的 description 同样参与 LLM 推理——它在工具选择之后的"参数填充"阶段生效。

一个完整的 inputSchema 参数描述应该包含四个信息:

参数名(类型): 含义
  默认值: xxx
  取值范围: xxx(如 top_k 最大 15)
  什么时候改默认值: xxx

search_kbtop_k 为例:

top_k(integer): 返回的检索结果数量
  默认值: 5
  限制: 1-15,超过 15 自动截断
  改默认值的时机: 需要更多参考材料时增加到 8-10;只需要一个精确答案时降到 1-2

这样写和只写"Number of results to return"的区别在哪?AI 做参数填充时不是凭空选值——它会参考 description 里的约束和引导。你告诉它"只需要一个精确答案时降到 1-2",它就会在用户问"Redis 默认端口是多少"这类精确问题时自动调小 top_k,减少 token 浪费。

四个信息的优先级: 取值范围 > 改默认值的时机 > 含义 > 默认值。因为 AI 最需要的是"这个参数不能填什么",其次是"不同场景下应该填什么"。缺失取值范围描述,AI 可能填入超出限制的值导致工具调用失败。

用中文写中文场景描述

如果你的目标用户是说中文的工程师,知识库内容也是中文的,工具描述就用中文写。

这不是语言偏好问题,是 attention 匹配效率问题。MCP 的 tool description 和用户 query 在同一个语义空间做匹配。用户用中文问问题("帮我查一下 Redis 哨兵模式的选举流程"),你的描述也是中文("在码哥 AI 知识库中语义检索相关内容"),embedding 空间的 cosine similarity 更高,匹配更准。

反过来,如果你的用户用中文问,但工具描述是英文写的,跨语言语义匹配天然有损耗。跨语言 embedding 的准确率目前仍然低于同语言匹配,在工具选择这个精度敏感的环节上,这个损耗不值得。

不是所有描述都必须用英文。 MCP 协议本身是英文的,name 字段用英文保证兼容性没问题。但 descriptioninputSchema 的 property description,用你的受众的语言写,匹配效果更好。

一个反面案例:我见过一个面向中文开发者的知识库 MCP Server,全部描述用英文写。结果用户用中文问"Spring Boot 里怎么配 CORS",AI 从来没调用过——因为英文描述和中文 query 的语义距离太远,在 21,000+ 个工具的海洋里,它根本浮不上来。

如果你面向国际化用户,可以考虑维护两套描述(中英文各一套),但这是少数场景。大多数 MCP Server 的目标用户是明确的,用他们的语言写就是了。

三个工具,三条不重叠的职责

回到 kb-builder 的完整实践。我有三个工具,描述写清楚后,三者职责互不重叠,各司其职:

search_kb:有明确检索目标时用。用户说了具体要查什么。
list_kb_topics:不确定知识库覆盖范围时先用这个。相当于"先看菜单再点菜"。
get_kb_stats:排查问题或确认索引状态时用。这是一个排障工具,不是查询工具。

三个工具的分工原则:每个工具只对应一种用户意图,给 AI 明确的"选 A 不选 B"的信号。

如果 search_kb 的 description 也写了"可以查看知识库统计信息",AI 就会在用户问"知识库里有什么"时纠结——它有两个工具可选,description 都匹配。多个工具描述重叠,等于给 AI 出选择题,增加选错概率。

做工具分工时问自己一个问题:如果用户的意图用一句话描述,有且只有一个工具能对应上吗? 不能的话,说明你的工具职责边界需要重新画。

💬 你的 MCP 工具描述是怎么写的?

  • A. 只写了工具名 + 一句话描述,AI 爱用不用
  • B. 写了详细参数说明,但没加触发场景
  • C. 有触发场景,但忘了写排除边界
  • D. 三段式都用上了,效果还行

评论区说说你的选项,码哥猜选 B 的人最多 😂

MCP工具描述三段式结构模板

常见问题

Q: 我的工具是通用的(比如 execute_sql),怎么写三段式?

A: 通用工具的难点不在写描述,在定义边界。三段式更需要写:第一段明确"你可以执行任意 SQL,但只能读不能写"(如果是只读工具);第二段列出具体 SQL 场景("查询用户信息、统计订单量、对比不同时间段的销售额");第三段尤为重要——"不要用来建表/删库/改 schema"这类破坏性操作。通用工具没有排除边界,等于给 AI 发了张空白支票。

Q: 怎么知道我的描述改完之后效果有没有变好?

A: 日志。每次工具调用都记录:用户 query 是什么、AI 是否调用了工具、调用是否合理(你的主观判断)。攒 50 次手动标注后,你就有自己的 eval set。不需要 fancy 的测试框架,一个 CSV 三列足矣。关键不是工具,是持续记录的纪律。Anthropic 的工程师也是靠日志发现问题然后改描述,不是一次写对的。

Q: 工具多了之后,描述会互相干扰吗?

A: 会。MCP 生态目前平均每个 Server 有 5-13 个工具。当你的工具超过 8 个且描述有重叠时,AI 的选择准确率会明显下降。解法不是合并工具(万能工具更糟),而是检查每条 description 里的触发场景——如果两个工具的"当以下情况时使用"有重叠的用例,拆开到各自唯一的场景。

Q: description 写多长合适?

A: 三段式总长度控制在 200-400 字(英文约 150-300 words)。太短信息量不够,太长 AI 会截断。排除边界不是越多越好——3-5 条最有效,超过 7 条 AI 倾向于忽略后面的。inputSchema 的每个 property description 控制在 20-80 字。

说到底,描述写的是你对工具的理解

改了三版描述,最大的感受不是"掌握了一套模板",而是这个模板逼我把每个工具的定位想清楚——它到底解决什么问题、不解决什么问题、用户在什么场景下会需要它。

工具描述写不好的根本原因,往往不是文笔问题,是你在写代码的时候没想清楚这个工具的职责边界。模板只是把模糊感量化成具体句子——等你写"什么时候别用"这一条的时候,你会被迫面对那些你一直回避的定位问题。

我见过最好的一句工具描述,来自 Anthropic 官方 reference server 里一个文件操作工具的开头:"Read the complete contents of a file from the file system."——没有"powerful"、"comprehensive"这类自夸词,没有多余的上下文,就是一句话说清楚:读、什么、从哪。

写完这篇,我自己回去把 kb-builder 的描述又改了一版。不骗你。

下一篇打算拆 MCP 工具的参数设计——inputSchema 写得好的和写得烂的差距比 description 还大。感兴趣关注一下,不然算法不一定会推。码哥不靠标题党冲流量,每篇都是自己磨的。但这样算法不会主动推,所以把号设为星标,你想看的时候就还在。如果你身边有同事在写 MCP Server,这篇可以直接发给他——省得他从我踩过的坑开始踩。

beeaa00ee37c5db0e2fb2c5c5efe4f29

posted @ 2026-07-31 16:14  码哥字节  阅读(128)  评论(0)    收藏  举报