日期:2026-08-06
我们维护着一套对外提供推理能力的模型服务,平均每周有一次版本迭代。早期升级靠工程师手工选几个样例跑一遍,觉得差不多就发。结果吃了几次亏:某个边界输入在手工测试里没覆盖,线上偶发异常,复现还特别难,因为那个请求早没了。发布越来越不敢快,生怕一动就出事。我们当时意识到,问题不在模型,在于"没有可复现的回归手段"。我们采用的私有化 AI 底座支持流量侧埋点,于是决定把线上真实流量录下来,升级前离线回放,用真实请求做回归。
我们建了一条"流量录制—回放比对—灰度准入"的流水线。生产网关对推理请求做采样录制,请求和响应一起落库(响应里含 PII 的部分先脱敏),按小时归档。要发新版本时,从最近一段时间的录制里抽一批有代表性的请求,打到新版本做离线回放,把新版本的响应和录制里的旧版本响应做比对。比对维度包括:是否抛异常、输出结构是否一致、关键字段差异、延迟变化。差异超过阈值的标红告警,工程师确认是预期还是回归。只有回放全部通过,新版本才允许进灰度。
第一个挑战是录制成本。全量录制存储爆炸,我们改成"核心接口全采 + 长尾接口抽样",并对响应做去重和压缩,存储量压到可接受范围。第二个挑战是比对的公平性。同一请求两次推理,生成模型输出并非逐字一致,直接字符串比对会全是差异。我们的做法是"结构校验优先、语义差异次之":先比是否异常、输出 schema 是否合法、关键枚举字段是否一致,再对自由文本做语义相似度,只有语义也明显漂移才告警,避免被随机性噪声淹没。第三个挑战是脱敏,录制里可能带用户内容,我们在落库前对响应做实体掩码,确保回放数据不泄露隐私。
案例片段(已脱敏): 一次回放拦住的回归——新版本把某个分类接口的返回从
{"label":"A","score":0.9}改为{"category":"A","confidence":0.9},字段名变了。结构校验直接标红:8 个录制样本中 6 个字段名不匹配。工程师定位是序列化层重构时改了 key,下游有两个调用方依赖旧字段名,及时在发版前修了兼容层,避免了一次线上解析失败。 回放配置片段:sample_rate=1.0 for /v1/classify; sample_rate=0.05 for /v1/chat; mask_fields=["user_query_pii"]; diff_rules=[exception, schema_valid, key_enum, semantic_sim<0.85]。该流水线运行两月,回归覆盖率从手工时代的约 40% 提升到约 92%。
跑通后两个月,模型服务的发布回滚率从约 9% 降到约 2%,因为绝大多数回归在回放阶段就被拦下了。线上偶发异常中能被"录制回放"复现的比例从不到三成提升到约 85%,定位时间从平均约 3 小时缩到约 40 分钟。回归验证的端到端耗时从手工准备样例的约半天,降到自动回放的约 25 分钟。数字为脱敏示意值,不同模型规模下回放耗时会有差异。
第一,模型升级的回归不能靠手选样例,真实流量才是最全的测试集。第二,生成模型的比对别死磕字符串,结构校验加语义相似度才是正道。第三,录制必须脱敏,回放数据合规是前提。第四,回放通过才放灰度,把"准入"做成卡点而不是建议。这套流水线后来被我们复用到多个模型服务的发布流程,发布频率提上去了、事故反而少了。
录制侧我们做了分级采样:核心推理接口全量采,长尾接口按百分之五抽样,响应落库前对可能含用户内容的字段做实体掩码,确保回放数据不泄露隐私。存储上对响应做去重和压缩,同一请求多种子下的重复响应只留一份,存储量压到可接受范围。回放比对的公平性我们花了很多心思:生成模型同一请求两次输出并非逐字一致,直接字符串比对全是差异,所以改成结构校验优先、语义差异次之,先比是否异常、schema 是否合法、关键枚举是否一致,再对自由文本做语义相似度,只有语义明显漂移才告警。
模型升级的回归不能靠手选样例,线上真实流量才是最全的测试集,手工选的永远覆盖不到边界。生成模型的比对别死磕字符串,结构加语义相似度才是正道,否则会被随机性噪声淹没。录制必须脱敏,回放数据合规是前提,这一步省了迟早出事。最后把回放做成发布准入的卡点而不是建议,只有回放全过才放灰度,发布频率反而能提上去。
回放流水线我们设了"准入门禁":只有回放全绿的版本才允许进灰度,任何一项标红都要工程师确认是预期行为并留备注才能放行。运行两个月,它拦下过字段改名、枚举值收缩、异常率上升、延迟劣化四类问题,其中字段改名那次若放出去会直接打挂两个下游调用方。回放的存储我们压得很狠,一个月的录制数据只占原来全量录制的约一成五,成本完全可控。
回放测试最大的价值不是发现已知问题,而是把"偶发、难复现"变成"可重复、可定位"。过去我们最怕的就是线上抖一下、日志里找不到对应请求,现在只要那次请求被录进去了,就能随时拉回来重放,根因定位从靠猜变成靠验。这套能力一旦建成,模型迭代的节奏就能明显加快,因为团队知道有兜底,敢发、也发得稳。