跳到主要内容

9 篇博文 含有标签「deprecation」

查看所有标签

那个谁也不敢从注册表里删掉的死工具

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个工具在你共享的 agent 目录里已经躺了十四个月。它是某位早已离职的工程师为两次组织重组前就被砍掉的工作流接上的,对接的后端服务的归属如今也没人说得清。这个工具定义占 380 个 token。它会出现在组织里每一个 agent、每一轮对话的系统提示中,因为没人能证明它没在被使用,而一旦证明错了,代价比永远扛着它还高。

这个工具就是那个没人敢删的数据库字段,就是那个日志早已轮转干净的定时任务,就是那条你 grep 不到任何引用、但因为 eval() 存在所以你不敢动的死代码。Agent 版本的这个问题更糟,因为持有成本不只是磁盘上的几个字节——它是用 token、用选择准确率、用安全攻击面付出的,而且是在你平台跑的每一次推理里付出。

你无法通过邮件给模型发送变更日志:为什么当调用者是 LLM 时,API 弃用机制会失效

· 阅读需 11 分钟
Tian Pan
Software Engineer

API 弃用是一种建立在接收者具备阅读能力这一假设之上的通信协议。你发布更新日志、向注册开发者发送邮件、添加 Deprecation 标头、提前六个月发出通知,并寄希望于另一端的人类能看到警告、提交工单,并在停用日期之前完成迁移。当你的最活跃调用者变成了语言模型的那一刻,这整套工作流程就悄无声息地失效了。

LLM 不会订阅你的开发者时事通讯。它没有 Slack 频道让人转发你的迁移指南。它在每一次调用中重新发现你的 API —— 或是通过被交付的工具描述,或是通过一份可能已经过时 18 个月的文档页面,亦或是基于其训练数据中对你 API 样子的记忆。这里没有一个你可以进行版本化、通知或传呼的持久客户端。每一次请求都是与一个实体的全新博弈,而这个实体既不记得你上一次的公告,也没有义务阅读你下一次的通知。

这并非假设。随着 Agent 逐渐成为内部和外部 API 的主要消费者,后端团队沿用了 15 年的弃用策略手册正在以一种特定的、可诊断的方式失效 —— 且大多数团队只有在发现一个“已弃用六个月”的端点仍在生产环境中为 Agent 提供服务、且没有路径使其停止时,才会意识到这一点。

没人写的 AI 功能下线指南

· 阅读需 14 分钟
Tian Pan
Software Engineer

每个 AI 组织都有一个坟场。不是服务的坟场——服务会有操作手册(runbook)、弃用横幅、30 天的迁移窗口,以及在平台团队季度路线图上的位置。这个坟场是属于 功能 的:从未转正的智能摘要 Beta 版、两个大客户据此构建了工作流的自动分类器、演示效果极佳但在灰度发布后无人问津的 Agent 流程。弃用一个端点很容易。但与之关联的其他四个东西——提示词(prompt)、评测员(judge)、回归测试集(regression set)和事故记忆(incident memory)——才是真正需要一个季度才能搞定的,而且团队中没人写过这种手册,因为没人会因为下线某个功能而获得晋升。

这就是差距。大多数关于“模型弃用”的公开讨论都是针对供应商侧的下线:GPT-4o 在某天停止服务,Assistants API Beta 版在 8 月 26 日下线,DALL-E 3 在 5 月 12 日退休,而你的平台团队有一个通知期来进行迁移。这个问题有现成的手册,因为供应商发布了日期,迁移是被迫的,而且工作量可以塞进一个 Sprint 中。而“内部”版本——当你决定你构建的一个功能未能转正并必须将其撤除时——则没有任何这类强制因素。弃用日期由你说了算。迁移路径由你来构建。而且你必须退役的产物不是单个端点,而是一堆纠缠在一起的、与模型相关的资产,你的监控系统几乎感觉不到它们的存在。

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

· 阅读需 10 分钟
Tian Pan
Software Engineer

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

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

撤回的代价:为什么撤回一项 AI 功能比上线它更难

· 阅读需 11 分钟
Tian Pan
Software Engineer

你现有的发布流程是为发布不可逆、回滚无成本的世界设计的。AI 颠覆了这一点。一旦某个功能上线了一个季度,撤回它的破坏成本就会超过发布它的成本 —— 而且你对该功能收到的最响亮的客户反馈,将是在你取消它的那天,而不是它发布的那天。

团队会为每次 AI 发布构建一个紧急开关(kill switch)。但没人会去拉动它。不是因为功能完美无缺,而是因为等到有人想撤回时,撤回的成本已经复合增长,超过了发布标准所考虑的任何因素。功能旗标(Feature flags)假设世界是对称的:开启前的系统和开启后的系统是同样有效的静止点,你可以根据喜好在它们之间移动。AI 功能默默地打破了这一假设,而团队围绕可逆旗标构建的发布流程,则悄无声息地忽略了这种不对称性。

团队第一次注意到这一点,是在有人提议弃用该功能时。

下线一个 Planner 已产生依赖的 Agent 工具

· 阅读需 12 分钟
Tian Pan
Software Engineer

你从工具目录中注销了 lookup_account_v1,换上了 lookup_account_v2,并修改了系统提示词中的一个段落来指向新名称。测试通过了。三天后,支持工单开始提到助手“一直尝试调用不存在的东西”,或者——更令人不安的是——它用自信、看似合理的数字回答客户问题,却根本没有查询数据库。弃用并没有在通信层失败,它在规划器(planner)中失败了。

