prompt-versioning-across-backends · ZH · 2026-11-04

后端轮换时如何钉住同一个提示词版本:给提示词打标,让换模型不悄悄改变输出

当聚合站按 model=auto 或别名路由请求时,后端可能在无提示的情况下切换到另一家厂商。本文介绍一套可落地的做法:给提示词打版本标签、按响应记录实际承接后端、在上线前做输出差异对比,避免换模型悄悄改变输出。

为什么提示词需要版本标签

在聚合站里,请求写的往往是 model=auto 或某个别名。路由层会根据可用性、负载或贡献 key 的分布选择实际承接后端。这意味着同一个请求,今天落到 Claude,明天可能落到 GPT 或 DeepSeek。

模型本身变了,输出风格、长度、格式遵循度都会变。如果提示词没有版本标识,你很难判断「输出变了」是因为提示词改了,还是因为后端换了。

版本标签的作用不是控制路由,而是让「提示词身份」和「模型身份」解耦:提示词是一个有版本的固定资产,后端是每次调用都可能变化的执行环境。

给提示词打标的三个层次

1. 内容版本号

在提示词文本的可控位置(通常在系统提示末尾或元数据里)放一个稳定标识,例如 prompt_id 加语义化版本。同一份提示词修订一次就升一版,不要复用旧号。

这条信息有两个用途:一是回放时能定位到确切的提示词快照,二是下游日志可以按版本聚合。

2. 变量契约

模板里插入的外部变量(用户输入、检索片段、工具返回)要有固定字段名和顺序。变量契约变化也应视为版本变更。否则你以为是提示词稳定,实际上输入结构已经变了。

3. 期望输出契约

把「这段提示词应该产出什么结构」写成可检查的断言:JSON 字段是否齐全、是否必须带某个标记、长度区间。它既是测试用例,也是版本的一部分。

从响应里识别实际承接后端

聚合站通常在响应体或响应头中返回实际使用的模型标识。写法可能因网关而异,需要在文档里确认字段名,例如响应中某个 model 字段、x-* 响应头,或者 usage 附带的模型信息。

建议按以下顺序建立记录:

  • 每次调用都记录:请求侧写请求的 model 参数和提示词版本号;响应侧写实际模型标识、时间戳、请求 ID。
  • 本地落一份调用日志,字段至少包括 promptid、promptversion、requestedmodel、servedmodel、request_id、输入 token 与输出 token。
  • 建立别名到真实模型的映射快照。别名可能被重新指向,定期拉取一次映射并附上时间,回放时才能还原当时的语义。

如果响应里没有直接暴露承接后端,不要猜。可以在文档中确认可用的观测手段,或与站点确认日志字段;猜出来的模型归属会让后续对比全部失效。

在路由变更前做输出差异对比

构建小规模固定评估集

从真实流量里挑出有代表性的输入,覆盖主要任务类型和边界情况。数量不必大,关键是稳定、可重复,并且每条都绑定提示词版本号和期望输出契约。

A/B 对比同一提示词在不同后端上的输出

对同一批输入、同一版提示词,分别指定明确模型和走 auto 各跑一次。比较维度建议:

  • 结构合规:是否满足输出契约
  • 语义一致性:关键结论是否相同
  • 长度与风格漂移:是否明显变长、变短、语气改变
  • 截断与拒答:是否出现异常结束

结构合规适合自动判定,语义一致性适合抽样人工看。不要只看平均分,要看分布和失败样本。

把比较结果写回版本记录

每一版提示词的发布记录里,附上它在哪些后端上验证过、差异如何。这样当路由层把请求换到新后端时,你能快速判断这是不是已覆盖的组合。

上线前的检查清单

  • 提示词文本、变量契约、输出契约三者版本一致
  • 调用日志包含请求模型、实际模型、请求 ID、提示词版本
  • 评估集覆盖主要任务,并且绑定到具体提示词版本
  • 明确定点模型与 auto 各跑过一轮对比
  • 别名映射有快照,变更时有记录
  • 发现输出漂移时,先看 served_model 再看提示词 diff

常见误区

  • 把 auto 当成固定模型:它只是路由入口,不是承诺。
  • 只记录请求模型:没有承接后端信息,事后无法归因。
  • 用生产流量直接验证路由变更:先在小评估集上对比,再放量。
  • 一个版本号覆盖多次修改:版本号失去定位能力。

按这套方法做,换后端就从一个不可见的风险,变成一个可观测、可对比、可回滚的常规发布动作。