Skip to content

评估 ​

本页定义 eyeful 的评估实验。实验方案已冻结在研究方案里;本页和方案不一致时,以方案为准。eval/ 里的脚本已经写好,运行还没有做(见路线图)。结果等主实验跑完再补上。

研究问题 ​

与更简单的 LLM 审查者相比,带规划的多专家审查加上基于执行的验证,能否找到更多要紧的缺陷、噪声更少、并给出维护者可以核对的证据?代价是多少?

问题问的是
RQ1,检出规划出的专家组是否比使用相同模型和 skill 的单个 agent 找到更多已知缺陷、更多类别的问题?
RQ2,噪声在每种验证条件下,报告的发现里有多大比例是成立的?
RQ3,可验证性与代价执行能复现并修复多少发现,漏掉多少真实缺陷,代价是多少?

RQ2 不预设方向。如果只读验证下的发现大多已经成立,执行的价值就体现在 RQ3。

数据集 ​

一个被试是一个缺陷已知的改动,来自公开的测试集。只有 SWE-bench 的测试能运行,所以 RQ3 只靠它回答。不对任何输出做人工标注。

数据集被试已知缺陷回答
SWE-bench Verified,回退版七个 Python 项目里的约 30 个任务任务本身,由它自己的测试判定RQ1、RQ2、RQ3
Code Review Bench,离线50 个 pull request173 条人工审查者确认的评论RQ1、RQ2
ReviewBench219 个 pull request 中的 50 个,按语言从开发未用过的 194 个里抽取基准认可的 golden 发现RQ1、RQ2
  • SWE-bench 被试把参考修复放进基准,再在改动里把它去掉。它用任务自带的 Docker 镜像构建,镜像名是中性的,issue 文本不提供,测试在任务的容器里无网络运行。这七个项目是 subjects.py 有测试运行器的那些。
  • ReviewBench 的 25 个测试 pull request 是 eyeful 开发时用的,永不抽取。50 个名额按各语言在其余 194 个里的占比分配,再按哈希挑选,所以每次抽到的都一样。
  • 数据集放在 .eval/ 下,被 git 忽略。被试的描述指明了缺陷,它和仓库分开存放,每次审查都在只能读取该仓库的沙箱里运行。agent 读了仓库之外内容的运行会被排除并计数。

配置与条件 ​

配置决定谁来找问题,条件决定发现怎样被验证。

配置运行方式谁来审查
paneleyeful review规划器给改动分组,Go 挑选专家
singleeyeful review generalist一个拥有全部 skill 的 agent(见名册)
fixedeyeful review correctness security两个指定的专家,没有规划器,用于消融
条件报告哪些
none全部发现
read-only裁判没有否定的发现
execution已复现的发现,以及没有复现、裁判也没有否定的发现

三种条件验证的是同一份发现存档,所以唯一的差别就是验证。计数单位是评论:合并成一个问题的发现只算一次。没有能运行的测试时,execution 等同于 read-only,所以在 Code Review Bench 和 ReviewBench 上只比较 read-only 和 none。

实验步骤 ​

采用被试内设计。每个被试都由专家组和单 agent 各审查三次。execution 先运行,其他条件复用它的发现。fixed 配置只在 SWE-bench 和 Code Review Bench 上运行一次,与专家组的第一次运行比较。合计约 860 次审查。失败的审查最多重试三次。

所有 agent 和裁判都用 DeepSeek V4.1 Flash,基准的官方裁判也一样,所以结果是内部比较,不是排行榜分数。提示词、预算和本方案在主实验开始前固定。

指标与分析 ​

一条发现是否成立,由数据集自己的评分器决定:

数据集已知缺陷算作找到的条件评分脚本
SWE-bench官方 harness 用修复 agent 为某条报告的发现写的修复解决了该任务:FAIL_TO_PASS 和 PASS_TO_PASS 测试都通过resolve.py
Code Review Bench基准的裁判在默认的 Core 配置下判定某条发现就是该 golden 评论match.py
ReviewBench基准的裁判把某条发现匹配到该 golden 发现;它的分类器还会认可没有匹配上但成立的发现reviewbench.py
问题指标分析方法
RQ1召回率:一个已知缺陷在某配置的三次运行中有两次找到才算。找到的类别数,用各基准自己的标签McNemar 精确检验
RQ2精确率:报告的发现中解决了 SWE-bench 任务或匹配到 Code Review Bench golden 评论的比例;ReviewBench 用其 augmented precision按被试的配对 bootstrap
RQ3可验证率:被执行的发现中,复现通过全部六道关卡的比例。验证损失:解决了 SWE-bench 任务、执行却没有确认的发现所占比例。token、费用、秒数按被试的 bootstrap

专家组还会与单 agent 三次运行的并集比较,后者的花费大约等于一次专家组运行。每个估计都附带 95% 区间,由对整个被试做 10,000 次重抽样得到。

消融 ​

去掉后测量结果没有任何变化的部分,会从 eyeful 中移除。

去掉的部分运行方式预期效果
规划器fixed 配置,与专家组的第一次运行比较混合改动上的召回率下降,或者没有变化
oracle 分级对存档的复现重新打分,允许每一条都阻断阻断的发现更多,它们的精确率下降

效度威胁 ​

  • LLM 裁判可能偏宽松。
  • golden 集不完整,所以精确率是下界。
  • 同一个模型既是审查者,又是裁判和评分者。
  • SWE-bench 的项目早于模型的知识截止时间,模型可能知道这个 issue;而在回退版被试上,被去掉的代码就在 diff 里。
  • RQ3 只靠约 30 个 Python 被试。

工具 ​

eval/ 里的脚本只用 Python 标准库。resolve.py 用 uv 运行 SWE-bench 的 harness,match.py 和 ReviewBench 的裁判在各基准自己的检出目录里运行。mise run test 会运行这些脚本的测试。

脚本作用
subjects.py从 SWE-bench 的行或 Code Review Bench 的 golden 评论构建被试
reviewbench.py构建 ReviewBench 样本,把每次审查报告的评论交给基准的裁判,再读回分数
run.py用 eyeful 审查每个被试:每种配置先找问题,再由各个条件验证
confine.py在 macOS 沙箱里启动 pi,只允许读取被审查的仓库,用户的其他内容一概不能读
audit.py列出审查者的 agent 在仓库之外打开过什么
resolve.py把每个修复交给 SWE-bench 的 harness 运行,并给 SWE-bench 的审查打分
match.py在审查上运行 Code Review Bench 的裁判,并按 Core 配置打分
analyze.py根据审查和分数计算各项指标,一次一个数据集
revmux.py用 revmux 审查每个被试,这是可选的扩展,在 Code Review Bench 上打分