AB 实验与线上迭代:搜推策略怎么科学上线
Published in:2026-04-20 | category: 搜推算法

本文是 搜推算法笔记 第 5 篇。索引见 搜推算法 · 知识索引

上一篇:精排与评价指标 · 下一篇:Python 搜推技术栈

离线 NDCG 涨了 0.02,能直接全量吗?不能。线上还有真实用户决策、展示位置、系统延迟、长期生态——没有 AB 的「感觉上线」,不是可运营系统。

这篇是算法笔记的「最后一公里」:Query、召回、精排、指标的理论最终都要通过 AB 实验在线上验证。

0. 从离线到线上:完整迭代链

1
2
3
4
5
6
算法想法
→ 离线 NDCG/Recall 过闸(第 4 篇)
→ 小流量 AB(本篇)
→ 看主指标 + 护栏
→ 5% → 20% → 50% → 100%
→ 全量 or 回滚

离线指标是必要非充分——它排除了明显不行的方案,但不能替代真实用户行为。典型情况:离线 NDCG 提升,但 AB 中发现 P99 延迟恶化——护栏指标阻止了有损上线。


1. 为什么需要 AB

离线指标只能近似真实世界——真实用户决策、展示位置、机制约束、系统延迟,都是离线算不出来的。

2. 实验基本概念

术语含义
Control(对照)旧策略
Treatment(实验)新策略
分流(Assignment)谁进哪一桶
粘性(Stickiness)同一主体实验期内固定在一桶
主指标决定胜负
护栏指标不能明显变差
新颖性效应刚上线短暂变好/变差,需观察足够久

3. 分流设计

哈希分流(最常用)

1
2
3
4
5
6
def bucket(exp_id: str, unit_id: str, mod: int = 100) -> int:
return hash(f"{exp_id}:{unit_id}") % mod

def assign(exp_id, unit_id, treatment_ratio=10):
b = bucket(exp_id, unit_id)
return "treatment" if b < treatment_ratio else "control"

要点:

  1. 加入 exp_id,让不同实验映射不同
  2. 使用稳定 ID(user/shop/device)
  3. 不要每次请求 random(无粘性)

粘性为什么重要?

无粘性时同一用户来回跳桶:体验混乱、转化难归因、方差变大。

分流键怎么选?

适用场景
user_id个性化、用户体验
shop_id商家维度策略、B2B
device_id / cookie未登录

原则:谁是策略作用的决策主体,就用谁。

分流键对比

分流键粘性周期适用实验风险
user_id长(跨 session)个性化排序、UI 改版未登录用户需 fallback
shop_idB2B 商家策略、店铺功能与用户维度实验可能互扰
device_id / cookie未登录流量换设备则跳桶
session_id极短几乎不适合 AB同一用户跨 session 体验不一致
request_id不是 AB 键每次请求都变,无法归因

常见起步 5%~10% treatment。太小难显著,太大风险高。


4. 指标:主指标与护栏

搜推常见主指标

指标期望方向典型场景
无结果率召回/兜底
CTR列表吸引力
CVR / 分销转化业务核心
GMV电商(更滞后、方差大)

一次实验只设 1 个(最多 2 个)主指标,避免「哪个涨看哪个」。

护栏指标

护栏为什么
P95/P99 延迟变慢直接伤体验与转化
错误率 / 降级率系统是否健康
空结果率是否引入新空洞
投诉/违规合规与生态

决策规则:主指标显著变好,且护栏不恶化 → 才放量。

北星与代理

  • 北星可能是 GMV/留存(慢)
  • 代理指标是 CTR/无结果率(快)
  • 代理涨但北星不涨时,要复盘是否优化偏了

5. 放量、回滚与开关

放量节奏

1
5% → 20% → 50% → 100%

每档至少观察完整业务周期(含工作日/周末),并检查分人群。

回滚手段

手段说明
缩流量treatment 比例降回 0
配置开关关掉新模型/新改写/某召回路
kill-switch紧急一键走降级路径
版本回退模型文件回上一版

