# ch03 推荐系统评价体系 — 代码示例

本目录对应教材第 3 章，覆盖离线指标、在线指标、A/B 实验体系与监控体系的 Python 实现，共 **14 个可运行脚本**。目录编号与正文节次一一对应，均可直接 `python3 <文件>.py` 运行。本章全部脚本**只依赖 Python 3.12 标准库**（`random` / `math` / `statistics` / `hashlib` / `collections`），不需要 PyTorch、NumPy，也不读取任何外部数据。

---

## 目录结构

```
code/
├── ch01_offline_metrics/              § 3.1 离线评价指标
│   ├── classification_metrics.py      § 3.1.1 分类指标：Accuracy/Precision/Recall/F1 与阈值依赖
│   ├── ranking_topk_metrics.py        § 3.1.2 排序指标：NDCG/MAP/MRR/HitRate@K/Recall@K
│   ├── auc_gauc.py                    § 3.1.2 AUC / UAUC / GAUC 与「全局 AUC 选错模型」反例
│   └── calibration_metrics.py         § 3.1.3 校准指标：PCOC/COPC/ECE/MCE + Platt/Isotonic 后验校准
├── ch02_online_metrics/               § 3.2 在线评价指标
│   ├── pxtr_metrics.py                表 3.1 九个 pxtr 指标的分子/分母口径 + 消费漏斗
│   └── core_and_guardrail_metrics.py  核心指标(North Star) vs 诊断指标(Guardrail)：标题党反例
├── ch03_ab_test/                      § 3.3 A/B实验体系
│   ├── layered_traffic_split.py       § 3.3.1~3.3.2 哈希分流、三大假设校验、分层正交性
│   ├── significance_testing.py        § 3.3.2 AA 空跑、Welch t / 两比例 z、样本量、多重检验校正
│   ├── experiment_platform.py         § 3.3.2 实验平台五子系统：配置/下发/分桶/指标/分析/风控
│   ├── logging_data_quality.py        § 3.3.3 日志拼接、丢失/重复/延迟、SRM、特征快照一致性
│   └── rollout_iteration.py           § 3.3.4 5%→10%→20%→50%→100% 放量决策、新奇效应、1% Holdout
└── ch04_monitoring/                   § 3.4 推荐系统监控体系
    ├── module_metric_dashboard.py     全链路分模块指标大盘 + 四种故障的根因定位
    ├── anomaly_alerting.py            指标采集 → 同比/环比/分位数/稳健 z → 分级告警与降噪
    └── degradation_fallback.py        熔断 → 逐级降级 → 半开探测 → 逐级恢复，及四个降级监控量
```

---

## 快速运行

```bash
# 离线评价指标（§3.1）
python3 ch01_offline_metrics/classification_metrics.py
python3 ch01_offline_metrics/ranking_topk_metrics.py
python3 ch01_offline_metrics/auc_gauc.py
python3 ch01_offline_metrics/calibration_metrics.py

# 在线评价指标（§3.2）
python3 ch02_online_metrics/pxtr_metrics.py
python3 ch02_online_metrics/core_and_guardrail_metrics.py

# A/B实验体系（§3.3）
python3 ch03_ab_test/layered_traffic_split.py
python3 ch03_ab_test/significance_testing.py
python3 ch03_ab_test/experiment_platform.py
python3 ch03_ab_test/logging_data_quality.py
python3 ch03_ab_test/rollout_iteration.py

# 监控体系（§3.4）
python3 ch04_monitoring/module_metric_dashboard.py
python3 ch04_monitoring/anomaly_alerting.py
python3 ch04_monitoring/degradation_fallback.py

# 一次跑完全部 14 个脚本
find . -name '*.py' | sort | while read f; do echo "=== $f"; python3 "$f" >/dev/null || echo FAIL; done
```

---

## 各脚本要点

### § 3.1 离线评价指标

