Agentic Eval · Release Engineering

Barena: Agent Eval 的终点, 不是排行榜, 而是发布 CI

每一次 Agent 变更都会产生一项证明义务:它是否真的更好、稳定、无回归,而且证据足够。Barena 想做的不是另一个评分器,而是把这项证明义务变成可执行的发布协议。

我做 Barena 时,最先困住我的并不是“怎么给 Agent 打分”,而是一个更实际的问题:我刚改了 Prompt、换了模型、加了 Skill,这一版到底敢不敢发?

一个 Agent 能完成任务,不等于这次改动值得发布。它可能本来就会;也可能平均表现更好,却把一个关键旧能力做坏;还可能只在这一次碰巧成功。于是评测的对象不应该只是“一个 Agent”,还应该是从 baseline 到 candidate 的这次变化。

几行 diff,为什么单元测试兜不住

给 Skill 增加一段说明、替换模型、开放一个新工具,代码 diff 可能只有几行,行为变化却会穿过整个系统。模型会不会选择这个 Skill,工具是否写进正确目录,环境里有没有残留状态,外部服务失败后 Agent 会不会换一条路径——这些问题无法只从实现中推出答案。

传统测试仍然重要,它擅长证明确定性组件满足局部合同。Agent E2E 要补的是另一块:在接近真实的任务压力和运行环境下,这个由多个非确定性部件组成的系统,能不能稳定地产生可验证结果。

Barena 架构:一次 Agent 变更进入成对实验,在隔离环境中执行;OTel Trace 与 Reviewer 形成行为证据,Artifact Verifier 与边界观察形成结果证据,最后进入 cleared、held、rejected 发布门。
图 1:Barena 先验证实验是否成立,再讨论提升。行为证据与结果证据缺少任何一路,结论都会降级,而不是由另一路代填。

Benchmark、Eval 和 Release CI 问的是三件事

机制 核心问题 典型输出
Benchmark 谁在一组公共任务上表现更好? 分数、排名、能力比较
Eval 一个 Agent 在目标任务上表现怎样? 通过率、错误类型、轨迹
Release CI 这次具体变更是否有效、稳定、无回归,可以发布吗? clearedheldrejected

排行榜适合回答模型或 Agent 的相对能力,却很难直接替团队做发布决策。一个 Skill 在公共任务上拿到高分,不代表它对当前 Role 有增益;一个新模型平均分更高,也可能让最重要的回归用例从稳定通过变成偶发失败。

所以 Barena 不是在找“最聪明的 Agent”。它评估的是一次发布候选:在同一目标 Runtime、同一组 Case、同一套约束下,从 baseline 到 candidate 究竟发生了什么。

Release Eval 本质上是一个反事实问题

“Candidate 能不能完成任务”只是能力问题;“如果没有这次变更,同一个任务会怎样”才是发布问题。后一个问题天然包含反事实:只有观察相同条件下 baseline 与 candidate 的差异,结果才有机会归因到这次变更。

Barena(
  target runtime,
  baseline configuration,
  candidate configuration,
  E2E case pack,
  replay policy
)
  → effectiveness
  → stability
  → regressions
  → evidence
  → cleared | held | rejected

对 Skill 来说,Barena 在同一个 Agent 上比较“不加载”和“加载候选 Skill”;对于其他变化,也需要尽量固定任务、Runtime、模型、工具和验证器,只改变要评估的候选项。它不是严格的实验室因果,但至少把问题缩小到:除了这次变更,还有什么不同?

一个高分本身没有因果含义

假设 Candidate 跑出了 100% 通过率,看起来很好。但如果 baseline 也是 100%,这次变更并没有证明任何效果。Barena 会把这种结果标成 no_effectheld,而不是因为候选拿到满分就允许发布。

反过来,如果总体通过率提高,却有关键 Case 从稳定通过变成偶发失败,平均分也不能替它开脱。Release CI 关心的不只是总体 lift,还要保护那些不能退化的具体能力。

