跳到主要内容

提示词弃用合约:为什么措辞清理是一项破坏性更新

· 阅读需 11 分钟
Tian Pan
Software Engineer

系统提示词(system prompt)上一个四个词的修改——用 "respond using clean JSON"(使用干净的 JSON 响应)替换 "output strictly valid JSON"(输出严格有效的 JSON)——在评估(eval)中一度没有引起任何波动。它在周四发布,却在周五凌晨 4 点被回滚,因为结构化输出的错误率从 0.3% 飙升到了 11%。提示词并没有变糟。它只是变得“不同”了,而下游解析器在无人察觉的情况下,已经固化(pinned)在了 "strictly valid" 这个词组上。

这是大多数提示词工程(prompt-engineering)团队尚未建立工具来应对的失效模式:提示词被视为作者拥有的文本,而实际上它是与作者从未见过的消费者之间的一份合约。这些消费者中,有些是逐字引用原句的其他提示词;有些是 JSON 模式(JSON schema)字段锚定在特定形容词上的工具描述;有些是其评分标准(rubrics)要求裁判(judge)检查“严格有效格式”的评估(evals);还有一些是解析器——最脆弱的一类——其正则表达式是根据模型输出的精确前导语(preamble)进行校准的。

一次“小小的措辞清理”会悄无声息地破坏解析器、导致裁判校准偏移,并使数周的评估运行失效。这些失败都不会在 PR(拉取请求)中显示出来,而是在一周后作为“偏移”(drift)出现在仪表盘上。

提示词有消费者,且消费者已被固化

当你发布一个 REST 端点时,消费者是“大声”的。他们会编写集成测试,如果你更改了某个字段,他们会出现在你的错误日志中,如果你将 userID 重命名为 user_id,他们不出一小时就会提交一个 Jira 工单。而当你发布一个提示词时,消费者是沉默的——而且他们的数量比你想象的要多。

梳理一个典型的 AI 功能并数数看:

  • 其他引用你的提示词。 一个检索感知的系统提示词说“遵循规划器使用的格式”,这依赖于规划器格式的稳定性;一个聊天模式提示词逐字粘贴智能体的指令,这依赖于智能体措辞的稳定性。这些引用通常是不可见的——在集成时通过复制粘贴完成,而非链接。
  • 工具描述。 函数调用工具的自然语言描述(“当用户想要按助手被指示的措辞方式查找订单时调用此工具”)继承了系统提示词的假设。修改系统提示词的词汇,工具描述现在描述的就是模型不再产生的行为了。
  • 评估和裁判标准。 一个评分标准为“模型是否在严格有效的 JSON 信封中响应”的 LLM-as-judge 裁判,已经针对数千个过去的输出进行了校准。将系统提示词改为 "clean parseable JSON",模型输出的内容相同,但由于锚定在 "strictly valid" 这个词组上,裁判开始将其标记为模棱两可。校准偏移(Calibration drift)是基于裁判评估的已知失败,而提示词修改是其最可靠的诱因之一。
  • 解析器。 正则提取器、JSON 形状验证器和思维链提取器都依赖于稳定的前导语。将 "Sure, here's the response:" 替换为 "Here you go:",对作者来说是一个字符的差异,而对消费者来说则是解析失败。
  • 链式智能体。 当智能体 A 的输出是智能体 B 的输入时,第二个智能体的提示词已经过调整,以期望从第一个智能体那里获得特定的形状。对智能体 A 进行的“润色”变成了智能体 B 的回归(regression),且由于评估是按智能体进行的,没人能发现这一点。

每一个这样的消费者都是你在不经意间交付的一份合约。措辞就是 API。措辞就是下一个系统要解析、评分或引用的内容。

为什么“评估通过”不代表可以安全发布

大多数团队发布时的直觉——“如果评估套件全绿,那么提示词更改就是安全的”——是错误的,而且在事故发生之前很难察觉。

评估针对的是输出(output),而消费者固化的是措辞(wording)。这两者是不同的层面。

提示词更改可以使评估集上的输出分布保持基本不变(因此得分不变),但同时又改变了表面形式,足以导致下游解析器停止匹配。裁判看到的答案仍然正确;解析器看到的文本却无法再从中提取字段。评估报告显示绿色,而生产环境则报告来自消费服务的 4xx 错误峰值。

这与不破坏 API 行为(behavior)、仅破坏其接口(interface)的向后不兼容 API 更改的形式相同。REST 团队绝不会将 created_at 重命名为 creationTime 并称之为补丁发布(patch release)。而提示词团队每周都在发布类似的东西,并称之为“小小的清理”。

解决方法不是更大规模的评估,而是意识到提示词有两份合约:一份是评估可以衡量的行为合约,另一份是评估无法衡量的措辞合约。两者都需要进行版本管理。

提示词弃用合约长什么样

直接借用 API 管理规范:

