智能体评测何时停?先定规则再跑分
文章用预先登记的序贯停止规则,替代看到几次成功就结束评测的做法,以减少提前停止造成的选型偏差。约四十行 Python 在固定任务池上输出采用、放弃或预算耗尽后的回退决策,不承担精确排名或通过率估计。
AI 深度解读
免费 AI 编程接口跑过几道题,就能接进日常开发吗?作者认为,最容易误导团队的不是测试结果,而是「看到结果不错就收工」:五题过四题便宣布通过率 80%,再从十个接口里挑一个,很可能选中了开局运气最好的那个。
作者给出的办法,是提前冻结任务、环境和停止规则,再用约四十行 Python 决定采用还是放弃。这套流程有借鉴价值,但文中的校准预期和预算兜底存在问题,值得连同代码一起看清楚。
先固定考卷,才有资格讨论接口好不好
这套评测只回答一个问题:在预先固定的任务池上,这个接口是否值得采用。
它不负责估计带置信区间的通过率,也不负责判断两个合格接口谁更强。作者明确区分了「做采用决策」和「精确测量差距」:要区分 71% 与 74%,需要数百道任务和另一种实验设计,不能指望小样本顺序测试解决。
第一步是准备 60 道留出任务,而不是 20 道。留出任务就是没有参与前期调试、专门留给正式评测的题目。先确定任务,再接触被测接口;看见失败后改题,评测就变成了挑选有利样本。
随后只打乱一次顺序,公开随机种子,并提交最终排列。这样,团队就不能临时跳过那道「感觉会失败」的题。原文记录的 order_seed=20261107,作用是让顺序可以复现。
运行环境也要冻结,包括容器镜像摘要、Python 版本、测试运行器版本、单题时限,以及测试阶段是否允许联网。原文示例用 docker inspect -f '{{.Image}}' bench-runner 取得镜像标识,用 python3 -V 记录版本,把 wall_clock_s=300 写进 manifest.txt,但没有指定实际 Python 或测试运行器版本。
作者要求把环境标识附在每条评测记录旁。镜像摘要中途变化,就停止当前计划。对代码修复任务而言,依赖、工具链和网络条件都可能影响测试结果;这些条件没固定,就很难判断变化来自模型还是运行环境。
每跑一道题,都用同一条规则决定是否继续
作者采用 Wald 序贯概率比检验,也就是 SPRT。它允许逐题查看结果,但每次查看后采取什么动作,必须提前写好,不能临场决定。
下面这段 sprt.py 根据累计成功和失败次数,输出采用、放弃、继续,或触及预算上限后的结果:
"""sprt.py — pre-registered sequential stopping rule for a pass/fail bench."""
import math
from dataclasses import dataclass
@dataclass(frozen=True)
class Plan:
p_adopt: float = 0.60 # H0: the pass rate you would ship with
p_drop: float = 0.40 # H1: the pass rate you would walk away from
alpha: float = 0.10 # tolerated false-adopt rate
beta: float = 0.10 # tolerated false-drop rate
n_cap: int = 60 # hard ceiling = pool size
def llr(self, passes: int, fails: int) -> float:
return (
passes * math.log(self.p_adopt / self.p_drop)
+ fails * math.log((1 - self.p_adopt) / (1 - self.p_drop))
)
def decide(self, passes: int, fails: int) -> str:
n = passes + fails
llr = self.llr(passes, fails)
upper = math.log((1 - self.beta) / self.alpha)
lower = math.log(self.beta / (1 - self.alpha))
if llr >= upper:
return "adopt"
if llr <= lower:
return "drop"
if n >= self.n_cap:
# out of budget and still undecided: fall back to the point estimate
return "cap-adopt" if passes / n >= self.p_adopt else "cap-drop"
return "continue"
def run_plan(results, plan=None):
"""results: iterable of 0/1 in the pre-registered order. Yields ledger rows."""
plan = plan or Plan()
passes = fails = 0
for n, ok in enumerate(results, start=1):
passes += int(ok)
fails += 1 - int(ok)
verdict = plan.decide(passes, fails)
yield {
"n": n, "passes": passes, "fails": fails,
"llr": round(plan.llr(passes, fails), 3), "verdict": verdict,
}
if verdict != "continue":
return
要盯住的是两个概率参数和 n_cap 分支:前者决定证据如何累计,后者额外引入了一条预算耗尽后的决策政策。
默认设置把 0.60 作为愿意采用的通过率,把 0.40 作为愿意放弃的通过率,alpha=0.10、beta=0.10 表达作者设定的错误容忍目标。这不是「测到 60% 就立即采用」。
代码先算对数似然比 LLR:当前结果更支持 0.60,还是更支持 0.40。默认参数对称,公式可简化为:
LLR ≈ 0.4055 ×(成功数 − 失败数)
上下边界约为 ±2.197。因此,成功数比失败数多 6 次就采用,少 6 次就放弃,否则继续,最多累计 60 次有效结果。每行记录包含 n、passes、fails、llr 和 verdict,用表格也能复核。
免费接口还会遇到限流、断连、补丁无法干净应用等情况。作者主张标为 invalid,不进入成功数或失败数,按既定顺序重跑同一道题,同时单独报告无效率。通过率再好,若无效率达到 30%,实际使用也可能难以接受。
这里的关键是保留每次尝试。悄悄重试到成功,只展示最后一次,会把服务不稳定从报告里抹掉。
我的判断
我认同「先登记规则,再看结果」这个方向。相比跑到满意就停,固定任务、顺序、环境和记录,确实更容易审查。文章也披露了 MonkeyCode 产品推广背景;免费模型访问和免费服务器是这套流程的资源选项,方法并不依赖这个品牌。
但原文没有提供真实接口的完整评测记录,也没有贴出模拟输出。它给出的是可检查的方法和代码,不能据此认定某个产品有效。
最需要打问号的是校准说明。作者提供的 calibrate.py 默认执行 trials=20_000,随机种子为 seed=7,通过 python calibrate.py 检查 p_true 为 0.30、0.50、0.70 的情况。正文建议先看 0.70,再看 0.30,最后看 0.50,并声称 0.50 时多数实验应耗尽预算。
没有方向性偏移,不代表多数实验会一直留在边界内。
按照这段代码,0.50 对应的成功与失败之差会随机上下走动,碰到正负 6 就结束。它完全可能靠随机波动提前碰线。原文把「多数耗尽预算」当成正确性标准,缺乏依据,不能拿这句描述验收脚本。
预算兜底还有一个可以直接推导的问题:默认参数下,cap-adopt 实际不会出现。若走到第 60 题仍未碰线,成功与失败之差只能在正负 4 以内,成功数最多 32,通过率最多约 53.3%,达不到兜底要求的 60%。所以,默认规则中所有预算耗尽且未越界的情况都会成为 cap-drop。
这可以是一种保守政策,但不能把它和原始 SPRT 的错误控制混为一谈。应在 0.40、0.60 以及中间区域校准最终采用概率,并把兜底结果一起统计。
还有两个迁移前提。固定题池中的任务可能相关,逐题成功概率也未必相同,独立同分布的模拟不能自动代表真实代码任务。无效运行的界定同样需要预先写清:补丁格式错误如果经常由模型造成,全部剔除会高估能力。
与固定样本量测试相比,顺序测试适合尽早淘汰明显不合格的候选;需要比较细小差距时,固定样本量设计更合适。若同时筛选十个接口,单次规则的错误容忍目标也不等于整个筛选流程的保证。
能拿来做什么
- 给前端或 Node 编程代理换接口前,先冻结一组真实修复任务,写清验收测试、依赖环境、超时和联网条件,再运行候选接口。
- 在评测器里分别记录有效成功、有效失败和无效尝试,并提前约定重试次数与总预算。原文的
n_cap=60只限制有效结果,不能限制实际请求次数。 - 采用这段代码前,先检查 0.30、0.40、0.50、0.60、0.70 下的决策分布、平均任务数和预算耗尽比例,确认它符合团队的采用标准。
- 把计划、任务顺序、环境标识和记录路径放进切换接口的 PR。若只想确认接口能否产出补丁,就先做一道题的冒烟测试,不必包装成通过率结论。