开关必须在设计期就留好,不要只能靠发版救命。


6. AA 测试

两边其实是同一策略,只是分成两桶(A/A)。用来发现:

  • 分流是否均匀
  • 埋点/指标计算是否有 bug
  • 指标自然波动有多大

若 AA 就「显著」→ 实验平台或指标有问题。

上正式 AB 前,最好用 AA 验证分流与指标管道是干净的。


7. 统计直觉(够用版)

  1. 样本量不够:转化稀、流量小 → 很难显著
  2. 观察期不够:要覆盖周期性(星期效应、大促)
  3. 多重比较:同时看 20 个指标,总会有几个「碰巧显著」→ 先定主指标
  4. 新颖性/学习效应:上线初期波动,需要稳定窗口
  5. Simpson 悖论:总体涨、某分层跌 → 要看分层

开实验前写清:主指标、护栏、最小周期、成功标准。实验中途不随便改配置。

7.1 显著性检验(够用版)

**零假设 (H_0)**:Treatment 与 Control 的真实均值相同(策略无效)。

t 检验直觉: 观测到的 CTR 差异 (\Delta),是否大到「自然波动」难以解释?

[
t = \frac{\bar{x}_T - \bar{x}_C}{\sqrt{\mathrm{Var}_T/n_T + \mathrm{Var}_C/n_C}}
]

(p)-value含义决策
< 0.055% 概率是偶然通常认为「显著」
0.05~0.10边缘需结合业务判断、延长观察
> 0.10不显著不能证明有效

常见陷阱:

  • 样本量不足:CVR 0.5% 时,5% 流量要跑数周才够 power
  • MDE(Minimum Detectable Effect):实验设计时应算「最小可检测 uplift」,避免「其实涨了 0.1% 但检验力不够」
  • SRM(Sample Ratio Mismatch):实际分流 48:52 而非 50:50 → 分流 bug,结果不可信

7.2 置信区间

点估计 (\Delta=+2.3%) CTR 不够,应报告 95% CI,例如 ([+0.8%, +3.8%]):

  • CI 不含 0 → 与 (p<0.05) 一致
  • CI 很宽 → 样本不够,即使「显著」也不稳

7.3 方差缩减(CUPED)

CUPED(Controlled-experiment Using Pre-Experiment Data):用实验前的用户指标作协变量,降低指标方差,同样流量下更容易检出小 uplift。适合有历史行为数据的成熟产品。


8. 搜推可实验变量

可实验变量
Query纠错开关、阈值、改写词表、改写条数
召回各路权重、是否开热门补召、TopK
融合加权 vs RRF、RRF 的 k
精排模型版本、特征开关、去偏方式
机制打散窗口、过滤规则
工程超时阈值、降级策略

一次少改因子——改太多说不清收益来自谁。


9. 线上异常排查

空结果率突增

1
2
3
4
5
1. 最近是否上线纠错/改写?(误伤)
2. 某召回路超时率/错误率是否暴涨?
3. 过滤是否突然变严?(库存/类目硬过滤)
4. 向量索引是否过期/没更新?
5. 流量结构是否变化?(异常爬虫)

P99 延迟突增

1
2
3
4
5
1. 哪一路耗时变长(分层追踪)
2. 精排特征计算 / 模型预测
3. 下游依赖(DB/向量库)慢查询
4. 是否缺少超时与隔离
5. 是否放量后容量不足

点击涨、转化跌

1
2
3
4
1. 是否推了标题党/低质高点
2. 主 label 是否过度拟合点击
3. 价格带/类目结构是否偏移
4. 机制打散是否被关掉

离线 NDCG 涨、线上无感

回到 Train=Serve、标签目标、延迟、机制层四件套排查。


下一步

Prev:
IPD 集成产品开发学习笔记
Next:
《格鲁夫给经理人的第一课》读书笔记(五):中层管理者的双重角色