多版本模型如何做路由和回滚?
简化版
多版本路由应基于不可变 release_id,把模型、Tokenizer、Prompt、索引、策略和解析器作为完整组合。路由规则先检查地域、能力、权限等硬约束,再按用户/会话稳定哈希做 Canary 或 A/B,避免同一会话跨版本漂移。
回滚不是只切模型别名:要切回完整 Manifest,隔离不兼容缓存,处理长会话和在途请求,并保留上一版本暖容量。触发条件同时覆盖错误率、任务质量、安全、TTFT/TPOT 和成本。
详细版
request -> hard constraints -> experiment/canary assignment
-> session stickiness -> healthy replica selection
-> release manifest -> response tagged with release_id
发布从 1% 小流量逐步扩大,每阶段满足最低样本数和观察时间。出现红线时停止新流量进入候选,旧请求排空或按规则迁移;路由控制面故障时回退到最后已知安全配置,而不是随机选择版本。
| 机制 | 解决的问题 |
|---|---|
| 稳定哈希 | 用户/会话版本一致 |
| 权重路由 | Canary 分阶段放量 |
| 能力过滤 | 防止路由到不兼容模型 |
| 健康/熔断 | 隔离故障版本或区域 |
| 完整 Manifest | 可复现与原子回滚 |
完整版教学
1. 版本单位为什么是 Release
模型行为依赖 Prompt、Tokenizer、Adapter、索引、安全策略和输出解析。单独给模型打版本,无法复现真实请求。
Release Manifest 固化所有依赖,路由只引用 release_id,使切换成为原子操作。
2. 硬约束先于流量权重
候选版本必须满足上下文长度、工具能力、结构化输出、地域、合规和租户授权。未通过硬约束,权重再高也不能进入候选。
这避免将长上下文请求路由到短上下文模型,或把受监管数据发送到错误区域。
3. 稳定哈希如何分流
bucket = hash(experiment_id || stable_unit_id) mod 10000
route = treatment if bucket < treatment_weight else control
stable_unit_id 可选用户、会话或租户。会话型应用至少保持单会话一致,防止上下文和工具格式跨版本变化。
4. Canary 与 A/B 有何区别
Canary 主要验证新版本安全与稳定,流量逐步扩张;A/B 主要估计两个版本的因果效果,需要稳定随机与统计设计。
两者可共用路由基础设施,但停止规则、样本要求和分析方法不同,不能把 Canary 的“没报警”当成 A/B 提升证据。
实践中可以先用内部流量做 Canary,确认没有崩溃、格式或安全回归,再进入稳定随机的 A/B。Canary 发生严重故障时立即回滚;A/B 则在护栏安全的前提下运行到预设样本量,避免因短期波动误判效果。
5. 如何做多维路由
路由可组合租户等级、任务、语言、风险、输入长度与区域。规则需要优先级和冲突检测,避免多个条件同时命中产生不可预测结果。
| 层次 | 示例 |
|---|---|
| 合规 | 数据地域、模型授权 |
| 能力 | 上下文、工具、Schema |
| 产品 | 租户、任务、实验组 |
| 运行时 | 健康、队列、容量 |
每次决策记录命中的规则与最终 Release。
6. 缓存怎样按版本隔离
响应、语义和 KV 缓存键包含模型、Prompt、索引和策略版本。不兼容 Release 使用不同命名空间。
回滚可重新指向保留的旧命名空间,但仍检查数据时效与权限;不能因为回滚而复活已撤权内容。
7. 长会话如何迁移
新会话进入候选,旧会话粘在原版本并逐步排空。旧版本设置最长保留期,避免永久运行。
强制迁移时清除不兼容 KV,必要时对历史做中立摘要,并向客户端返回上下文重建标识。
8. 健康路由与版本路由
版本权重决定希望分多少流量,实例健康与容量决定当前能否接收。先选 Release,再在其健康副本中按队列和局部性选择。
某候选熔断时,按预定义策略回主版本;不能把失败流量平均散到所有未知版本。
9. 回滚触发条件
错误、超时、P99、任务成功、事实、安全、Fallback 和单位成本都可触发。安全违规通常使用绝对红线,其他指标与控制组比较。
rollback if safety_violation > hard_limit
or error_budget_burn > threshold
or quality_delta < allowed_regression
阈值、窗口与最小样本在发布前确定。
10. 回滚步骤如何原子化
先将候选权重降为零,停止新请求;已开始请求按安全策略完成、取消或转移;路由切回旧 Manifest;验证缓存、Schema 和工具兼容。
数据库或索引变更若不可逆,需要双写/版本化读取。没有数据回滚方案,就不是真正可回滚发布。
11. 控制面故障怎么办
路由配置存储不可用时,数据面使用签名的最后已知安全配置,并设最大有效期。不要默认拉取 latest 或随机均衡到全部版本。
配置发布使用校验、审批和原子更新;节点报告已应用版本,便于发现配置分裂。
12. 如何避免容量陷阱
候选只预留 1% 容量时,回滚通常容易;但主版本若已缩容,候选故障后的回流可能压垮主站。
逐级放量期间保留回退容量,扩容考虑冷启动。演练“候选全量后立即回滚”,验证旧版本能恢复。
13. 可观测性记录什么
记录 assignment、实际 exposure、release_id、规则、Fallback、缓存命中和最终结果。指标按 Release、区域、任务和长度分桶。
只有分配记录没有实际执行记录,会把熔断后回退的请求错误算到候选效果中。
14. 测试与演练
覆盖规则冲突、会话粘性、区域约束、候选熔断、控制面断网、缓存隔离和全量回滚。用固定 Trace 验证决策可解释。
定期演练回滚并计时,确认旧权重、旧解析器和容量仍存在,而不是只保留一份文档。
路由系统最重要的能力不是把流量切过去,而是在错误发生时把完整执行语义安全地切回来。
15. 常见误区与追问
- 误区:模型别名切回即可回滚。 Prompt、索引、策略和解析器也可能不兼容。
- 误区:每个请求随机分流最均匀。 会破坏会话一致并污染实验。
- 误区:Canary 未报警证明效果更好。 它主要验证安全稳定,不证明因果提升。
- 误区:候选故障时随便选一个备用版本。 必须走预定义兼容路径。
- 误区:全量后可立即删除旧容量。 回滚窗口内应保留权重、缓存与容量。
- 追问:控制面挂了怎么办? 使用签名的最后安全配置并限制有效期。
- 追问:如何处理在途请求? 按副作用与兼容性决定排空、取消或迁移。
16. 加强记忆
- 先定单位:完整 Release Manifest。
- 再硬过滤:能力、地域、权限和合规。
- 再稳分流:用户/会话哈希与版本粘性。
- 再看健康:版本权重与实例容量分层。
- 再隔缓存:执行语义变化就换命名空间。
- 再保回退:旧组合、旧容量和数据兼容。
- 最后做演练:控制面故障和全量回滚都要验证。