高难度 Benchmark 不该变成编程技巧题

1 minute read

Published:

AI 科学 Benchmark 最危险的失败方式,不是它太难,而是它悄悄变成了一道编程技巧题或猜谜题。

作者:Koutian WuGitHub: ktwu01

今天,我和自己的 Agent 进行了一场很有意思的争论。

事情本身很具体。我们当时在看一个科学 Agent Benchmark 的 Pull Request。审稿人 Allen 请我们对任务做压力测试,检查它是否公平。Agent 确实失败了,这一点已经很清楚。更尖锐的问题是,它们是否败在了这项测试本应考查的地方。

这听起来只是一个细微的区别,但我认为这就是整件事的核心。

糟糕的 Benchmark 之所以难,可能是因为它藏起了任意细节。好的 Benchmark 之所以难,是因为现实本来就难。

一开始,我的 Agent 做了一件强大的编程 Agent 理应做的事。它读完任务文件,发现了一个真实的不一致之处,并指出说明文字声称几个案例都从同一行物理强迫数据开始,实际数据却使用了五行不同的强迫数据。这是一个真实的 Bug,修起来成本很低,也没有什么争议。

然后,它又往前走了一步。

它开始对 oracle 做扰动测试。如果一个在科学上合理的解法用了不同的米氏常数,会怎样?如果它用了 Jmax 饱和型电子传递形式,会怎样?如果它用了不同的 C4 初始斜率,又会怎样?其中一些选择在植物生理学上完全说得通,但另一些却完全无法通过验证器。

Agent 最初的判断大致是:这个任务是在猜 oracle。

我很强硬地反驳了它。

因为我在意的不是让 Agent 做得舒服。科学 Benchmark 的目的,不是把每一个常数都写在题面上,再给 Agent 一道整整齐齐的编程练习。那样做,任务就不再是科学,只剩下实现。

而 SOTA Agent 已经很擅长实现了。

下面这些话就是我当时对 Agent 说的。坦白讲,我现在仍然坚持这个观点。

我确实认为,我们不需要把常数提供给 Agent。如果给出常数,一切都会变成编程技巧题,Agent 也会轻易完成所有任务。如果把每一个精确参数都给它们,这就会变成一道没有难度的编程技巧题,失去科学意义。

我认为这样并不好,因为任务会变得毫无用处。它不再是一项科学任务,因为 SOTA Agent 非常擅长编程,肯定能在一次调用里完成所有任务。

我们是来挑战它们的,不是来设计另一道毫无用处的编程技巧题。你也知道,即使是 HumanLast exam 这样的考试,有时也不会提供任何数值。题目不会把数值直接给出来,只让 Agent 作答,因为找出那些数字本来就是测试的一部分。

我们应该让题目足够难,而且在这里,这种难度在科学上是有效的。

这段话点出了人们谈论 Benchmark 时反复回避的争论。

如果把每条方程、每个参数、每项容差、每个特殊情况、每个分支条件和每项数据约定都交给模型,那么 Claude Code、Codex 或 Cursor 当然能写出求解器。那不是科学推理任务,只是变量名更好看的一场编程面试。

科学里困难的部分,往往不是别人给出方程以后把它敲出来。

真正困难的是知道这个世界里该用哪条方程。

真正的科学家必须知道去哪里找资料,当前问题沿用了哪条文献脉络,这个子领域通常接受哪些假设,哪种参数化属于哪个模型家族,以及哪些细节是物理的一部分,哪些只是装饰性背景。如果 Agent 能访问互联网,要求它找出这些信息并非不公平。这本来就是任务的一部分。

这也是我认为 HumanLast exam 这个类比很重要的原因。那些题目往往不会给出每一个数字,只会要求你作答。找到缺失的正确数字、正确的定理、正确的历史事实和世界中正确的对象,本来就是测试的一部分。

所以,我不想把常数粘贴进 Prompt。

我真的不想。

但接下来,Agent 说了一件改变整个争论结构的话。

它纠正了自己。重新阅读任务后,它意识到 oracle 并不是随机设定的,也不是一堆任意的秘密常数。它采用的是一种可辨认的 Collatz 和 Ball-Berry 风格参数化,属于 CLM 和 Bonan 的学术脉络。Agent 先前太快地把它称为临时拼凑的方案。

这个纠正很重要。

随后,它作出了一项区分。我认为,这是整场争论最清楚的表述。

Hard = 即使方法正确,专家也需要付出努力才能通过。很好,保留这种难度。

Valid = 只要推理正确,专家就能够通过。

界线就在这里。