带有语义化版本(semver)分类的提示词版本注册表。 每个提示词都有一个版本。修改在 PR 时进行分类:

  • 补丁(Patch) —— 拼写错误修复、仅限注释的更改、空格。不能更改可观察的措辞。
  • 次版本(Minor) —— 添加部分、新约束、不替换现有示例的新示例。不能删除或重命名其他工件可能引用的短语。
  • 主版本(Major) —— 任何删除、重命名或重构已被引用、解析、评审或链式调用的措辞的操作。需要填写弃用分录(deprecation entry)。

这种分类属于 PR 模板的一部分,就像数据库迁移声明它是扩展还是收缩一样。

为每个提示词建立消费者索引。 这是一份与提示词存放在同一个代码库中的列表,记录了每一个固化在其中某个短语上的工件。引用系统提示词的工具描述、锚定在特定形容词上的裁判标准、正则表达式包含字面前导语的解析器,以及复制了某个片段的其他提示词。消费者索引是作者在合并之前需要看到的“爆炸半径”。该索引通过在消费者端添加回溯链接来维护(例如,“此正则依赖于提示词 X v3.2 中的 'strictly valid'”),并通过工具进行反向索引。

重大更改的弃用窗口。 当你删除或重命名消费者依赖的措辞时,旧措辞应与新措辞并存一个定义的周期——长到足以让每个消费者完成迁移。模型会同时获得两种措辞,消费者会收到通知,只有在消费者索引报告剩余固化数为零后,旧措辞才会退役。这与在客户端更新期间同时保留 created_atcreationTime 字段一个季度的模式相同。

在未声明的破坏性变更上报错的 CI 门禁。 如果一个 PR 删除了一段出现在消费者索引中的短语,但没有提升主版本号并添加弃用分录,则 PR 失败。不是警告——是失败。这是承重部分,因为其余的规范都是自愿的,而在发布压力下,人类会跳过自愿的规范。

这一切并不稀奇。这几乎是逐行复刻了一个成熟的后端团队处理公共 REST 端点的方式。

最难的部分是消费者索引

注册表和 CI 门禁是机械化的。消费者索引则是需要组织协调的部分,因为消费者通常是投机性地自行添加,而作者往往没有动力去注册。

使其变得可处理的三种模式:

消费者端的反向链接,而非提示词端。 依赖于“严格有效的 JSON”的评审准则(judge rubric)会获得一个头部注释:# depends on system_prompt v3.x phrase "strictly valid"。正则表达式提取器也是如此。消费者携带依赖声明,因为消费者才是会因变更而崩溃的一方。然后工具遍历代码库,并将这些声明反向索引到提示词的消费者视图中。

短语级指纹识别。 对提示词中起关键支撑作用的短语进行哈希处理,并检测版本之间哈希值的变化。随后 CI 门禁可以询问:“短语 X 已更改;消费者索引列出了三个绑定到短语 X 的产物;弃用条目是否存在?”这与公共资产的内容哈希(content-hash)思路一致 —— 你不需要枚举所有消费者来检测破坏性变更,只需检测契约界面(contract surface)发生了移动。

针对新消费者的“禁止引用”规则。 想要依赖提示词用词的新消费者必须通过命名且带版本的摘录(excerpt)来进行,而不是直接复制粘贴。摘录成为了 API。提示词作者可以自由更改摘录周围的所有内容;而摘录本身遵循弃用规则。这在结构上等同于强制 API 消费者依赖类型化的客户端,而不是对 JSON 结构进行逆向工程。

做对这件事的团队会将消费者索引视为代码库的一等公民,在 PR 中进行评审,就像对待 CODEOWNERS 文件或 OpenAPI 规范一样。

当你以这种方式处理提示词时会发生什么

主要是两件事。

首先,“微小的用词清理”不再是免费的。它们会像任何其他破坏性变更一样,根据弃用周期计算成本。其中大多数清理在成本核算后都无法通过 —— 这是正确的,因为其中大多数也并不值得引发一次解析器故障。那些真正值得的清理会伴随着弃用窗口和干净的迁移而推进,团队由此学会区分修饰性编辑和契约性编辑。

其次,提示词代码库开始看起来像一个正常的 API 代码库。有了注册表、版本规范、CI 门禁、消费者索引和弃用政策。那些绝不会在没有迁移计划的情况下发布 /v1/users 重命名的工程师,也开始停止在没有计划的情况下发布系统提示词(system-prompt)重命名。

这一切背后的架构认知是:提示词具有公共 API 的所有契约稳定性问题,却没有任何配套工具。它们比类型化 API 更脆弱,因为消费者被绑定在自然语言短语上,而不是结构化的字段名。它们更加分散,因为消费者分布在提示词、工具、评估脚本、解析器和链式智能体中。它们也更隐形,因为标准的提示词工程工作流中没有任何环节会揭示消费者端的情况。

除非负责发布提示词的团队像对待 /v1/users 接口一样应用同样的工程纪律,否则周四发布的用词清理仍会在周五凌晨 4 点呼叫值班工程师 —— 而事后总结会继续错误地得出结论:模型是不稳定的那部分。

References:Let's stay in touch and Follow me for more thoughts and updates