same task + same runtime + fresh workspace
                 │
         ┌───────┴────────┐
         │                │
     baseline         candidate
         │                │
    attempts × N      attempts × N
         └───────┬────────┘
                 ↓
 verifier-backed lift + regressions + stability

Agent 说“完成了”,不能算完成

这是做 Agent Eval 最容易踩的坑。Agent 可以非常自信地说“文件已经生成”,Reviewer 也可能觉得它的回答不错,但磁盘上根本没有目标文件。只让另一个模型评价它,最后很容易变成两个模型互相认可。

Barena 把证据拆成三层:最终回答记录 Agent 的声明;Trace 解释它走了什么路径;Artifact Verifier 直接检查文件、JSON 结构、内容和其他可观察状态。发布结果以 Verifier 为准,Reviewer 主要帮助解释失败模式。

证据层 回答什么 不能单独证明什么
Agent final answer Agent 声称自己做了什么 真实产物已经存在
Trace / Reviewer 过程如何发生、哪里可疑 最终状态一定正确
Artifact Verifier 可观察结果是否满足断言 隐藏推理一定合理

结论不能超过证据的边界

在 Barena 里,Trace 是整条评测链的 evidence spine。每次尝试会保留任务输入、进程状态、工作区变化、Runtime 原生轨迹和 Verifier 结果。能通过 OpenTelemetry 导出的原生 Trace 统一走 OTLP;Barena 自己从进程和文件系统看到的 boundary evidence 则单独标记来源。

这个区别很重要。只有进程边界证据,就只能说明看到了输入、输出和副作用;没有 Runtime 原生 Trace,就不能声称知道内部工具序列;没有 Verifier,也不能把模型判断写成 Outcome Truth。评测系统不能为了让报告完整,补写自己没有观察到的事实。

User task
   ↓
fresh baseline / candidate attempts
   ↓
boundary evidence + OTel trace + artifacts
   ↓
Reviewer signal + deterministic Verifier
   ↓
validated evidence package
   ↓
paired release gate

可靠性不是附加指标,它本身就是能力

非确定性系统最危险的结果不是稳定失败,而是偶尔成功。只跑一次时,一个 flaky candidate 和稳定 candidate 都可能显示绿色;进入真实使用后,前者才暴露出用户需要反复重试。

Barena 因此把多次独立 attempt 纳入发布判断。有提升但 flaky 的候选仍然会被 held,因为用户无法消费“平均意义上的成功”,只能消费眼前这一次任务到底有没有完成。

Unknown 不是失败,而是必须保留的结果

Eval 系统最糟糕的失败方式,不是报错,而是在缺少运行条件或证据时给出一个看似完整的成功。Barena 因此把发布结论分成三态:

  • cleared:候选产生稳定、Verifier 支持的正向提升,没有测得回归。
  • held:结果不稳定、没有效果、证据不全,或当前不具备比较资格。
  • rejected:出现能力回归或不安全行为。

held 非常关键。缺少证据不等于失败,更不等于通过;它只表示当前没有足够资格做发布决定。把“未知”单独建模,CI 才不会用一个假精确的数字掩盖基础设施问题。

一个真实案例:144 次运行之后,能比较的只剩 36 对

只有框架和 fake fixture 还不够。我从 SkillsBench v1.1 的 8 个类别里各选了 3 个公开任务,用同一个 XiaoBaOS Agent 比较“不加载任务 Skill”和“加载任务 Skill”。每边独立运行 3 次,完整矩阵是 24 个任务 × 2 个 arm × 3 次 trial,共 144 次 rollout。

任务是否成功只看 SkillsBench 的确定性 Verifier,不采用 Agent 自述,也不拿 Reviewer 分数代替。真正让我在意的不是跑出了多少数字,而是这些数字里有多少具备比较资格。

