跳转到主要内容

MCP 工具弃用:为什么模型仍然调用旧名称

阅读需 1 分钟Tian PanTian Pan

六周前,你将 get_user_email 重命名为 lookup_contact。新名称已发布,旧的处理程序已移除,变更日志记录了这一点,你的评估集也通过了。然而上周二,一位客户支持工程师联系了你:智能体在上周的大约 3% 的工具调用中返回了错误——tool_not_found: get_user_email。那个已被重命名的名称。那个在实时系统中已经不再对外公开的名称。

先验知识(Prior)具有粘性。你的智能体正在与之对话的模型是在一个语料库上训练的,在这个语料库中,get_user_email 是询问“这个人的电子邮件是什么”的绝大多数规范方式。即使你在推理时传递的 tools 数组中仅列出了 lookup_contact,模型偶尔——在特定的上下文条件下,特别是长追踪(long traces)或错误恢复状态下——仍会退回到它记忆中的名称。直接切换并不能消除长尾效应;它只是将软故障变成了硬故障。

这就是关于 MCP 版本控制的公开讨论中一直绕不开的失效模式。服务器动态宣告工具;客户端刷新;协议提供了 tools/list_changed 来提示过时的缓存。这些都没错。但它们都没有解决模型的先验知识问题。协议是简单的部分。困难的部分在于,JSON-RPC 管道另一端的东西是一个概率分布,它看过五年的 GitHub 代码,而你的变更日志并不在它的权重(weights)中。

直接切换模式对工具而言是错误的

大多数团队参考的心理模型是 API 弃用:宣布一个停用日期,发送六个月的 Deprecation 请求头,然后在切换日返回 410 Gone。这种模式假设调用者是一个能够读取响应代码并更新其代码的软件。它适用于人类编写的 REST 客户端,因为人类对 410 的反应是提交一个 Jira 工单。

模型不会读取 410 并提交 Jira 工单。模型收到 tool_not_found 错误后,会根据其训练分布和周围的上下文决定做什么,并且经常会用同一个名称重试。或者它会向用户道歉。或者它会幻觉出另一个同样错误的工具名称。或者它通过另一条路径成功了,而你永远不知道它曾尝试过已弃用的名称,因为错误已被吸收进了一个恢复分支中。

直接切换模式还假设弃用窗口是昂贵的——你希望窗口尽可能短,以便移除旧代码。对于模型来说,窗口是廉价的。弃用途径只是一个转发到新名称的单行垫片(shim)。真正的成本是在垫片消失那一刻你所创建的失效模式。

在 MCP 介导的智能体系统中,工具重命名不是 API 版本控制事件。它们是模型输入分布的偏移,需要像迁移数据库列时使用的那种双写(dual-write)机制。

真正有效的弃用垫片

在生产环境中经受住考验的模式包含三个部分,MCP 规范都没有强制要求这些,但协议本身都允许。

保持两个名称同时在线。 当你将 get_user_email 重命名为 lookup_contact 时,在至少一个模型生成周期和客户端更新周期(以较长者为准)内,在 tools/list 中同时宣告两者。旧工具的处理程序是对新工具的单行转发,参数保持一致。Schema 应该完全相同或更加宽泛。旧工具的描述应以弃用标记开头——[DEPRECATED: use lookup_contact]——模型有时会读取并对此做出反应,而人类在 grep 你的清单文件时也肯定能看到。

记录对已弃用名称的每一次调用。 为其标记原始会话 ID、模型版本、在追踪中的位置,以及该调用是模型的第一次尝试还是在其他失败后的重试。这是你目前缺失的数据,也是唯一能告诉你何时可以安全移除垫片的数据。没有它,你的移除决定就像是在抛硬币。

根据流量而非日期定义移除触发器。 “我们将在六周后移除 get_user_email”是错误的承诺。“一旦我们路由到的所有模型版本中,每周调用次数连续两周低于 N 次,我们就会移除它”才是正确的做法。模型正在通过实际表现告诉你它何时内化了新名称;让它自己决定。

会员专享

余下内容仅对会员开放。

会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。

  • 完整文章,包含未公开存档的部分
  • 可落地的工作框架,附带权衡与决策依据
  • 新文章抢先看,先于公开发布

随时取消 · 一次订阅,畅读全部

参考资料

保持联系,关注我获取更多内容

阅读需 9 分钟

MCP Server 蔓延:无人监管的无边界工具表面

每个团队都在接入另一个 MCP Server,Agent 的工具表面在没有负责人、没有预算的情况下不断扩大,且每一轮对话都要支付 Token 税。本文探讨这种蔓延如何破坏选择准确性,以及什么样的策展纪律可以修复它。

insider
mcp
阅读需 8 分钟

你的工具描述是模型遵循的指令通道

工具描述是模型视为权威指令的散文,但代码审查和输入清理从未检查过它们。本文将探讨被投毒的元数据和地毯式攻击是如何渗透进来的,以及弥合这一差距的规范。

insider
ai-engineering
阅读需 10 分钟

那些被你的智能体“触发并遗忘”的异步工具调用

函数调用将同步和异步工具视为相同的形式。智能体触发了一个任务,收到了一个 ID,随后标记该步骤已完成 —— 而实际工作却从未落地。

insider
ai-agents
阅读需 10 分钟

你的智能体把指针当成了值:工具输出里的引用 vs 值

当工具的返回值是 ID、路径或 URL 时,它实际上是在让智能体去做一次解引用。但模型何时解析、何时直接"假装已解析"地继续往下编,这套策略是隐式的、不一致的、悄无声息地出错的。把这层间接寻址显式地写进类型里。

insider
ai-engineering
阅读需 10 分钟

为什么弃用 AI 功能比你想象的更难:用户构建了你看不见的信任脚手架

停止 AI 功能的服务不像停用 API。契约是模型被观察到的行为,用户会在其上构建不可见的脚手架,而这些脚手架会在切换时断裂。

insider
ai-engineering