- **`classification_metrics.py`**：按正文定义实现 $$\text{Acc}=\frac{TP+TN}{TP+TN+FP+FN}$$、$$P=\frac{TP}{TP+FP}$$、$$R=\frac{TP}{TP+FN}$$、$$F_1=\frac{2PR}{P+R}$$。核心演示是正文的「高 Accuracy 陷阱」：10 万条样本、正样本率 0.0106（模拟短视频 1% CTR），全预测未点击得到 **Acc=0.9894 而 Recall=0.0000、F1=0.0000**。同一批数据上换有区分能力的模型，阈值 0.02/0.05/0.10/0.20/0.31/0.50 对应 F1 = 0.0619/0.3668/0.9991/1.0000/0.6552/0.0000——四个指标全部随阈值剧变，这正是正文偏好与阈值无关的 AUC/GAUC 的原因。另给出 P/R 冲突对照：保守模型 P=0.8571 R=0.1500，激进模型 P=0.0863 R=0.8500。
- **`ranking_topk_metrics.py`**：实现 $$\text{DCG@}K=\sum_{i=1}^{K}\frac{2^{rel_i}-1}{\log_2(i+1)}$$、$$\text{NDCG@}K=\text{DCG@}K/\text{IDCG@}K$$、$$\text{MAP@}K$$、$$\text{MRR}$$、$$\text{HitRate@}K$$、$$\text{Recall@}K$$。6 物品小例子逐行展开 DCG 计算（DCG@6=9.2869，IDCG@6=9.8235，NDCG@6=0.9454），并校验 1-based 与 0-based 折扣的一致性（K=3~6 差值 ≤ 2.22e-16）。两个消融：(a) 增益用 $$2^{rel}-1$$ 还是线性 $$rel$$，NDCG 从 0.9454 变 0.9219；(b) 失配敏感性——把最相关物品从位置 1 挪到位置 6，NDCG@6 从 1.0000 一路掉到 0.3562，说明 NDCG 比 AUC 更贴合 Top-K 展示场景。100 用户 × 200 候选、人均 8 个相关物品的多用户汇总显示 Recall@K 随 K 单调升、Precision@K 随 K 单调降（弱模型 K=5→50 时 Prec 0.1078→0.0418、Recall 0.0673→0.2612）。
- **`auc_gauc.py`**：同时用 $$\text{AUC}=\frac{\#\{s_{pos}>s_{neg}\}}{M\times N}$$、rank 公式、ROC 梯形积分三种口径实现并互相校验（600 样本上三者均为 0.780477）。取值边界验证：完美排序 1.0000、完全反序 0.0000、随机打分 0.5028、全部同分 0.5000。关键演示有两处：(a) **AUC 对正样本率不敏感**——固定模型能力，正样本率 0.5/0.1/0.01 下 AUC = 0.8005/0.8042/0.8108，这是它取代 Accuracy 的根本原因；(b) **全局 AUC 与 GAUC 结论相反**——模型 A 全局 AUC 0.8822 > 模型 B 0.5566，但 GAUC 0.4868 < 0.8224（$$\Delta\text{AUC}=-0.3256$$ 而 $$\Delta\text{GAUC}=+0.0260$$），因为模型 A 只靠「高活用户整体打分高」赚跨用户序对，而线上推荐是单次请求内同一用户的内部排序，跨用户序对不产生任何曝光决策。
- **`calibration_metrics.py`**：实现 $$\text{PCOC}=\frac{\sum \hat{p}_i}{\sum y_i}$$、COPC（同口径倒数形式）、$$\text{ECE}=\sum_b \frac{n_b}{N}|\bar{\hat p}_b-\bar y_b|$$、MCE，并实现 Platt Scaling（$$\sigma(a\cdot\text{logit}(\hat p)+b)$$，拟合得 a=0.7158、b=−1.2242）与 Isotonic Regression（PAV，18000 点合并成 41 个单调块）。核心结论对应正文的分工：校准前 AUC=0.7640 / PCOC=1.9723 / ECE=0.1341 / MCE=0.3430；Platt 后 AUC=0.7640（**不变**）、PCOC=0.9913、ECE=0.0140；Isotonic 后 AUC=0.9908、PCOC=1.0073、ECE=0.0229——两种校准都是单调（弱保序）变换，AUC 基本不动而 PCOC 被拉回 1 附近，印证「AUC 看排序、PCOC 看校准，二者可独立优化」。末尾给出广告场景的直接代价：按 $$\text{eCPM}=\text{Bid}\times\text{pCTR}$$ 排序，概率高估使 Top-1 实际收益 180 元/千次 vs 理想 200 元/千次，**相对损失 10.0%**。

### § 3.2 在线评价指标

- **`pxtr_metrics.py`**：按正文表 3.1 逐行实现 CTR/LTR/CMR/WTR/EVR/LVR/VTR/CVR/GTR 九个指标的分子分母口径（36000 条曝光日志 + 行为日志按 `req_id` 关联），并打印「模型先验 pxtr 均值 vs 后验实测」及其 PCOC，突出正文强调的区分：pxtr 是模型输出的先验预测概率，CTR 等是真实流量的后验统计。两个口径陷阱用数字量化：(a) CVR 分母误用曝光数，5.008% → 0.431%，**相差 11.63 倍，恰等于 1/CTR**；(b) EVR 的有效播放阈值 1s/3s/5s/10s/30s 给出 93.409%/86.947%/77.027%/57.415%/26.785%，LVR 完成度门槛 0.60~1.00 给出 23.748%→1.131%——阈值是产品定义，跨团队比指标前必须先对齐。末尾打印 Impression→Click→Watch→Interact→Conversion 漏斗（36000 → 3095 → 2384 → 406 → 155）。
- **`core_and_guardrail_metrics.py`**：对应 §3.2 与 §3.3.1 的核心/诊断指标二分。Base 组为多目标平衡版本，Exp 组为只优化 CTR 的激进策略（偏标题党与头部热门），各 4000 用户 × 25 次曝光。结果复现正文论断：Exp 组 **CTR +58.69%**，但**人均时长 −60.53%、互动率 −35.36%、次日留存 −8.29%、7 日留存 −7.02%**；诊断指标同步报警——归一化类目熵 −26.55%、类目 HHI +130.75%、item 基尼系数 +169.74%、去重 item 数 −60.65%、冷启动曝光率 −83.43%、hate 率 +256.57%、P99 延迟 +47.26%、超时率 +695.92%、崩溃率 +160.42%。末尾给出「不要只看均值」的分位数对照（Base 人均时长 P50=36.4s/P99=114.6s vs Exp P50=15.2s/P99=37.6s）。

### § 3.3 A/B实验体系

- **`layered_traffic_split.py`**：实现正文的 `hash(user_id) mod 100` 分流（[0,94]→Base、[95,99]→Exp，20 万用户实测 94.9685% / 5.0315%），并逐条校验 A/B 实验三大假设：
  - **均匀性**：100 桶卡方拟合优度 chi2=107.069、df=99、p=0.2724 通过；反例 `user_id mod 100` 虽然 chi2=0.000「完美均匀」，但 user_id 带注册顺序语义，低位桶可能全是老用户。
  - **随机性**：Base/Exp 平均年龄差 0.0641、新用户占比差 0.0074pp，地域分布 chi2=2.175 (p=0.5368)、机型 chi2=1.693 (p=0.4290)，无系统性差异。
  - **一致性（Sticky Assignment）**：2000 用户 × 20 次请求全部恒定同组；反例改用 `request_id` 分流，300 个用户中 **184 人（61.3%）** 在 20 次请求内切换过组。
  - **分层架构**：L0-Holdout 1% / L1-召回 Combo 80-10-10 / L2-排序 85-10-5 / L3-重排 90-10 的实际占比全部对齐设计值；L2×L3 交叉表 chi2=4.7823 (df=2, p=0.0915) 判定正交；反例「两层共用同一 salt」给出 chi2=125570.6、p=0.000，Y 层实验组被完全嵌套在 X 层实验组内。
- **`significance_testing.py`**：§3.3.2 统计推断部分。(1) **AA 空跑**：重复 2000 次（每组 3000 用户），假阳性 108 次 = **5.40%**（理论 5.00%），p 值十等分直方图各格 8.60%~11.00%，接近 U(0,1)。(2) **Welch t 检验**：人均时长 40.5913s vs 41.4702s，相对 +2.165%，t=1.6570、df=39940.9、p=0.097533、95% CI=[−0.1607,+1.9185]s → 不显著。(3) **两比例 z 检验**：CTR 10.0150% vs 10.2930%，z=4.1162、p=3.852e-05，相对提升 +2.776%、95% CI=[+1.445%,+4.125%] → 显著。(4) **样本量**：人均时长 σ=52.032s（CV≈1.30），检出相对 MDE 0.5%/1%/2%/5% 分别需每组 1,062,483 / 265,621 / 66,406 / 10,625 人（100 万 DAU、5% 流量下 21.25/5.31/1.33/0.21 天），$$n\propto 1/\delta^2$$，检出 0.5% 的成本是 2% 的 16 倍。(5) **多重检验**：m=20 个指标、其中 3 个有 +3% 真实效应，未校正下至少一个假阳性的理论概率 $$1-0.95^{20}=0.642$$；本次运行裸检验 1 个假阳性，Bonferroni 与 BH-FDR 均为 0 个假阳性，但三者真阳性都是 0（3 个真实效应在该样本量下都没检出），直观展示 FWER 控制的功效代价。该脚本含 2000 次 AA 重复，是本章最慢的脚本（约 14s）。
- **`experiment_platform.py`**：按正文 §3.3.2 列出的五个子系统组装一个进程内的 [MOCK] 实验平台。
  - **配置管理**：6 次注册里拦住 2 次——`exp_rank_dcn` 因层内桶区间 [92,99] 与同层已占桶重叠 3 个被拒；`exp_rerank_bad` 因参数 `model` 不在 L3 重排层参数空间 `(diversity_lambda, ctr_mult, hate_mult)` 内被拒。
  - **配置下发**：灰度推送 20 台实例，一致率 25%→50%→75%→**95%**，最终 1 台滞后（`rec-online-00`）；提示实验统计必须从「配置生效时间」之后起算。
  - **流量分桶**：层内互斥 + 层间正交，6 万用户中同时命中 0/1/2/3 个实验的占比为 **64.74% / 30.75% / 4.33% / 0.18%**，人均参与 0.40 个实验；分层后 L1/L2/L3 分别占用 10%/20%/10%，而若不分层这 4 个实验要在单层互斥瓜分 40% 流量——这就是正文「同一批用户流量被多个实验同时复用」的量化含义。四个实验实际占比 10.09%/10.03%/9.97%/9.85%，均对齐设计的 10%。
  - **指标计算 + 实验分析**：Welch t / 两比例 z + 95% CI。`exp_rank_mmoe` CTR +4.89%（p=5.07e-07）、时长 +6.80%（p=1.11e-09）；`exp_rerank_mmr` CTR +1.79%（p=0.0638）不显著。
  - **风险控制**：`exp_rank_aggressive` CTR **+10.94%（p≈0）显著正向**，但 hate 率 +63.11%、P99 延迟 +44.12%（124.04ms vs 86.07ms）双双破线，被风控自动置为 `stopped`；`exp_recall_i2i` 因 hate 率 +6.27% 破 −5% 护栏也被止损。配置版本推进到 v6。
- **`logging_data_quality.py`**：§3.3.3 的日志体系与数据质量保障，字段取正文列举的曝光日志（`user_id/req_id/item_id/position/exp_group/hist_len/ts/feature_snapshot`）与行为日志（`req_id/user_id/item_id/action/value/ts/event_id`）。
  - **丢失率监控**：曝光 72000→71108（丢失 **1.239%**）、行为 4034→3910（丢失 **3.074%**），双双越过 0.5% 阈值；两类日志丢失对 CTR 的偏向相反（行为丢失低估 CTR，曝光丢失产生孤儿行为并高估 CTR），必须分别监控。
  - **重复上报与幂等去重**：按 `event_id` 去重剔除 175 条（4.48%），未去重 CTR 5.4973% vs 去重 5.2512%，**虚高 +4.687%**——一次客户端重试风暴就能伪造实验收益。
  - **`req_id` 关联**：join 命中率 **98.393%**，孤儿行为 60 条（1.607%），被关窗丢弃的晚到行为 1 条；「关闸即算」vs「T+1 回溯重算」对 base 组 CTR 的低估为 −0.031%，对相对提升影响很小但对绝对值有系统性偏差，日报口径必须固定。
  - **分流信息写错的代价**：设计 +10% 的 `exp_a`，按**日志记录的分组**算相对提升为 **−4.195%，95% CI=[−17.12%,+8.73%]**；按**分桶函数重算**为 **+0.174%，95% CI=[−14.02%,+14.37%]**。两点同时成立：分流写错会把点估计拉偏数个百分点；且 5% 小流量 + 单日样本的 CI 宽达 ±十几个百分点（同时覆盖 0 与设计值 +10%），此量级根本无法判定收益，必须按 §3.3.4 放量。
  - **SRM 卡方检验**：日志口径 chi2=31.952 (df=2, p=5.066e-07) → SRM 告警、数据不可用；分桶函数口径 chi2=2.171 (p=0.3385) → 正常。工业惯例 p<0.001 即判实验失效。
  - **指标漂移**：逐小时同比 + PSI。注入的 14 点埋点故障被 |同比|>25% 规则抓到（CTR 2.1970% vs 昨日 4.8260%，**−54.48%**），而全天 PSI 仅 0.01657（<0.1 稳定）——说明单一聚合指标会掩盖局部故障。
  - **特征快照一致性**：线上快照 vs 离线重建，drift_rate=0 时字段不一致率 0.000%；drift_rate=0.03 时整体 1.925%、至少一个字段不一致的样本占 9.450%；drift_rate=0.15 时整体 9.510%、样本占 39.825%（`u_ctr_7d` 不一致率 13.625%、平均相对误差 24.960%）。这是 training-serving skew 的直接度量。
- **`rollout_iteration.py`**：§3.3.4 迭代流程。
  - **MDE 反解**：人均时长基线 42.0s、σ=54.60s（CV=1.30），α=0.05 双侧、power=80%。2,000,000 DAU 下各阶段跑到最小天数时可检出的最小提升为：5%/3 天 → 每组 150,000 人、MDE **1.3299%**；10%/3 天 → 300,000 人、0.9404%；20%/4 天 → 800,000 人、0.5759%；50%/7 天 → 3,500,000 人、0.2753%。结论：**5% 阶段的定位是验证安全性而非确认收益**。
  - **放量决策**（规则取正文：核心指标显著正向且诊断指标无明显恶化才放量；hate 率相对恶化 >5% 且显著立即回滚）：`strategy_good`（真实 +2.5%）5%→10%→20%→50%→100% 一路放量至全量；`strategy_tiny`（真实 **+0.6%**，小于 5%/10% 阶段 MDE）在 5% 与 10% 阶段多次「延长观察」，10%/7 天时触发「放量以提升功效（收益 0.160% < 本阶段 MDE 0.616%）」，放到 20% 之后才稳定显著（+0.734%，p=3.39e-04），最终全量 +0.506%；`strategy_risky`（时长 +3%、hate +40%）在 5% 首阶段即被护栏拦下（时长 +2.543% 显著，但 hate **+37.30%**）→ 回滚。
  - **新奇效应**：稳态真实提升仅 0.4%，首日被抬高 +3.0%（半衰期 2.5 天）。观察 1/2/3/5/7/10/14 天的观测提升为 +3.558%/+2.910%/+1.982%/+1.401%/+1.143%/+0.354%/+0.319%——只看首日会严重高估，这是正文要求跑多个用户行为周期的根本原因。
  - **1% 长期 Holdout**：一个季度先后全量 6 个策略，各实验 AB 测得收益朴素相加 **+6.20%**，而 Holdout 实测季度累计仅 **+3.79%**，**兑现率 61.1%**（收益重叠、新奇效应衰减、季节性）。代价也一并量化：1% 流量 7 天每组 70,000 人，**MDE ≈ 1.947%**，因此 Holdout 只用于看大盘累计收益，不用于判定单个策略。

### § 3.4 推荐系统监控体系

- **`module_metric_dashboard.py`**：按正文的分模块维度搭一个 [MOCK] 全链路指标大盘（内容池 3000 item、长尾 1500、6 类目、5 内容池、400 作者；每窗口 900 次请求、每请求召回 200 条、下发 Top-10），指标分四组：数据与索引（`feature_missing_rate` / `feature_psi` / `index_delay_sec` / `index_coverage` / `log_completeness`）、召回（分召回源的召回数、覆盖率、命中率 + 候选集时长分位数 + 长尾覆盖率）、排序（`pctr` 的 mean/P50/P90/P99、`real_ctr`、PCOC、`online_auc`、`nan_inf_cnt`）、重排混排（各内容池占比、类目熵、冷启动占比、作者去重率、Top1 作者占比）、服务稳定性（QPS、平均/P99 延迟、超时率、错误率、GPU 利用率）。健康基线窗口 0 个指标破线（PCOC=1.0443、online_auc=0.5692、长尾覆盖率=0.2220）。四个注入故障均按「最上游破线层」定位根因：
  - **故障 A（关键索引字段写坏 40%）**：数据与索引层 4 项破线——`index_coverage`=**0.6000**（阈值 0.97）、`index_delay_sec`=**930.7442**（阈值 300）、`feature_missing_rate`=0.1020（阈值 0.05）、`feature_psi`=0.7471，同时把召回覆盖率拉到 0.6000、长尾覆盖率 −36.9%、错误率 +2868.1% 一起拖下水。只看召回指标会误判成「召回模型退化」。
  - **故障 B（`i2i_cf` 召回数量跌 70%）**：仅召回层 1 项破线（`i2i_cf.recall_cnt_per_req`=15.0000 < 阈值 45.0），排序/混排指标基本不动（PCOC −2.4%、real_ctr −0.7%）——单通道供给故障。
  - **故障 C（新模型 pCTR 整体抬高 50%）**：`pctr_mean` +50.7%、**PCOC=1.5732**（阈值 1.15）破线，而 `real_ctr` +0.0%、`online_auc` −2.6% 几乎不变（单调变换不改排序）。正文原话：CTR 预测值整体提高 50% 而实际 CTR 未同步提升，意味着严重的概率高估问题。
  - **故障 D（流量突增、响应时间放大 6 倍）**：仅服务层破线，`latency_p99_ms`=**472.1001**（阈值 150）、`timeout_rate`=**0.3535**（阈值 0.01）、GPU 利用率 0.9900，而业务指标暂未受损——属容量问题，应走限流与降级而非回滚模型。
- **`anomaly_alerting.py`**：[MOCK] 3 天 × 288 个 5 分钟窗口 = 864 个窗口、3 条指标流（`ctr` / `latency_p99_ms` / `pctr_mean`），注入三类故障：D3 10:00 CTR 突降、D3 04:00 P99 尖刺、D3 16:00 pCTR 慢漂移。检测器同时算**同比**（对齐前一天同一时刻的季节基线）、**环比**、**分位数**（P50/P90/P99）与**稳健 z**（基于中位数/MAD），并要求**连续确认 ≥ 2 窗口**、**冷却 24 窗口**。结果：共 **12 条告警（P0=10 / P1=1 / P2=1）**，被冷却规则抑制掉 **211 个重复候选**。最有价值的是三种策略的命中对比（命中窗口数 vs 故障真窗口数）：`ctr` 静态阈值 33 / 仅环比 1 / 同比+稳健 z **163**（真 168）；`latency_p99_ms` 4 / 2 / 4（真 4）；`pctr_mean` 静态阈值 **0** / 仅环比 **0** / 同比+稳健 z **65**（真 96）——慢漂移每窗口只涨 0.35%，环比永远看不出、静态阈值要等绝对值涨到 0.12 才响，只有同比约掉日内周期后才暴露，这正是正文「pCTR 整体抬高而真实 CTR 未同步提升」的发现方式。
- **`degradation_fallback.py`**：[MOCK] 120 个窗口 × 10s、每窗口采样 400 请求，注入三段故障（特征服务超时 [10,28)、GPU 推理队列打满 [45,70)、召回索引抖动 [84,96)）。按正文列出的降级手段建五级梯度：**L0 正常全链路 42.0ms / 效果系数 1.000 → L1 特征服务降级 33.0ms / 0.962 → L2 模型降级 21.0ms / 0.915 → L3 召回降级 14.0ms / 0.848（兜底内容 25%）→ L4 热榜/内容池兜底 6.0ms / 0.690（兜底 100%）**。熔断器实现 CLOSED/OPEN/HALF_OPEN 状态机：故障触发后逐级下沉（第三段连下三级到 L3），冷却结束放半开探测流量，探测失败退回 OPEN 重新冷却（第一段探测失败 4 次），连续健康才逐级上浮回 L0。正文要求的四个降级监控量实测为：**降级触发次数 3 次 / 逐级恢复 6 次、降级流量占比 57.27%、兜底内容占比 2.87%、降级持续 68 个窗口 = 680s（占时间线 56.7%）**，三段降级区间分别为 [11,32) 210s 最深 L1、[46,74) 280s 最深 L2、[85,104) 190s 最深 L3。对照实验量化「用可控效果损失换可用性」：**有降级请求成功率 98.07%、平均 P99 66.6ms、累计效果系数 0.9355**；**无降级硬扛成功率 87.26%、平均 P99 168.0ms、累计效果系数 0.8726**——用户看到的是略差的推荐而不是白屏。

---

## 实现约定

- **纯标准库**：本章全部 14 个脚本只用 Python 3.12 标准库，不依赖 PyTorch / NumPy / matplotlib，也不联网、不读本地数据集；所有「数据」都在脚本内用 `random` 合成。可视化一律以数值表格打印。
- **自包含**：文件之间不互相 import，每个文件可单独运行；顶部 docstring 标注对应的正文节次、本实现做了什么、以及关键公式。
- **可复现**：每个 `__main__` 块固定 `random.seed(42)`，输出可复现。
- **[MOCK] 标注**：教学用的假组件（实验配置中心与配置下发、日志采集链路、指标流、内容池与请求流、依赖服务与熔断器）均在 docstring 里标 `[MOCK]`，均为进程内模拟，不起真实服务、不做真实 RPC。
- **以已发布 PDF 为准**：公式、阈值与流程以第 3 章发布 PDF 的对应章节和表 3.1 为准，包括 §3.1.2 的 $$2^{rel}-1$$ 增益口径、pxtr 分子/分母定义、§3.3.1 的 `hash(user_id) mod 100` + [95,99] 分流示例、§3.3.4 的 5%→10%→20%→50%→100% 扩量阶梯与 1% 长期 Holdout、§3.4 的分模块指标清单。统计量（Welch t、两比例 z、卡方、样本量/MDE 反解、正态与 t 分布尾概率）全部手写实现，不调用 `scipy`。
- **运行开销**：14 个脚本串行总耗时约 **30s**（单机 CPU）。最慢的是 `significance_testing.py`（约 14s，2000 次 AA 重复）；其余脚本均在 4s 内完成。
