AB-Experiment-RAG

离线 Recall 涨了,用户仍不满意或成本先爆。根因是离线代理指标不等于线上目标函数。本方法随机分桶加护栏(时延、成本、投诉)。流量不够就不要做 A/B,回到 Benchmark 与延长观测。

本文属于 RAG 工程框架中的「6 模块化架构与评估闭环」环节,聚焦「AB Experiment(A/B 实验)」方法。

定位

维度 内容
角色 线上随机对照
输入 → 输出 user → bucket → 主指标 $\Delta$ + 护栏
默认组合 GrowthBook / Statsig / LaunchDarkly
何时不用 无真实流量;MDE 大于你能接受的提升

核心机制

$\mathrm{bucket}=\mathrm{hash}(\mathrm{user_id})\bmod 100$。功效不足时延长窗口,而不是提前宣布胜利。

实现路径与心智:稳定 hash 分对照/实验,盯主指标与护栏,显著且护栏不破再放量。底层心智:线上目标函数才是最终估计量,离线 $\Delta$ 只是假说。

优缺点

  • 优点:测真实收益。
  • 缺点:要流量与时间。

契约与走通样例

输入

1
{"user_id": "u18", "ratio": 0.5}

中间量

hash 落实验桶,走 ColBERT 精排。两周后主指标 +3%,P95 护栏未破,MDE=2.5% → 可放量。若日活过低,MDE=12% 则停实验。

输出

1
{"bucket": "treatment", "decision": "ship_to_25%"}

社区实现

GrowthBook / Statsig。风险:按请求而不是用户分桶导致同一人跳组。

工程落地

最小可运行示例

复制为 .py 后直接运行(仅标准库)。分桶键必须是 user_id;不要用 hash()(进程间不稳定)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
"""按用户稳定分桶,同一用户始终走同一臂。"""
from __future__ import annotations

import hashlib


def stable_bucket(user_id: str, n_bins: int = 100) -> int:
"""md5 分桶,跨进程可复现。"""
digest = hashlib.md5(user_id.encode()).hexdigest()
return int(digest, 16) % n_bins


def online_ab_assign(user_id: str, control: str, treatment: str, ratio: float) -> str:
"""ratio=0.1 表示 10% 流量进 treatment。"""
return treatment if stable_bucket(user_id) < ratio * 100 else control


if __name__ == "__main__":
users = ["u-1", "u-2", "u-3"]
print({u: online_ab_assign(u, "hybrid-v1", "hybrid-v2", 0.5) for u in users})
print(online_ab_assign("u-1", "hybrid-v1", "hybrid-v2", 0.5)) # 再次调用仍相同

参数

参数 起点 影响
分桶键 user_id 不要用 query
护栏 P95、成本、投诉 主指标涨但护栏破则回滚
功效 80% 不够就延长

失效—信号—螺丝

  • 按 query 分桶:同一用户两边都看到。螺丝:user_id。
  • 流量不够:螺丝:回 Benchmark,或拉长窗口。
  • 无护栏:成本先爆。螺丝:强制成本/时延护栏。

规模(100 篇生物学 PDF)

与篇数无直接映射。有效样本常需 数天–两周;库流量小则延长或改离线。

-------------本文结束感谢您的阅读-------------