Benchmark 当然应该让 Agent 付出努力。它应该迫使 Agent 搜索、阅读、推断、测试、调试,并从错误路径中恢复。它应该惩罚浅层的模式匹配,也应该惩罚那些听起来合理、却始终无法变成有效科学结果的文字。

但如果一位专家正确解决了一个描述不充分的问题,只是选择了另一个同样有效的版本,Benchmark 就不应该惩罚他。

这就是隐藏答案和隐藏问题之间的区别。

隐藏答案没有问题,考试本来就是这样。

隐藏问题则不行,那会让测试在无意中变成读心术。

在这项任务里,正确做法不是把 Kc、Ko、Q10 数值、Ball-Berry 截距、光转换细节和求解器容差全部塞进说明文字。那等于替 Agent 完成了本该由它承担的科学判断。

真正需要的改动要小得多。

说出模型家族的名字。

说明目标是一个 Collatz 风格光合作用与 Ball-Berry 气孔导度相耦合的叶片模型,属于 CLM 或 Bonan 的学术脉络。不要提供常数,不要写出方程,也不要把任务变成操作手册。只要告诉 Agent,它应该重建的科学对象究竟是什么。

Agent 的表述很好。

说出模型名称是在明确问题要求,并不是给出答案。

我很喜欢这句话。

因为它在保留难度的同时消除了不公平。

如果 Agent 现在仍然失败,那很好。它失败是因为没有正确重建指定的科学模型。它也许选错了论文,也许找到了常数却错误实现了耦合,也许弄错了 C3 和 C4 分支,也许没有注意夜间分支,也许固定点始终没有收敛。这些都是真实的失败。

这些才是我想测量的失败。

我不想测量的是,Agent 能否猜中隐藏的 oracle 默默偏爱植物生理学中的哪一个有效流派。

Benchmark 设计到了这里,会变得有些哲学化。

你始终在选择自己想暴露哪一种无知。

你想暴露的是,当所有科学内容都已经交到 Agent 手里以后,它仍然不会编写求解器吗?这已经没有多大意思了。

你想暴露的是,Agent 无法从稀疏但公平的科学背景中找回正确的模型脉络吗?这很有意思。

你想暴露的是,Agent 无法阅读论文、把文字转成方程、处理单位、耦合非线性过程并验证收敛吗?这非常有意思。

你想暴露的是,Agent 猜不中你私下采用的隐藏约定吗?那只是噪声。

麻烦在于,这四种情况都会导致一次运行失败。

从外面看,13 分或 55 分都只是失败。但如果你关心 Benchmark 的质量,就必须追问它属于哪一种失败。科学理解混乱造成的失败是信号,模糊 Prompt 造成的失败是债务。

我认为,这正是 Allen 的观点。

不是让它更容易。

而是让它站得住脚。

在设计高难度任务时,人们很容易把每一个隐藏细节都辩护成挑战的一部分。我理解这种冲动,我自己也会这样想。如果 Agent 太强,每一条背景信息都会让人觉得危险。你会开始担心,只要说出模型名称,它们也许搜索一下就能解决问题。只要提到学术脉络,整项任务也许就会坍缩成代码实现。

但这种恐惧会把你推向一个糟糕的地方。

你开始隐瞒科学对象本身的身份。

这不是严谨,只是披着难度外衣的歧义。

更好的标准应该更苛刻,也更清楚。尽可能少地提供背景,但必须给出让目标具有唯一性所需的背景。不要多,也不要少。

尽可能少地提供背景,但必须给出让目标具有唯一性所需的背景。

对这项任务而言,这意味着只做最小修改。修正有关强迫数据行的事实表述错误。点明 Collatz 和 Ball-Berry 的学术脉络。明确 PAR 字段是否已经是模型所使用的光量,否则吸收光和入射光就会成为另一项隐藏约定。不要给常数,不要给方程,保留互联网访问,再运行一次 Agent,看看它们是否仍然失败。

如果它们过于轻松地通过,那这项任务从一开始就没有测试科学。它测试的是 Agent 能否从一个描述不充分的 Prompt 中活下来。

如果它们仍然失败,那很好。

现在,这次失败有了意义。

我认为,这会成为 AI 评估的核心问题之一。随着 Agent 越来越擅长编程,让 Benchmark 变难的廉价办法就是隐藏越来越多的细节。但这条路最终会造出只有 Benchmark 作者本人才能解决的谜题。

更有价值的路径不同。让任务锚定在真实的领域对象上,让目标能够被唯一地找回,让求解过程保持艰难,让工作本身保持科学性。

不要给出常数。

不要设计一道毫无用处的编程技巧题。

但也不要逼 Agent 猜你的心思。

界线就在这里。