成功率 90% 的 Agent,连续 8 次都对的概率只有 43%
"跑 k 次至少对 1 次"叫 pass@k,"跑 k 次次次都对"叫 pass^k。k 越大,两者差得越远。
能重试的场景看 pass@k;用户只给一次机会的场景(客服、退款、改数据库)看 pass^k。
1直觉:同一个 90%,两种完全不同的说法
一个 Agent 单次成功率 \(p = 90\%\)。让它对同一个任务跑 8 次:
- 至少成功 1 次的概率:几乎 100%。只要 8 次不是全挂就行。
- 8 次全部成功的概率:\(0.9^8 \approx 43\%\)。还不到一半。
同一个 Agent,一个指标看着接近完美,另一个指标说明它"一半时候靠不住"。你汇报哪个,取决于产品是怎么用它的。
2公式
设单次成功率为 \(p\),每次运行相互独立:
$$\text{pass@}k = 1 - (1-p)^k \qquad\qquad \text{pass}^k = p^k$$pass@k:k 次至少 1 次成功 = 1 − "k 次全失败"。由 Kulal et al.(2019,SPoC)提出,OpenAI 的 Codex 论文(Chen et al., 2021)推广开并给出无偏估计量,评代码生成:生成 k 份代码,有一份通过单测就算解出。
pass^k(读作 pass hat k):k 次全部成功。出自 τ-bench(Yao et al., 2024),评客服类 Agent:同一个用户请求跑 k 次,要求每次都处理对。
| 单次成功率 p | k = 1 | pass@3 | pass@8 | pass^3 | pass^8 |
|---|---|---|---|---|---|
| 50% | 50% | 87.5% | 99.6% | 12.5% | 0.4% |
| 80% | 80% | 99.2% | >99.9% | 51.2% | 16.8% |
| 90% | 90% | 99.9% | >99.9% | 72.9% | 43.0% |
| 99% | 99% | >99.9% | >99.9% | 97.0% | 92.3% |
三个规律:
- k = 1 时两者相等,都是 \(p\)。
- k 越大,pass@k 越高,pass^k 越低,差距一路拉大。\(p=90\%\) 时,k = 3 差 27 个百分点,k = 8 差 57 个。
- pass^k 对 p 极其敏感:p 从 90% 提到 99%,pass^8 从 43% 涨到 92%。想要"8 次都对的概率 ≥ 90%",单次成功率得 ≥ 98.7%。
3该用哪个:看用户有没有重试机会
| 场景 | 指标 | 理由 |
|---|---|---|
| 代码生成,有单测把关 | pass@k | 生成 k 份,自动挑通过测试的那份,失败的用户看不见 |
| 搜索 / 头脑风暴,用户会自己挑 | pass@k | 给 k 个候选,有一个好的就行 |
| 客服、退款、订票 Agent | pass^k | 每个用户只有一次机会;同样的请求来 k 次,每次都得对 |
| 改数据库、发邮件、执行命令 | pass^k | 操作不可撤销,错一次就是事故 |
4实际怎么算:无偏估计量
真实的 \(p\) 不知道。做法是对每个任务跑 \(n\) 次(\(n \ge k\)),数出成功 \(c\) 次。直觉上直接代入 \(\hat p = c/n\):\(1-(1-\hat p)^k\)。但这样算出来的 pass@k 系统性偏低;pass^k 正好相反,直接代入会系统性偏高。
Codex 论文给的无偏估计:从 n 次结果里不放回地抽 k 次,算"抽到的 k 次全失败"的概率:
$$\widehat{\text{pass@}k} = 1 - \frac{\binom{n-c}{k}}{\binom{n}{k}} \qquad\qquad \widehat{\text{pass}^k} = \frac{\binom{c}{k}}{\binom{n}{k}}$$分子:从 n − c 次失败里选 k 次的组合数;分母:从 n 次里选 k 次的组合数。pass^k 同理,从 c 次成功里选 k 次(τ-bench 用的就是这个)。
例子:跑 10 次,成功 3 次,求 pass@5。
- 无偏估计:\(1 - \binom{7}{5}/\binom{10}{5} = 1 - 21/252 \approx 91.7\%\)
- 直接代入:\(1 - 0.7^5 \approx 83.2\%\),低了 8 个多百分点
多个任务:每个任务单独算 pass@k 或 pass^k,再对所有任务取平均。不能先把所有任务的成功率平均成一个 p 再套公式,原因见第 6 节。
5和 rule of three / Wilson 的关系:p 本身就不准
上面的公式都把 \(p\) 当成已知。可 \(p\) 是跑出来的估计,本身带不确定性,pass^k 会把这个不确定性放大。
因为 \(p^k\) 随 \(p\) 单调增,把 p 的置信区间两端各自取 k 次方,就得到 pass^k 的区间。
| 观测 | p 的 95% 区间 | pass^8 点估计(无偏) | pass^8 区间 |
|---|---|---|---|
| 30 次成功 27 次 | Wilson 双侧 95%:[74.4%, 96.5%] | 37.9%(直接代入为 43.0%) | [9.4%, 75.5%] |
| 30 次全过 | 精确法单侧 95%:p ≥ 90.5% | — | ≥ 45.0% |
30 次成功 27 次,pass^8 可能低到 9%,也可能高到 75%。只报一个点估计,等于没说清楚。注意两行口径不同:第一行是双侧区间,第二行是单侧下界。
6公式成立的前提:每次运行独立、成功率相同
\(p^k\) 成立,要求 k 次运行相互独立、每次成功率都是同一个 \(p\)。现实中常常不满足。
例子:两个 Agent 在 10 个任务上的平均单次成功率都是 70%。
- Agent A:每个任务的成功率都是 70%,时好时坏。pass^8 = \(0.7^8 \approx 5.8\%\)。
- Agent B:7 个任务每次必对,3 个任务每次必错。pass^8 = 70%。
平均成功率一样,pass^8 差了 12 倍。A 是"不稳定",B 是"稳定地不会",两种问题的修法完全不同。这也是为什么要按任务分别计算再平均。
同一个 prompt 重跑 k 次、换个 temperature 或换个用例,算不算"独立的 k 次"?这是下一章「独立性假设」的内容。
▶互动演示:拖 p 和 k,看两条曲线怎么分开
▶计算器:跑了 n 次、成功 c 次
无偏估计量用组合数算;"直接代入"是把 c/n 当成 p 套公式。最后一列用 p 的 Wilson 95% 区间推出 pass^k 的区间。
✎练习
7面试要点与代码
一句话讲清楚
pass@k 是 k 次里至少对一次,衡量能力上限,适合能自动挑结果的场景;pass^k 是 k 次全对,衡量稳定性,适合用户只有一次机会的 Agent。k 越大两者差距越大。实际计算用组合数的无偏估计,按任务分别算再平均,并且要记得 p 本身有置信区间。
常见错误说法
❌ "c/n 代进 1 − (1 − p)k 就是 pass@k":有偏,系统性偏低,要用组合数公式。
❌ "所有任务平均成功率 70%,所以 pass^8 = 0.78":任务之间成功率不一样,要逐任务算。
❌ "跑了 8 次就能算 pass@8":只跑 n = k 次,估计量只能是 0 或 1,方差很大。Codex 论文每题采样 n = 200。
from math import comb
def pass_at_k(n: int, c: int, k: int) -> float:
"""n 次里成功 c 次,pass@k 的无偏估计(Chen et al., 2021)。"""
if not 0 <= c <= n or not 1 <= k <= n:
raise ValueError(f"需要 0 <= c <= n 且 1 <= k <= n,收到 n={n}, c={c}, k={k}")
if n - c < k: # 失败次数不够 k 次,抽 k 次必有成功
return 1.0
return 1 - comb(n - c, k) / comb(n, k)
def pass_hat_k(n: int, c: int, k: int) -> float:
"""n 次里成功 c 次,pass^k 的无偏估计(τ-bench)。"""
if not 0 <= c <= n or not 1 <= k <= n:
raise ValueError(f"需要 0 <= c <= n 且 1 <= k <= n,收到 n={n}, c={c}, k={k}")
return comb(c, k) / comb(n, k)
print(pass_at_k(10, 3, 5)) # 0.9167
print(pass_hat_k(10, 7, 3)) # 0.2917
公式显示依赖 KaTeX(CDN),断网时公式会显示成原始 LaTeX 源码,交互部分不受影响。