Bootstrap CI + 收口
Day 19 我们算出了 judge-human κ 的点估计并对照 0.6 阈值——但点估计会骗人,尤其样本小的时候。
阶段: B2 · attention/decoder/KV + judge 校准(Day 11-20) 标签: #bootstrap #confidence-interval #error-bars #eval-rigor
今日导引(由浅入深)
Day 19 我们算出了 judge-human κ 的点估计并对照 0.6 阈值——但点估计会骗人,尤其样本小的时候。
今天给 κ 加上 95% 置信区间(bootstrap 重采样),并把整个 B2 block 的所有数字(attention 数值对齐 diff、KV cache 提速倍数、JSON-validity sweep、judge κ)汇成一份收口报告,跑 pnpm test 封板。
这是 B1→B18 能力曲线里「会算指标 → 会给指标加诚实误差棒并收口」的最后一跳,也是 B2 阶段的总闸。过了今天,B2(attention/decoder/KV + judge 校准)整块封板,B3(Day 21-30,agent loop + 评测统计)接棒——而 B3 的统计部分正是建立在今天打下的 CI 纪律之上。
今日最小可判定产出:形如 κ=0.71 [0.58, 0.83] 的带 CI 报告 + report-b2.md 整合表 + 测试绿。
1. 机理精读
点估计 κ 单看会误导:N 小、类不平衡、或某几条配对恰好特殊,都会让单个 κ 值偏离真实一致性。修正办法是 bootstrap 重采样——对 N 条 trace 配对做有放回抽样,重复 ≥2000 次,每次重算一个 κ,得到 κ 的经验分布,取 2.5/97.5 分位作 95% percentile CI。
CI 的宽度直接告诉你「这个点估计能不能信」:
- N < 50 时 CI 太宽,比如 κ=0.71 [0.30, 0.95]——区间横跨「差」到「很好」,根本下不了结论。
- N ≥ 50 才收窄到可下结论的程度,窄 CI 才支撑「judge 可用」的判断。这正是 Day 18 坚持标 ≥50 条 gold 的统计动机。
为什么用 percentile bootstrap 而不是解析方差公式?因为 κ 没有简洁的解析方差(它是两个边缘分布的非线性函数),直接套正态近似会在小样本/偏态下失真。bootstrap 用重采样直接逼近 κ 的抽样分布,无需对分布形态做任何假设——这是它在 eval 场景特别合适的原因。
为什么 2000 次是下限?bootstrap 的 CI 端点本身也是个估计,次数太少(如 200)会让 2.5/97.5 分位抖动明显。2000 次让分位估计稳定,且 κ 计算极轻(O(N)),2000 次毫秒级,没有理由省。更激进的场景可上 10000 次,但 2000 是稳健下限。
设计权衡:bootstrap 是「用计算换分布假设」——它不要求你知道 κ 的真实分布,代价是 B 次重算。对 κ 这种轻量统计量,这笔交易极划算。本日承接 Miller《Adding Error Bars to Evals》(2024-11)——2026 评审硬要求误差棒,无 CI 的 κ 不予采信。这一条把「评测严谨性」从「报个数字」抬到「报数字 + 区间 + 样本量」的标准。
与相邻概念的边界:Day 19 给「judge 像不像人」一个点;Day 20 给那个点配区间,并把 B2 整块的离散产出收成一份可追溯报告——从此 B2 的每个数字都带状态标签(已完成 / 待跑 / 待建)和(若已测)误差棒。
2. 推导 / 手算 / 代码走读
本日复用 src/agent/eval/cohensKappa.ts 的 bootstrap 路径(真实文件,已 Read,已测试绿)。走读其 bootstrap 实现要点:
cohensKappaWithCI(a, b, { bootstrap = 2000, rng }):先取点估计point = cohensKappa(a, b);循环 B 次,每次对n个下标做j = floor(rng() * n)的有放回抽样,重建ra/rb两数组,samples.push(cohensKappa(ra, rb).kappa)。- 抽完
samples.sort(...)升序,ci95 = [percentile(samples, 2.5), percentile(samples, 97.5)]。 rng可注入(默认Math.random)——这让单测能用确定性种子复现 CI,是它能进 CI/测试套件的关键。- 返回
KappaResult:{ kappa, po, pe, n, ci95, bootstrapSamples }——一行就拿到点估计 + 区间 + 样本量。
注意实现细节:bootstrap 是对配对重采样(同一个下标 j 同时取 a[j] 和 b[j]),而不是对两个评分者各自独立抽——这保留了 judge 与人在每条 trace 上的相关结构,否则会破坏配对、低估一致性。源码里 ra[i]=a[j]; rb[i]=b[j] 正是这个配对抽样。
percentile(sorted, p) 的线性插值逻辑(取 2.5/97.5 分位时实际走的路径):
idx = (p/100) * (len - 1)
lo = floor(idx), hi = ceil(idx)
若 lo == hi: 返回 sorted[lo]
否则: 按权重 w = idx - lo 在 sorted[lo] 与 sorted[hi] 间线性插值
这保证了 CI 端点不是粗暴取最近样本,而是平滑插值——在 B=2000 的有序样本上,2.5% 分位约落在第 50 个、97.5% 约落在第 1950 个附近,两端各截掉约 50 个极端重采样值。
手算示意(理解 N 对 CI 宽度的影响):bootstrap CI 宽度大致 ∝ 1/√N。
N=25 → 标准误 ∝ 1/5 = 0.20
N=50 → 标准误 ∝ 1/√50 ≈ 0.141
N 从 25 翻到 50,标准误约缩 √2≈1.41 倍——这就是为什么 50 是「能下结论」的经验门槛,也是 labels.example.json 的 _README 里强调 ≥50 条的统计根据。(此为定性说明,非本块实测 κ。)
report-b2.md 的收口表目标形态(每行带状态标签,数字按 seed 如实标):
指标 | 值 | 状态
-----------------------------+-----------------+--------------------
attention 数值对齐 max diff | <1e-4 (目标) | 待建/待跑
KV cache 提速倍数 | ?× (待实测) | 待建/待跑
JSON-validity sweep | 折线+表 | 待跑(需 key)
judge-human κ + 95% CI | κ=? [?, ?] | 待跑(需 key)
仓库测试套件 | 378 passed | 已完成 (tsc clean)
这张表是 B2 的「单一事实来源」:每个数字都带状态,待跑的绝不伪装成已完成,已完成的(378 测试绿)如实标注。评审看这张表就能一眼分清「哪些是真测量、哪些等 key」。
3. 今日实战
- 用
src/agent/eval/cohensKappa.ts的 bootstrap 路径对 50 条配对标签跑 2000 次重采样,出 κ 的 95% CI。 - 整合本 block 全部数字成
agent-evals/report-b2.md:- attention 数值对齐 diff(Day 13)
- KV cache 提速倍数(Day 14)
- JSON-validity sweep(Day 16)
- judge-human κ + CI(Day 19-20) 每项标清状态(已完成 / 待跑(需 key) / 待建)。
- 跑
pnpm test收口,本 block 新增测试并入。 - CI 报告形如
κ=0.71 [0.58, 0.83](示例形态,非实测)。
4. 今日实测 / 产出
- 状态:待跑(需 OPENROUTER_API_KEY 出 κ);bootstrap CI 管道在
src/agent/eval/cohensKappa.ts已测试绿。 - 目标产出:形如
κ=0.71 [0.58, 0.83]的报告(示例形态,具体数字待跑,不臆造)。 - 仓库现状:全套 378 测试通过、tsc clean,本 block 新增测试将并入。
5. 常见误区 / 陷阱
- 只报点估计无 CI——2026 评审硬要求误差棒,无 CI 的 κ 不予采信。
- bootstrap 次数太少(如 200 次)——分位估计本身抖,2000 是稳健下限。
- N<50 还硬下「judge 可用」结论——CI 太宽,区间横跨差到很好,结论无效。
- 把示例
κ=0.71 [0.58,0.83]当真实测量写进报告——必须标注待跑,诚信底线。
6. 学习资源(每条带 YYYY-MM)
- Miller, E., Adding Error Bars to Evals (2024-11) — 本日权威来源:eval 误差棒方法论,仍 current。
- Efron & Tibshirani, An Introduction to the Bootstrap (经典) — percentile bootstrap 的理论打底。
- Anthropic, Demystifying Evals (2026-01) — gold-set + κ + CI 的完整评测纪律。
- 仓库代码
src/agent/eval/cohensKappa.ts(bootstrap CI 路径,RNG 可注入,已测试绿)— 本日 CI 实现底座。
SOTA检查 (2026-06 更新)
- 当前主流方案:Miller《Adding Error Bars to Evals》(2024-11) 仍是 eval 误差棒权威,current;2000 次 bootstrap 是稳健下限。
- 是否仍 SOTA:是;2026 评审把「点估计 + CI + 样本量」作为评测报告的硬标准。
- 过时黑名单:避免只报点估计无 CI(不予采信);避免 bootstrap 次数不足;避免 N<50 强下结论。
- 下次复查点:2026-Q3 复核误差棒方法(percentile vs BCa bootstrap)与多指标联合报告的评审新规,以及本 block 待跑数字(judge κ)在补齐 key 后回填。
衔接
- 昨天:Day 19 — judge-human κ(点估计 + 0.6 阈值判定)
- 今天:给 κ 加 95% bootstrap CI,整合 B2 全部数字成 report-b2.md,跑
pnpm test收口 B2。 - 明天:Day 21 — Agent loop 范式(B3 开篇:workflow vs agent,观测→决策→工具→反馈回路)