Barena SkillsBench v1.1 方法验证海报:24 个任务、144 次运行、90 个通过证据准入的结果、36 个严格匹配 pair,candidate 相对 baseline 的观察差值为正 16.7 个百分点。
图 2:Barena × SkillsBench v1.1 方法验证。查看完整报告、数据口径与限制
Terminal rollouts 144 / 144

所有计划运行都到达终态,但终态不等于证据有效。

Verifier-admitted 90 / 144

只有能够证明 Verifier 实际执行的结果才进入证据池。

Strict matched pairs 36 pairs

同一任务、同一 trial、两边证据都有效,共覆盖 14 个任务。

Complete-task gate 2 / 7 / 0

9 个完整任务中:2 cleared、7 held、0 rejected。

Matched-pair direction 38.9% → 55.6%(+16.7 pp)

方向为正,但 exact McNemar p = 0.109;它是描述性结果,不足以证明总体显著更强。

144 次运行里只有 90 次通过证据准入;其中 72 次组成了 36 个严格匹配 pair,另外 18 次因为另一边缺少有效对应项,不能进入配对比较。剩下 54 次属于无效或没有评分的结果。

在 36 个匹配 pair 中,baseline 通过 14 次,candidate 通过 20 次;candidate-only pass 有 8 次,baseline-only pass 有 2 次。方向是正的,但 exact McNemar p = 0.109,再加上缺失可能不是随机发生,所以这次实验不能证明 candidate 在总体上显著更强

真数据反过来改变了评测规则

这 144 次运行最有价值的地方,是它逼框架暴露了原先容易偷懒的地方。实验结束后,我把几条规则写得更硬:

  • “进程结束”不等于“结果有效”,Verifier 是否真正执行必须有独立证据。
  • baseline 和 candidate 必须按 task 与 trial 严格配对,不能直接相减两个不同分母的总体通过率。
  • 证据不完整的任务保留在审计索引里,但不能参与效果结论。
  • 公开报告必须同时给出选择、准入规则、排除项和机器可读结果,不能只放一张漂亮图。

所以 Release Eval 的第一产物不是 score,而是 validity。只有 Runtime、输入、隔离和证据协议先成立,baseline / candidate 的差异才值得解释。

最后,它才落到三个产品动作上

到这里,Barena 的三个入口才变得自然:explore 用 UserCat 模拟真实用户,寻找还没有写进测试集的边界;replay 重放固定 Case,保护已经确认的能力;compare 聚合 baseline 与 candidate 的有效证据,给出发布判断。

Explore 发现的问题可以沉淀成下一轮 Replay Case;Replay 和 Explore 都通过 Runtime Adapter 执行真实 Agent,并保留 OTel Trace、Artifact 与 Verifier。它们不是三套互不相干的功能,而是同一个行为回归闭环里的三个动作。

Barena 当前仍然有明确边界

  • 当前深度适配的 Explore Runtime 是 XiaoBaOS;Claude Code、Codex 和 OpenClaw 的多轮 Explore Adapter 仍待完成。
  • 当前 compare 主要复用已经验证的 Skill baseline / candidate 引擎,最终的任意 RunSet 对比还在后续版本。
  • SkillsBench 实验早于现在的 OTLP Explore 路径,因此它验证的是配对准入、Verifier 和门禁方法,不是新 OTLP 模块的实验成绩。
  • 公开仓库保留结果、选择和可移植证据索引;原始 provider trajectory 没有全部公开。
  • 有限次 Replay 能暴露一部分 flakiness,但不能证明概率意义上的绝对稳定。

这些限制不需要藏起来。一个可信的 Agent Eval 系统不必声称自己看见一切,但必须准确区分:它看见了什么、没有看见什么,以及现有证据允许做出多强的结论。

Benchmark 告诉我们一个 Agent 大概处在什么位置;Release CI 要回答的是下一次改动能不能进入生产。Barena 想把这件事变成持续协议:用真实任务制造压力,用成对实验观察变化,用 Trace 解释过程,用 Verifier 检查结果,最后再决定这次变化值不值得信任。

View Barena on GitHub →