榜单越来越热闹,复现越来越难
过去两年,Agent 评测的榜单密度上升得很快。SWE-bench 及其变体、各类工具调用基准、多轮交互评测,几乎每个月都有新名字。但做工程的人会发现一个越来越明显的错位:榜单上分数涨得越快,自己动手复现就越难。
问题通常出在几个地方。同一个数据集,换一个编码 Agent 去跑,得分可能大幅波动——公开讨论中出现过从 72% 掉到 41% 这样的落差。在本地跑通的用例,塞进 Docker 就卡死,换到云端沙箱又报权限错误。还有一类更隐蔽的:某个开源 Agent 在榜上排名靠前,团队照着说明配了三天环境,最后发现对方用的是定制版沙箱加上打了补丁的运行时,再叠加一层私有提示缓存,而这些细节榜单里连个注脚都没有。
浙江大学 ZJU-REAL 团队开源的 ageval(全称 agenteval)就是冲着这三类问题去的。它的定位不是再提供一套跑分脚本,而是把评测本身做成一个可声明、可锁定、可回放、可共享的底座。
它拆的是哪三层
ageval 的核心主张是把评测拆成三层,并让它们彼此解耦。
环境层负责提供 Agent 运行所需要的资源与约束,例如容器、沙箱、文件系统、网络与权限。运行时层负责真正执行 Agent 的那段逻辑,也就是常说的 harness:怎么组织提示词、怎么解析工具调用、怎么处理多轮循环。评测逻辑层负责判定,包括任务如何切分、结果如何比对、分数如何计算。
传统做法里,这三层是揉在一起的。换一个 Agent,往往意味着同时改动环境配置、执行脚本和判定代码,改动量随项目规模线性增长。ageval 的做法是让三者通过声明式接口对接:环境以服务的形式暴露能力,Agent 以插件的形式声明自己需要什么能力、占用哪个槽位,评测逻辑则按任务描述驱动调度。
团队的说法是,检查通过后会生成一份调度拓扑,运行时基座严格按照拓扑关系分发调用,从而实现基座代码完全不变、环境与 Agent 自由替换。这句话的技术含义比听起来更重要:它意味着评测的变量被隔离了。当分数变化时,可以定位到是模型变了、harness 变了,还是环境变了。
插件长什么样:以接入 DeepSeek 官方 harness 为例
抽象说解耦容易,落到代码上才见真章。公开材料给出的例子是接入 DeepSeek 开源的 deepseek-harness(简称 dsh)。按照介绍,接入过程不需要改动 ageval 框架的任何源码,只需要提供一份插件声明,路径是 plugins/dsh/plugin.yaml。
plugin_id: dsh
slots:
exclusive:
- id: executor # 注册为 Agent 执行器
inject:
- service: environment # 声明依赖环境服务
capabilities: [exec, upload] # 要求环境提供命令执行与文件上传能力
这份声明的信息量不小。plugin_id 是插件标识;slots 里的 exclusive 表示该插件独占 executor 这个槽位,也就是由它来承担 Agent 执行器的角色;inject 声明它依赖 environment 服务;capabilities 则列出了它对环境的硬性要求——需要能执行命令、需要能上传文件。
换句话说,Agent 不再假定环境长什么样,而是把需求写成契约。环境方只要满足契约,就能被复用;环境方不满足,就会在调度阶段被检查出来,而不是跑到一半才报错。这正好对上前面提到的那类痛点:本地跑通、进 Docker 卡死、进沙箱报权限,本质上是能力契约没有被显式声明。
对使用者来说,调用 dsh 与运行普通 Agent 没有区别。原有的 dataset 保持不动,切换对应的配置文件即可执行:
# 1. 安装带 dsh 支持的 extras
uv tool install 'ageval-cli[dsh]'
# 2. dataset 保持不动,指定 dsh 配置开跑
ageval run --task --profiles profiles.dsh.yaml
ageval 目前已经开源,可以通过 pip 或 uv 安装 CLI,也可以从源码编译体验。这套「安装 extras 加切换 profile」的模式,实际上把「换 Agent」这件事降到了配置层面。
调试体验:把轨迹当成手术录像看
评测工具的价值有一半在调试体验上。ageval 提供了一个本地命令 ageval view,会启动一个轻量的 Web 轨迹查看器。它呈现的是层级结构:上层是 Job,下层是 Task,每一行都带毫秒级耗时。
这个设计对排查问题的帮助很直接。环境准备花了 382 毫秒,说明镜像拉取慢或者缓存没命中。run 循环卡在第三轮工具调用,就要去看是密钥失效还是返回的 JSON 不符合 schema。evaluate 阶段耗时突然涨了五倍,就要怀疑判定用的提示词被污染,或者模型响应变长。这些问题在没有轨迹视图时,只能靠翻日志猜。
把耗时拆到毫秒级、把结构拆到 Job 与 Task,本质上是在给评测过程做可观测性。这类能力过去属于生产系统的监控范畴,现在被前置到了评测环节——这是一个值得注意的转变:评测本身正在被当作一套需要运维的系统来对待。
中立思辨
需要辩证看待几件事。其一,可插拔架构能解决的是工程层面的可复现性,解决不了评测本身的效度问题。如果任务设计得不好、判定规则有漏洞,那么无论环境多么干净、轨迹多么清晰,跑出来的分数依然可能误导决策。工具负责让结果可信,题目负责让结果有用,这两件事不能互相替代。
其二,解耦带来的抽象成本是真实存在的。插件声明、能力契约、调度拓扑,这些都是额外的概念负担。对只想快速跑一次评测的个人开发者,这套结构的收益可能不如直接写脚本;它的价值在团队协作、跨环境对比和长期维护的场景里才充分显现。项目目前提供的 extras 数量有限,生态是否成规模,还要看后续有多少 harness 与环境方愿意按这套契约接入。
其三,跨 harness 对比这件事本身有天花板。同一数据集下不同 harness 的得分差异,既可能来自 harness 的实现质量,也可能来自提示词、工具描述、循环策略等大量工程细节,而这些细节即便被声明出来,也难以完全对齐。ageval 做的是把这些变量显式化、可配置化,让对比的边界清楚,而不是让差异消失。
其四,项目仍在早期,公开信息中关于长期维护节奏、社区治理方式、与既有评测平台的兼容策略都还不够清晰。目前官方及行业暂未披露更多细节,后续将持续跟进迭代动态。
给工程团队的三条落地建议
即便不打算立刻引入这套工具,它提出的问题也值得照搬到自己的评测流程里。
一是把评测环境写进版本控制。环境不是一个「大概配好了」的状态,而应该是一份可重建的声明。镜像版本、依赖版本、网络策略、文件系统权限,凡是影响结果的都要固化下来,否则昨天的分数今天复现不出来,讨论就没有意义。
二是让 Agent 的接入变成配置而不是代码。把「用哪个 harness」与「评测怎么做」分开,是降低评测维护成本最有效的一步。很多团队的评测脚本之所以越写越乱,就是因为每次换 Agent 都要动判定逻辑。
三是保留完整轨迹,并且允许回放。只存一个最终分数,等于放弃了事后归因的能力。当分数出现异常波动时,能不能回放那一次执行、看到每一步的工具调用与返回值,决定了排查是十分钟还是一整天。
评测这件事的价值,从来不在于榜单上多一个数字,而在于当有人说「我的方案更好」时,能不能拿出别人愿意照着跑一遍的材料。