SPRT 与 LLR:证据攒够就提前下判的序贯检验

前两篇解决的是”拿什么判定”:看保底分(Wilson 下界),不看表面通过率。但有个问题一直悬着:跑多少把才算够?

前两篇的答案是”跑够样本量,比如 300 把”。可是干过回归的人都知道这个答案多贵:一个场景 300 把,一百个场景就是三万把,CI 排队排到明天。

更要命的是浪费感:很多时候根本不需要 300 把——故障一注入,系统连崩 4 把,明摆着是坏了;或者连过 12 把,行云流水,明摆着没问题。非要跑满 300 把才盖章,是在用排队时间惩罚一个早有答案的问题。

有没有办法边跑边看,证据攒够就提前收卷?有,这就是 SPRT(序贯概率比检验)。它的发动机叫 LLR(对数似然比)。

一、先建立一个画面:两个世界对质

判定通过率的本质,是让两个”世界假设”当场对质:

每跑一把,结果都会更像其中一个世界的产物。连着失败?更像退化世界。行云流水全过?更像健康世界。SPRT 做的事,就是给这场对质装一个记分牌:每把结果加减分,分攒够了直接宣判。

二、LLR:每把结果值多少分

似然比回答的问题是:”眼前这把结果,在 H₁ 世界里出现的可能性,是在 H₀ 世界里的几倍?” 取个对数(连乘变连加,方便记账),就是 LLR——每把结果的”证据分”。

拿上面的两个世界算一下记分规则(过程略,结论如下):

这一把的结果 记分牌变化 为什么
成功 −0.25(往”健康”推一小步) 健康系统本来就该成功,成功不算新闻
失败 +1.10(往”退化”推一大步) 失败在健康世界里很少见,一出现就是大新闻

注意不对称:一把失败的情报量,约等于四把成功。这符合所有测试工程师的直觉——没问题的时候跑得再顺也只是”应该的”,出问题的那一把才信息量爆炸。

三、SPRT:给记分牌画两条触线

规则简单到可以写在便利贴上:

记分牌 ≥ +2.94  →  宣判:H₁ 成立,FAIL(确实退化了)
记分牌 ≤ −2.94  →  宣判:H₀ 成立,PASS(扛住了)
两者之间        →  证据不够,接着跑

±2.94 不是拍的,是由你能容忍的误判率直接算出来的(两边各 5% 的错判空间,对应 log 19 ≈ 2.94;想更严,线就画更远,代价是多跑几把)。

走两个示例轨迹感受一下(按上述记分规则演算):

场景 A:故障注入后系统明显退化——连跑 4 把:失败、失败、成功、失败

+1.10 → +2.20 → +1.95 → +3.05  ≥ +2.94 ✅

4 把收卷,判 FAIL。 固定样本量方案这时还在第 4/300 把排队。

场景 B:系统健康——连续 12 把成功

12 × (−0.25) = −3.01  ≤ −2.94 ✅

12 把收卷,判 PASS。

一般情况呢?按期望算,健康场景平均约 25 把出判决,退化场景平均约 19 把——对比同等级别误判率下的固定样本量方案,平均省三到五成,一边倒的场景省九成以上。这不是野鸡技巧:Wald 在 1943 年证明了,同样误判率下,SPRT 的期望样本量是所有检验方法里最小的——省是有数学保证的省。

四、为什么这套东西和故障注入是天作之合

故障注入战役(fault campaign)有个鲜明的统计特征:大部分场景是一边倒的。

真正需要几百把细品的,是那些”退化量刚好卡在阈值附近”的争议场景。固定样本量方案对三种场景一视同仁地跑满,等于给显而易见的场景和争议场景发同样的预算;SPRT 自动把预算挪给争议场景——省下来的机器时,花在刀刃上。

这对 CI 门禁是硬收益:门禁的墙上时钟缩短了,反馈快了,开发者才不会把红灯当背景噪音。

五、SPRT 和 Wilson 是什么关系

不打架,分工不同:

  管什么 什么时候出场
SPRT + LLR 什么时候停——在线地、逐把地决定收卷时机 执行过程中
Wilson 下界 报告里写多少——给最终通过率一个诚实的区间 判决之后,写进证据包

所以 Cyclone Core 判定引擎里两者并用(已支持):SPRT 负责”证据攒够就提前下判”,Wilson 负责把判决落成可复算的保底分数字。一个管油门,一个管仪表盘。

六、三个工程上的实话(别踩坑)

  1. SPRT 要先设好两个世界(p₀ 和 p₁)。0.90 vs 0.70 还是 0.90 vs 0.85?两个世界离得越近,判定拖得越久。p₀/p₁ 不该拍脑袋,应该来自基线测量和裕度分析(本专栏第 4 篇展开)——SPRT 省样本,但不省思考。
  2. 偶尔会遇到”拉锯局”:真实通过率正好卡在两个世界之间时,记分牌会来回晃很久。工程对策是截断 SPRT——设一个样本量上限,到上限按当时证据判,并把”判得勉强”如实写进报告。
  3. SPRT 不是免死金牌:它优化的是”跑多少把”,不改变”拿什么判定”和”阈值怎么来”——那两件事分别归第 2 篇和第 4 篇管。三篇合起来才是完整的判定体系。

七、装进引擎之后

在 Cyclone Core 里,你不需要碰任何记分规则:场景 YAML 里声明两个世界(如 p0: 0.90, p1: 0.70)和误判预算(α/β),判定引擎逐把记账、触线即判,判决连同 LLR 轨迹一起落进证据包(已支持)。你写场景,引擎管收卷。

想亲手感受一下?场景包里有现成的故障注入场景,跑一遍,看记分牌几把触线。

下篇预告:裕度分析三步法——p₀、p₁ 和阈值到底该怎么定,”拍脑袋”和”可推导”的分水岭在哪。


附:名词解释(按出场顺序)

名词 通俗解释
SPRT(序贯概率比检验) 边采样边判定的方法:证据攒够立刻收卷,不够继续跑;1943 年 Wald 提出
LLR(对数似然比) 每把结果提供的”证据分”:这把结果更像哪个世界的产物,取对数后可逐把累加
似然 在某个假设下,观察到眼前数据的概率
H₀ / H₁(两个世界) 对质的两个假设:本文里 H₀ = 健康(通过率 0.90),H₁ = 退化(0.70)
记分牌 / 触线 LLR 的累加值;上下两条宣判线(本文 ±2.94),碰到就下判
误判率 α / β α:把健康误判成退化的概率;β:把退化误判成健康的概率。触线距离由它们算出
期望样本量 平均要跑多少把才能出判决;SPRT 在同误判率的所有方法里做到最小
故障注入战役(fault campaign) 成批执行故障场景、看系统是否守住底线的测试活动
截断 SPRT 给序贯检验加样本量上限的实用变体,防止”拉锯局”无限拖
p₀ / p₁ 两个世界的通过率设定值,应由基线测量和裕度分析得出
裕度分析 下篇主角:从基线出发推导阈值与判定参数的方法

(文中记分规则与轨迹为按 LLR/SPRT 标准公式演算的示意数据;产品能力以 Cyclone Core 当前版本为准。)

下一步:

下载场景包亲手跑一遍