octobench用25个2026年真实合并PR测试AI编程Agent,octomind(开源模型)胜过Claude Code Opus,避免了合成题目污染和品味打分陷阱。
没有合成谜题,也没有被污染的测试集:我们从 2026 年合并的真实 PR 中收集了 25 个任务,覆盖五种编程语言,并使用各项目自身未公开的测试进行评分。四个 Agent 均采用默认配置。octomind 搭配开放模型解决了 25 个任务中的 24 个,领先于使用 Opus 的 Claude Code;而同一个模型换到另一套 harness 后只解决了 19 个任务,成本却翻了一倍。下面是我们如何构建这套 benchmark,以及从中学到了什么。
我们想得到一个真正可信的数字:如果把日常维护者在一个普通星期二会遇到的任务交给 coding agent——真实的 bug、真实的功能需求、真实的代码库——它有多大概率能交付一个被项目自身测试套件接受的修复?
现有的公开 benchmark 都无法给出这个数字,于是我们构建了 octobench。这篇文章会讲述它是如何诞生的、过程中出了哪些问题,以及最终的排行榜说明了什么。
流行测试集反复暴露出两个问题。
污染。那些知名 benchmark 已经存在了很长时间,以至于前沿模型很可能在训练数据中见过对应的修复——有时甚至是逐个 commit 见过。有一次,我们发现某个模型竟然对一个它根本不该知道的 commit hash 执行 git show。无论这种测试衡量的是什么,反正不是解决问题的能力。
品味式评分。许多 benchmark 任务使用的测试,会断言实现者所做的任意选择,例如内部变量名,或错误消息的精确措辞。Agent 完全可能写出达到维护者水准的修复,却因为错误提示的表达与原作者不同而失败。这衡量的是模仿能力,而不是工程能力。
因此,我们的设计目标是:真实的任务、新鲜的任务、公平的评分。
每个任务都来自一个备受认可的开源项目中近期合并的真实 pull request:werkzeug、click、anyio、pydantic、twig、carbon、symfony、guzzle、commonmark、uuid、rayon、chrono、bytes、serde-json、fmt、yaml-cpp、catch2、spdlog、eslint、fastify、undici、pino、pino-pretty。
这份名单刻意兼顾了两个维度。首先是语言:一共五种——python、php、rust、c++、js——因为如果一个 Agent 很擅长 python,却在 CMake 构建中不知所措,那它就称不上通用 coding agent。其次是新鲜度:所有修复都在 2026 年合并,大部分晚于当前模型的训练数据截止日期,其中一些甚至是在采集前几天才合并的。有一个案例是 chrono 的反向日期迭代器,它在我们选中它的当天上午刚刚合并。随着训练数据截止日期向前推进,仍能重新采集任务的 benchmark,才不会过时。
任务类型从只需一行代码的崩溃修复,到涉及多个文件的功能开发都有。每个案例都会重建修复尚未存在时的现场:
setup.sh 会将仓库 checkout 到修复前的 commit,并采用只有单个 commit 的 shallow clone,确保答案不会藏在 git object store 里;它还会准备工具链,并删除 git remote,防止 Agent 直接从上游获取修复。
Agent 会收到一份任务 prompt,然后像受雇的外部开发者一样在仓库中工作。
Agent 完成后会运行 validate.sh:它会获取已合并修复中的测试文件——这些测试是 Agent 从未见过的——覆盖 Agent 可能对测试套件做出的任何修改,然后准确运行这些测试。最终通过还是失败,由项目自身维护者编写的项目原生测试决定。
另外还会由一个 LLM judge 根据 diff 和日志对工作质量进行评分。
任何案例在进入 benchmark 之前,都必须证明自己满足 fail-to-pass:未公开测试必须在修复前的代码上失败,并在应用真实的已合并修复后通过。无法证明,就不能入选。
对于其中 20 个任务,我们让一个专用 Agent(octomind 的 developer:reverse-spec)分析每个已合并的 commit,反向还原出一个有可能促成该修改的需求,然后再人工筛选。筛选只遵循一条规则——可推导性规则:未公开测试所断言的一切,都必须能够从 prompt 中推导出来。bug 修复只会收到简短、非正式的 prompt,因为任何正确的修复都能通过测试。对于那些测试会固定公共 API 名称或精确输出格式的功能,则会提供规格严谨的版本,因为真实需求方本来就会明确说明 wire format。
另外 5 个任务——每种语言各一个——直接逐字采用真实的 GitHub issue 文本,只删去会泄露修复方案的部分(有位作者非常贴心地写道:“我已经准备好了一个执行 X 的 PR”)。这测试的是另一种能力:把用户口吻的 bug 报告——有时只有截图,没有预期输出——转化为达到维护者水准的修复。
下面是几个我们很喜欢的案例,按它们分别考察的能力列出:
anyio 的 cancel-scope 自旋——修复只有 4 行,却要求你理解为什么 asyncio event loop 会占满一个 CPU 核心。diff 很小,异步推理却很深。
guzzle 的 cookie 前缀——27 行代码里藏着三个彼此独立的陷阱;最朴素的 startsWith("__Secure-") && !secure 修复会在一半测试中失败。
commonmark 的 fenced-code tab——有用户通过一张截图报告:“代码块有时会丢失第一个字符。”未公开 fixture 包含 issue 从未提到的情况:只有真正修复根因才能通过,针对症状打补丁则会失败。
pino-pretty 的控制字符——其中有两个未公开测试,纯粹是为了惩罚范围过大的清理操作:它们在有 bug 的代码上能够通过,而任何不尊重 trust boundary 的修复都会让它们失败。
在最终运行之前,三位评审逐一对照每个 prompt,检查所有未公开断言。这次审计确实发现了问题——但问题出在我们的 benchmark,而不是 Agent。某个案例的测试断言了错误消息的精确文案,但 issue 从未引用过这段话。两个前沿 Agent 都给出了完美修复——其中一个甚至选用了与维护者相同的错误码——却双双因为措辞不一致而失败。我们替换掉了这个案例。另一个案例的隐藏测试与它自己的 issue 文本互相矛盾。第三个案例把未公开测试放在了源文件中,因此,如果整体恢复标准测试,就会悄无声息地覆盖掉正确修复。
这里的元教训是:benchmark 基础设施出错时,看起来与模型失败一模一样。我们追查的每个异常——例如通过的运行却被 judge 打了 0 分,或者某个“已解决”的案例却有空 diff——背后都应该存在真正的根因,而其中大约一半是我们自己的问题。
我们测试了四个 Agent,全部使用各自默认、开箱即用的单 Agent 调用方式。没有调优,也没有自定义 prompt。
这张表说明了四件事:
harness 与模型同样重要。octomind 和 opencode 在同一个 endpoint、以相同价格运行了同一个模型,这是一次纯粹的 harness A/B 测试。octomind 解决了 24 个任务,opencode 解决了 19 个,而前者的成本只有后者的一半。差异来自上下文管理(某个任务中,opencode 输入了 3000 万 token,而 octomind 只需要 800 万)和监督机制:opencode 丢掉的恰好都是那些需要深挖根因、包含多重陷阱的案例。在这些案例中,没有监督的 Agent 会过早宣布胜利。
harness 与模型同样重要。octomind 和 opencode 在同一个 endpoint、以相同价格运行了同一个模型,这是一次纯粹的 harness A/B 测试。octomind 解决了 24 个任务,opencode 解决了 19 个,而前者的成本只有后者的一半。差异来自上下文管理(某个任务中,opencode 输入了 3000 万 token,而 octomind 只需要 800 万)和监督机制:opencode 丢掉的恰好都是那些需要深挖根因、包含多重陷阱的案例。在这些案例中,没有监督的 Agent 会过早宣布胜利。
一个开放模型在每个 token 都按全价付费的情况下击败了 Opus。glm-5.2 通过 Ollama cloud 运行,而后者没有 prompt caching——Agent 的每一轮都要按标价重新为完整上下文付费。与此同时,Opus 约 97% 的上下文重复读取都按十分之一的缓存费率计费。glm 的金额是它最糟糕情况下的成本,但它在解决任务数量、成本和耗时方面仍然领先。在任何支持缓存的 endpoint 上,成本差距都会变成一道鸿沟。
一个开放模型在每个 token 都按全价付费的情况下击败了 Opus。glm-5.2 通过 Ollama cloud 运行,而后者没有 prompt caching——Agent 的每一轮都要按标价重新为完整上下文付费。与此同时,Opus 约 97% 的上下文重复读取都按十分之一的缓存费率计费。glm 的金额是它最糟糕情况下的成本,但它在解决任务数量、成本和耗时方面仍然领先。在任何支持缓存的 endpoint 上,成本差距都会变成一道鸿沟。
速度需要以周全性为代价。Codex 的表现非常出色——每个案例只需 2~4 分钟,中位成本为 0.59 美元——但它失败的四个案例,无一例外都在惩罚同一种疏忽:没有多检查一个调用方、一个影响面或一个陷阱。
速度需要以周全性为代价。Codex 的表现非常出色——每个案例只需 2~4 分钟,中位成本为 0.59 美元——但它失败的四个案例,无一例外都在惩罚同一种疏忽:没有多检查一个调用方、一个影响面或一个陷阱。
没有任何任务是不可能完成的。每个案例都至少被一个 Agent 解决,而且失败类型非常清晰:trust boundary 案例难住了 opus、codex 和 opencode;需要深挖根因的 parser 案例,除了 octomind 外全部失败;而两个 glm harness 以完全相同方式失败的那个案例,暴露的确实是模型盲点,而不是 harness 造成的假象。
没有任何任务是不可能完成的。每个案例都至少被一个 Agent 解决,而且失败类型非常清晰:trust boundary 案例难住了 opus、codex 和 opencode;需要深挖根因的 parser 案例,除了 octomind 外全部失败;而两个 glm harness 以完全相同方式失败的那个案例,暴露的确实是模型盲点,而不是 harness 造成的假象。
“上下文管理”中的很大一部分,其实只是 Agent 如何查找代码。默认配置下的 claude code、codex 和 opencode 都以相同方式浏览仓库:grep、读取文件、再次 grep、继续读取——而每次重复读取产生的上下文,在之后的每一轮中都会再次向模型计费。octomind 的 developer:general 默认自带 octocode:它通过结构化搜索直接找到精确的 symbol、signature 或代码模式,让 Agent 能直接跳转到真正相关的三个函数,而不是逐页浏览无关文件。启用 semantic indexing 后,它还可以按语义搜索代码库——使用“cookie validation 在哪里处理”这样的查询,而不是 grep pattern。少读错误的文件,就意味着少为 token 重复付费;这种差异不断累积,最终形成 A/B 测试中 800 万与 3000 万输入 token 的巨大差距。
另一部分优势来自监督机制。在 dry run 期间,有个 Agent 曾这样“完成”任务:它宣布“现在让我制定计划并实现修复”,然后就停了下来,留下一个空 diff。在非交互式运行中,只有文本输出的一轮意味着 session 已经结束,因此 octomind 加入了一个确定性 guard:如果某一轮在没有采取任何行动的情况下结束,而 Agent 自己报告的状态仍是进行中,就会让它回去继续工作。在最终运行中,这种失败模式消失了——而 opencode 丢掉的那些案例,恰恰都是没有任何机制质疑 Agent 过早宣布胜利的情况。
所有内容都已公开并固定版本:包括此次运行对应精确 commit 下的完整逐案例表格和复现指南、运行 artifact 中每个案例的 Agent trace 与 judge verdict,以及案例采集 pipeline——reverse-spec Agent、可推导性规则和 fail-to-pass verifier。这些内容都已记录下来,让任务集能够随着训练数据截止日期向前推进而持续扩充。
我们最看重的结果不是排名,而是这次 A/B 测试:同一个模型、同一个 endpoint,以一半成本多解决了五个任务。如今,模型质量只是基本门槛——真正能带来杠杆效应的是 harness。这正是 octomind 建立之初所依据的核心观点,而现在,我们终于有了能够证明它的数字。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。