AI 功能有三层独立衰减:模型(第三方控制有截止日)、提示词(不断累加无删除)、架构(基于旧模型假设)。
六个月后,一个 AI 功能的模型已被更新版本替代,prompt 积累了大量无人能说清价值的从句,以及一组关于模型能力边界的假设——这些假设在当初是对的。每个衰减机制各有各的运行方式,各有不同的速度,知道哪个是哪个,决定了下午的时间花在哪里。
三个层次,三种衰减机制
一个 AI 功能有三个会老化的层次。将它们分开的目的在于,它们的衰减不是「东西会过时」这种笼统现象——每层都有具体的成因,成因本身就指向了修复方法。
最重要的区分在于第三层。Prompt 和模型的衰减是可见的——一条弃用通知会到来,prompt 文件会越来越长。架构的衰减是无形的,因为正常运行的代码不会宣告它存在的理由已经过期。一个三阶段管道之所以把文档拆开,纯粹是因为当时的模型上下文窗口不够用——它会完美地继续运行下去,产生三倍于实际需要的成本和延迟,而且会永远这样运行下去。
谁先出问题,以及为什么
按紧迫程度排序,这不等于按体量排序:
模型,因为它有截止日期。 提供商会提前公告弃用窗口,而绑定到一个即将退役模型上的功能,无论是否有人为此做过规划,都被迫要迁移。这是唯一一层,不作为就会在已知日期发生故障,这让它是唯一有真正截止时间的层次。
Prompt,因为它阻碍模型变更。 针对某个模型调优过的 prompt 无法干净地迁移到另一个模型,所以 prompt 债务才是迫使迁移成本高昂的原因。一个没有任何 case 依附的 prompt,根本无法以任何有原则的方式迁移——你换了模型,输出就变了,而没有任何东西告诉你这个变化是好是坏。
架构,因为它是最大的奖赏,而且根本没有截止日期。 去掉一个阶段,就永久性地去掉了它的成本、延迟和故障模式。永远不会有任何东西主动提示你做这件事,这恰恰就是为什么它需要一个计划内的审查,而不是等触发事件。
还有第四样会老化的东西,但它不是一层:评估集。发布时建立的 case 集代表的是六个月前的流量。如果使用场景已经扩展,那这个集合现在测量的只是一个切片,所有基于它做出的决策都继承了那个偏差——这让刷新评估集成为信任下面所有工作的前提条件。
一个下午,日志开着。六个问题,按这个顺序问,因为每个问题的答案会改变下一个问题的含义。
流量和我们想的一样吗? 输入长度分布、语言比例、主要意图、各分段的体量。与发布时对比。分布一旦偏移,下游所有东西都失效,包括评估集。
一次成功的结果现在要花多少? 不是每次调用的成本——是每个结果的成本,包含重试、降级、验证器、分类器以及审核时间。如果最初写过计划的话,和那个数字对比。
Prompt 中哪些从句仍然值得保留? 拿最长的那个 prompt,对每个段落问:如果没有它,哪个 case 会失败。没有任何答案的段落就是候选删除对象——如果有 case 存在,删除是可测试的,这就是 case 存在的意义。
哪些阶段是因为旧有约束而存在的? 对管道中的每一步,问它绕过了什么限制,那个限制现在还存不存在。分块、多遍摘要、正则修复 JSON 以及复杂重试梯队是常见的嫌疑对象。
模型弃用时间线是什么? 检查每个在用模型的公告日期,包括降级用的备用模型。绑定到已退役模型的备用方案,是一条在终于需要时才会失效的降级通路。
审核队列和故障日志这六个月说了什么? 修正记录是一个没人要求但天然存在的标注数据集。读一些样本;失败模式不会是 prompt 正在防御的那几种。
改变事物的顺序
同时改两样东西会让两样都变得无法衡量,而这就是 AI 功能重构出问题的典型方式:一切都变了,质量也变了,但没人能归因。
0. 从近期流量刷新评估集 (在这步完成之前,下面的所有数字都不可信)
1. baseline:用当前模型 + 当前 prompt 运行 -> 这是要超越的基准数字
2. 只改一样东西:
新模型,相同 prompt -> 隔离模型的效果
相同模型,删减后的 prompt -> 隔离 prompt 的效果
去掉某个阶段,其余不变 -> 隔离架构的效果
3. 和 baseline 比,不是和你记忆中的数字比
4. 如果两样改动都想做,按顺序执行并保留中间状态的数字——
否则一次回归将无法归因,你会回滚错误的那个
5. 在生产环境 canary,再默认开启,并且让之前的配置
可以通过 flag 触达,而不是靠回滚
第零步是那个在时间压力下最容易被跳过的一步,而跳过它会让之后所有数字都变得毫无意义。步骤四和步骤五在生产端的机制——百分比灰度发布加自动回滚、用真实流量回放新模型——在别处已有充分讨论;这里要强调的是一次只动一层的纪律。
向更少重构
这类审查最常产生的有价值结果通常是减法,带着这个预期进去比带着一堆改进清单进去更值得。
一个可以删除的阶段。 价值高于任何 prompt 改进:它永久性地去掉了一次调用、一个故障模式、一部分延迟贡献和一段代码。在优化之前,对照当前能力检查每个受限 workaround。
一个可以缩短的 prompt。 更短的 prompt 每次调用成本更低,而且指令数量越多指令遵循质量越差,所以删除无效从句既能改善行为也能降低价格。只有在有 case 的前提下才可能做到;没有 case,没人敢动。
一个可以变成代码的模型调用。 六个月的输出常常揭示某个步骤的答案几乎是确定性的——那个分类器对可识别模式返回相同标签,那个格式化步骤用模板就能完成。每转化一个,就永久性地降低了成本和方差。
一个可以退役的功能。 审查是问有没有人用它的好时机。一个从未增长过使用量的功能,花着钱做着维护,是候选删除对象,主动做这个决定远好过让它无人看管地衰败下去——这是事后分析报告中被称为「在运行,但没人用」的那种失败模式。
Writing the Post-Mortem for an AI Feature That Failed
Anti-Pattern: The Prompt Nobody Owns
A Checklist Before You Ship Anything AI