背景:模型升级不是“换一个 model name”这么简单
在传统后端系统里,发布一个新版本通常可以通过单元测试、集成测试、金丝雀流量和监控报警来控制风险。但在 LLM 应用 里,风险不只来自代码变更,还来自模型供应商托管版本更新、系统提示词调整、工具定义变化、微调模型替换、上下文拼装策略变化,以及采样参数变化。
这些变化有一个共同特点:它们可能不触发明显的 500 错误,却会改变用户真正感受到的结果。例如:
- 原来稳定输出 JSON 的客服分类模型,升级后开始补充解释文字;
- 原来会调用订单查询工具的 Agent,升级后变得更倾向于直接回答;
- 原来不会拒答的内部知识问答,在新安全策略下出现大量误拒。
系统看起来仍然可用,但业务行为已经漂移。
因此,LLM 模型发布不能只做“部署成功”检查,而要建立一条面向行为兼容性的发布链路:版本登记 → 离线回放 → 影子流量 → 兼容门禁 → 金丝雀发布 → 自动回滚 → 发布审计。
核心原理:把模型版本当成有契约的软件依赖
1. 为每个候选版本建立发布单元
一个可发布的 LLM 版本,不应只包含 model=gpt-x 或某个微调模型 ID。生产环境里更合理的发布单元通常包括:
| 维度 | 说明 |
|---|---|
| 基座模型 / 微调模型 ID | 模型权重或供应商托管版本的标识 |
| 系统提示词版本 | 控制模型行为、语气和输出风格 |
| 工具 schema 版本 | 函数调用定义及参数约束 |
| RAG / 上下文组装版本 | 检索策略、chunk 策略、排序逻辑 |
| 采样参数 | temperature、top_p、max_output_tokens 等 |
| 输出契约 | JSON Schema、字段枚举、拒答格式 |
| 安全策略 | 内容审核阈值和降级策略 |
这些内容应登记成一个 LLM Release Manifest。它的作用不是替代模型仓库,而是让线上每次请求都能追溯到“到底是哪套行为组合在回答”。
{
"release_id": "support-agent-2026-07-08-r3",
"model": "vendor-model-2026-07",
"prompt_version": "support-system-prompt-v18",
"tool_contract_version": "support-tools-v7",
"output_contract": "ticket-answer-json-v4",
"sampling": { "temperature": 0.2, "max_output_tokens": 900 },
"gates": {
"format_pass_rate": ">= 99.5%",
"critical_task_success_rate": ">= champion - 1.0%",
"p95_latency": "<= champion + 20%",
"cost_per_request": "<= champion + 15%"
},
"rollback_to": "support-agent-2026-07-06-r1"
}
2. 兼容门禁要测“行为”,不是只测平均分
OpenAI Evals 文档把一次 eval 概括为描述任务、用测试输入运行、分析结果并迭代;它还要求 eval 具备测试数据 schema 和判定模型输出是否正确的 testing criteria。这对 LLM 灰度发布很关键:上线前要明确“模型应该怎样表现”,而不是只说“新模型效果更好”。
LLM 发布门禁至少应分成五类:
| 门禁类别 | 关注点 | 典型指标 |
|---|---|---|
| 格式兼容 | 输出是否可解析、字段齐全、枚举不越界 | JSON 解析成功率、字段覆盖率 |
| 任务成功率 | 按业务高风险分桶评估 | 退款/报价/支付/安全等关键桶准确率 |
| 安全与合规 | 拒答、误杀、越权工具调用、隐私泄漏 | 误拒率、敏感内容触发率 |
| 运行指标 | 延迟、token 消耗、工具调用次数 | P95/P99 延迟、单位请求成本 |
| 稳定性指标 | 同一输入多次执行的一致性 | 答案波动范围、局部回归率 |
近期关于 LLM 供应链更新治理的研究也指出,托管模型可能在没有显式版本变更的情况下持续演化,从而带来格式、安全或业务功能回归;建议使用 production contracts、按风险分类的测试集和 compatibility gates 来阻断不兼容更新。
工程落地:一条可执行的发布流水线
第一步:冻结 champion 与 candidate
生产系统应始终保留一个当前稳定版本,称为 champion;即将发布的版本称为 candidate。所有评估、影子流量和灰度指标都应以 champion 作为基线,而不是和一个抽象目标比较。
对于模型注册,可以借鉴 MLflow Model Registry 的思路:使用集中式模型仓库管理模型版本、别名、标签、元数据和血缘。在 LLM 场景中,alias 不一定只指向权重文件,也可以指向一个 release manifest:
aliases:
support-agent@champion: support-agent-2026-07-06-r1
support-agent@candidate: support-agent-2026-07-08-r3
support-agent@rollback: support-agent-2026-07-06-r1
第二步:离线回放历史样本
发布前先做 offline replay。样本来源不要只用人工构造题,还应包括:
- 线上脱敏请求
- 失败工单与人工接管记录
- 投诉样本与边界场景
- 历史高价值客户问题
- 高成本长上下文请求
回放时要保存 candidate 与 champion 的并排结果:
{
"case_id": "ticket-refund-01892",
"bucket": "refund_policy",
"champion_output": "...",
"candidate_output": "...",
"format_ok": true,
"task_score": 0.92,
"safety_pass": true,
"latency_ms": 1380,
"input_tokens": 2140,
"output_tokens": 410,
"decision": "pass"
}
离线回放的目标不是证明 candidate 完美,而是识别是否存在不能上线的硬伤:格式破坏、关键任务明显退化、成本暴涨、安全拒答异常、工具调用参数变化等。
第三步:使用影子流量验证真实分布
离线样本再完整,也很难覆盖真实线上分布。因此 candidate 通过离线门禁后,应进入 shadow traffic。做法是:真实用户请求仍由 champion 返回,系统异步复制一份脱敏请求给 candidate,candidate 的结果只记录、不返回给用户。
影子流量要特别注意三点:
- 不能执行有副作用的工具。 订单取消、支付、发邮件、写数据库等工具必须 mock、dry-run 或只记录计划动作。
- 必须控制成本。 影子比例可以从 1% 开始,按业务低峰、用户分层和请求类型逐步扩大。
- 必须做差异归因。 比较 champion 与 candidate 的输出差异、工具调用差异、token 成本差异和人工规则判定差异。
第四步:金丝雀发布时用多指标闸门
当 shadow 阶段没有发现阻断问题后,才进入小流量金丝雀。普通 Kubernetes 或服务网格可以按流量权重切分;Argo Rollouts 这类 progressive delivery 工具还提供 AnalysisTemplate 和 AnalysisRun,定义观测指标、频率和成功/失败条件。LLM 金丝雀不应只使用 HTTP 成功率,更合理的指标组合包括:
canary_gates:
traffic_steps: [1, 5, 10, 25, 50, 100]
hard_fail:
format_error_rate: "> 0.5%"
tool_schema_error_rate: "> 0.2%"
safety_block_spike: "> champion + 30%"
p95_latency: "> champion + 25%"
cost_per_successful_request: "> champion + 20%"
soft_fail:
user_regenerate_rate: "> champion + 10%"
escalation_to_human_rate: "> champion + 8%"
answer_length_change: "> champion + 35%"
rollback:
immediate: true
target: "support-agent@rollback"
AWS CodeDeploy 对 Lambda 和 ECS 蓝绿部署支持 canary、linear 和 all-at-once 等流量迁移方式,并提供如 10% 流量持续 5~30 分钟后再迁移剩余流量的预定义策略。LLM 发布可以借鉴这种分阶段切流方法,但门禁指标要补上模型行为维度。
第五步:自动回滚必须回滚完整行为组合
LLM 回滚不能只把模型 ID 改回旧版本。如果提示词、工具 schema、RAG 检索策略和输出解析器已经一起变化,只回滚模型可能产生新的不兼容。正确做法是回滚到上一个 release manifest。
回滚记录至少包括:触发指标、时间窗口、candidate 版本、rollback 版本、受影响租户、采样样本、人工确认人、是否需要补偿处理。
常见误区
误区一:只用离线 benchmark 决定上线
通用 benchmark 只能说明模型的基础能力,不代表它适合你的业务链路。生产模型发布要看业务输入、业务输出契约、工具调用和成本,而不是只看模型榜单。
误区二:把 prompt 改动当成小改动
在 LLM 应用里,prompt 是行为控制面的一部分。系统提示词、few-shot、工具描述、拒答口径、输出模板都可能影响线上行为,应进入 release manifest,并走相同门禁。
误区三:只看错误率,不看“沉默失败”
LLM 最危险的问题往往不是请求失败,而是自信地产生错误答案、错误工具调用、错误拒答或不兼容格式。灰度门禁必须纳入语义层和业务层指标。
误区四:没有 champion 对照
没有 champion 对照,就很难判断 candidate 是真的变好,还是只是回答风格变化。发布平台应默认保存 champion 与 candidate 的并排样本,方便人工抽查和后续复盘。
上线检查清单
上线前,建议逐项确认:
- 是否有完整的 release manifest,覆盖模型、prompt、工具、输出契约、采样参数和回滚目标。
- 是否完成离线回放,并保留 champion / candidate 对照结果。
- 是否按风险分桶设置硬门禁,而不是只看平均分。
- 是否为工具调用做了 dry-run、mock 或副作用隔离。
- 是否配置 shadow traffic 成本上限。
- 是否配置金丝雀流量阶梯、暂停窗口和自动回滚条件。
- 是否把 P95 延迟、token 成本、工具调用次数和格式错误率纳入发布指标。
- 是否能一键回滚到上一个完整 release manifest。
- 是否记录发布人、审批人、门禁结果、样本版本和监控窗口。
参考资料
- OpenAI API Docs: Working with evals — https://developers.openai.com/api/docs/guides/evals
- AWS CodeDeploy: Working with deployment configurations — https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-configurations.html
- Argo Rollouts: Analysis & Progressive Delivery — https://argoproj.github.io/argo-rollouts/features/analysis/
- MLflow: Model Registry — https://mlflow.org/docs/latest/ml/model-registry/
- Test Before You Deploy: Governing Updates in the LLM Supply Chain — https://arxiv.org/abs/2604.27789
- Automated Self-Testing as a Quality Gate: Evidence-Driven Release Management for LLM Applications — https://arxiv.org/abs/2603.15676