!["https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=%E4%B8%8B%E7%BA%BF%E4%B8%80%E4%B8%AA%E8%A7%84%E5%88%92%E5%99%A8%E5%B7%B2%E5%AD%A6%E4%BC%9A%E4%BE%9D%E8%B5%96%E7%9A%84%E6%99%BA%E8%83%BD%E4%BD%93%E5%B7%A5%E5%85%B7"]

这是将工具弃用视为语法变更与将其视为行为迁移之间的差距。智能体不仅是在注册表中拥有你的函数;它还拥有数月的计划、多步配方(recipes)以及通过该函数作为检查点的 few-shot 示例。撤掉它更像是停用下游服务非正式硬编码的内部 API——只不过下游服务是一个你无法通过 grep 搜索其习惯的模型,而且当它偏好的工具消失时,它的兜底方案是编造一个。

停用 AI 功能是一次信任事件,而非简单的功能弃用

· 阅读需 14 分钟
Tian Pan
Software Engineer

数据指标告诉你该砍掉它了。3% 的月活跃用户。评估(Eval)刷新已经推迟了两个周期。Prompt 中还有一个一年前留下的 // TODO: 在脱离旧版工单架构时重新审视。你的资深 AI 工程师每月要花整整一周的时间来照看这个功能 —— 模型升级、标签偏移,还有一个只要上游 API 更改日期格式就会挂掉的工具集成。每次季度评审,总有人会问为什么这个助手仍然存在,而每个季度的回答都是“我们还没顾上处理它”。

于是你写了一份弃用备忘录。你参考了平台团队完善的 API 停用手册:提前 6 个月的公告、迁移指南、产品内横幅提示、面向合作伙伴的 Webhook,以及常见的 Sunset: HTTP 标头。你在周二发布了它。到了周四下午,你的客户成功经理(CSM)转发来的邮件听起来完全不像是对 API 弃用的投诉。它们听起来更像是分手信。

在那一刻,大多数团队才意识到他们将一个类别错误带到了生产环境。你要弃用的不是一个 API,而是用户与一个能够回应他们的实体建立的关系。

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

· 阅读需 11 分钟
Tian Pan
Software Engineer

2025 年 8 月,当 OpenAI 试图从 ChatGPT 中移除 GPT-4o 时,遭遇了强烈的抵制——有组织的标签、付费用户威胁取消订阅、几天内的公开反转——最终迫使公司将其恢复为默认选项,并承诺在未来任何移除之前提供“实质性通知”。替换它的模型在团队关注的每一项基准测试中都表现得更好。但这并不重要。用户已经花了几个月的时间来了解该模型的怪癖,根据其失效模式校准自己的判断,并将它的特定措辞整合进团队从未检测过的工作流中。用“更好的版本”替换它,会让这种校准归零。

这种失效模式是标准的弃用策略手册所未涵盖的。下线一个常规的 SaaS 功能——宣布、迁移、灰度发布移除、退役——假设用户契约是 API 接口。而对于 AI 功能,契约是模型的观察行为:措辞、倾向、失效模式,以及它处理歧义的特定方式。用户在这些行为之上构建了“脚手架”,而这些脚手架大多存在于他们的头脑中、笔记本电脑上以及你的团队从未触及的下游系统中。

工具 Schema 弃用:为什么你不能直接重命名参数

· 阅读需 13 分钟
Tian Pan
Software Engineer

你在一个工具 schema 中将 query 重命名为 search_query。变更日志写着:“非破坏性更名:更清晰的命名”。PR 通过了评审。三天后,你的支持队列里塞满了关于助手“搜索结果为空”的报告。发生的事情并不是讨论帖里任何人会告诉你的。智能体(Agent)并没有失败。它们提交了旧的字段名称,你的工具服务器忽略了未知的 key,将 search_query 默认设置为空字符串,并返回了零条结果。模型看到一个看起来很正常的空响应,便自信地向用户解释为什么他们的查询没有返回任何相关内容。

这是智能体工程(Agent Engineering)中不符合从 REST API 版本管理借鉴来的心理模型的部分。发送已重命名字段的 REST 客户端会收到 400 错误和清晰的报错——该字段要么存在于验证器中,要么不存在。而发送已重命名字段的智能体得到的则是静默接受、一个毫无意义的结果以及一段幻觉式的合理解释。失败不在于线路传输(the wire);而在于运行时 schema 与模型关于工具外观的上下文心理模型(in-context mental model)之间的脱节。

工具 schema 存在于两个地方。第一个是运行时规范(runtime spec)——即你发布到 MCP 服务器或函数调用注册表的 JSON schema。第二个是该规范在模型中的上下文表示,它通过系统提示词(system prompt)中的 few-shot 示例、智能体在多轮任务中看到的序列化工具历史记录,以及模型在预训练期间已经吸收的关于你 API 的知识来在每一轮对话中不断强化。你可以原子化地更新前者,但你无法原子化地更新后者。这种不对称性就是问题的核心,这也是为什么“仅限添加,永久保留”——protobuf 和 GraphQL 运营商在十年前就已经内化的原则——现在需要迁移到工具 schema 层了。