把模型和 prompt 钉死在版本里:别让上游悄悄换引擎,你的任务半夜翻船

凌晨三点,自动任务跑完一整夜,仪表盘上解析成功率从 99% 掉到 71%。第一反应是数据源出了问题,翻了两个小时日志才发现,尴尬得很:几天前路由器做了一次上游池子迁移,我们一直用的 qwen-cloud-plus 这个别名,被悄悄指到了另一个模型上。prompt 一个字没动,但它背后的权重换了。原本稳定吐 JSON 的

专属插画
把模型和 prompt 钉死在版本里:别让上游悄悄换引擎,你的任务半夜翻船

把模型和 prompt 钉死在版本里:别让上游悄悄换引擎,你的任务半夜翻船

凌晨三点,自动任务跑完一整夜,仪表盘上解析成功率从 99% 掉到 71%。第一反应是数据源出了问题,翻了两个小时日志才发现,尴尬得很:几天前路由器做了一次上游池子迁移,我们一直用的 `qwen-cloud-plus` 这个别名,被悄悄指到了另一个模型上。prompt 一个字没动,但它背后的权重换了。原本稳定吐 JSON 的输出,开始时不时回一段自由文本,下游那一排 `json.loads` 全在做无谓的重试。

修掉它只花了一行,把别名换成了带日期戳的版本名。但这事让我意识到,我们一直把"模型"当成一个固定的服务来调,其实它是会漂移的。别名背后指什么,上游说了算,而它换引擎这件事,通常不会通知你。你以为你在评的、回归的、兜底的,都是同一个模型,实际上昨天和今天可能根本不是。

后来我们把三样东西钉进了配置,写死在仓库里,谁改谁留记录。

第一是模型版本。生产任务里禁止出现裸别名,必须写成 `qwen-cloud-plus-2026-08` 这种带快照日期的名字。想升级不是随手改字符串,要走一次对比:用下面那组固定输入跑旧版和新版,把差异拉出来人工过一遍,通过了才把配置里的指针往前挪。上游哪天又换池子,顶多是出一个"新版本待评审",而不是让线上任务自己变成另一个物种。

第二是 prompt 本身。prompt 看着是几行字,其实是核心资产,也是最容易被人随手"顺手优化"然后悄悄改坏的东西。现在每个生产 prompt 都有一个独立的文件和版本号,改 prompt 等于改代码,得留 diff、得有人看一眼。别再让 prompt 只活在某个脚本的字符串常量和某个人脑子里。

第三是我认为最值钱的一条:一组很小的固定输入集,我们叫它 golden set。就十几二十条,全是历史上真实踩过坑或者真实验证过该给什么答案的请求,配上"标准答案"。升级模型、改 prompt、上游被动迁移,任何一项发生,就把 golden set 整个跑一遍,逐条对。它是你唯一的、不依赖线上流量的回归尺子——线上样本会漂移、会带业务噪声,但 golden set 是你自己认定过的基准。

有人会说就十几二十条,值不值得专门维护一套基准。我的回答是,解析成功率那两个百分点背后,是任务队列卡到早上九点、人工清理半天。golden set 花的功夫,是替你把"半夜翻船"从概率事件变成基本不可能。

最后这点是踩了坑才补的:光钉版本不够,还得把它显性地打出来。现在任务每跑一次,启动日志第一行就写清楚模型版本、prompt 版本、构建时间。出问题不用猜当天用的是哪套,一行日志直接对死。可观测性之前我们花成本上了心跳和告警,解的是"任务有没有在跑",这三样钉版本解的是"跑的是不是我以为的那套",两件事不重叠,都得有。

一句话收尾:把模型当会漂移的依赖来管,像管一个你自己没控制发版节奏的第三方库。别名是给人用的,版本是给生产用的,golden set 是你判断"换的那个版本到底行不行"的那把尺子。

留言区

欢迎分享你的想法!

发表留言

0/500

加载留言中…