离线A/B测试与在线A/B测试必须配合使用,否则上线后效果易断崖下跌;离线用历史数据按时间切分评估模型,指标须对齐业务目标;在线需网关层干净分流、全量日志记录及多维监控;特征逻辑一致性是结果对齐的关键。

离线A/B测试能验证模型效果,但无法替代在线A/B测试;两者必须配合使用,否则上线后效果断崖式下跌的风险极高。
离线A/B测试:用历史数据模拟线上分流
离线A/B测试本质是用同一份历史数据,对两个(或多个)模型做独立预测,再用统一评估指标对比。它不涉及真实流量,只解决“模型谁更好”的问题。
- 必须用
train_test_split严格按时间切分——比如用2025年1–6月数据训练,7–9月数据作为离线测试集,禁止随机打乱,否则会引入未来信息泄露 - 评估指标要和线上业务目标一致:房价预测不能只看
R²,必须同步计算MAE(用户感知误差)和高误差样本占比(如预测偏差>15%的房屋比例) - 避免直接比
accuracy:分类任务中,若正样本仅占2%,哪怕全预测为负,accuracy也能达98%,此时应看precision、recall或F1 - 离线结果稳定≠线上稳定:曾有模型在离线测试中
MAE降低12%,上线后因特征延迟(如用户实时行为特征未及时写入特征库)导致实际误差上升23%
在线A/B测试:真实流量下的可控分流
在线A/B测试是把模型部署为服务,将真实请求按规则分配给不同版本,观测业务指标变化。关键不是“怎么发请求”,而是“怎么确保分流干净、可观测、可回滚”。
- 分流必须在网关层完成,而非模型内部逻辑——例如用Nginx或API网关的
hash($request_id) % 100实现百分比分流,避免模型自己判断版本导致状态污染 - 必须记录原始请求与响应全量日志,字段至少包含:
request_id、model_version、input_features(哈希后)、prediction、response_time_ms、is_timeout - 拒绝“灰度发布即A/B”:灰度只控制流量比例,A/B必须保证两组用户除模型外其他条件完全一致(如前端渲染逻辑、缓存策略、下游依赖版本)
- 监控不能只盯
error_rate:某次上线中,v2模型error_rate为0.1%,v1为0.08%,看似无风险,但v2的p95_latency高出400ms,导致用户放弃提交,最终转化率下降7%
如何让离线与在线结果对齐?
离线和在线结果不一致,90%以上源于特征计算逻辑不一致。这不是模型问题,是工程一致性问题。
立即学习“Python免费学习笔记(深入)”;
- 特征生成代码必须共用同一套Python模块,禁止离线用pandas写一遍、线上用SQL重写一遍——曾发现“最近7天平均访问时长”在离线用
groupby('user_id').rolling(7).mean(),线上因数据库不支持窗口函数改用近似算法,偏差达32% - 所有特征必须带版本号,例如
feature_user_active_days_v2,并在模型元数据中显式声明所依赖的特征版本,上线前校验特征服务返回值是否匹配 - 上线前强制跑一次“影子模式(Shadow Mode)”:把线上流量复制一份,同时过v1和v2模型,不返回结果,只比对输出分布——若
prediction的KL散度>0.05,说明特征或模型存在隐性偏移,需暂停上线 - 离线测试脚本里禁止硬编码路径,如
pd.read_csv('./data/test_202509.csv'),应统一通过配置中心读取offline_test_data_uri,确保CI/CD中复现环境一致
真正难的从来不是跑通A/B流程,而是让离线训练、特征服务、在线推理三端的特征计算逻辑严丝合缝。一个fillna(0)和fillna(method='ffill')的差异,就足以让离线指标虚高、线上效果崩塌。


















