*.eval.ts 文件导出,通过 defineEval 声明。
它写起来像单元测试,但被测对象的输出不确定。同一条评估用例会按 Experiment 的 attempts 跑多次,每次是一个 Attempt,汇总起来读通过率或分数。
评估用例的组成
评估用例本身不声明用哪个 Agent,同一条评估用例可以在不同 Experiment 下跑不同 Agent。选哪个 Agent 是 Experiment 的字段,不由 CLI 临时覆盖。
不要手写
id 或 name。NiceEval 从文件路径推导 ID。路径即身份
evals/weather/brooklyn.eval.ts 的 ID 是 weather/brooklyn。Experiment 名之后的位置参数按 ID 前缀过滤:
terminal-swe-bench 也会命中 terminal-swe-bench-astropy-1,不要求后一个字符是 /。
生命周期
1
发现
Runner 加载
evals/ 下的 *.eval.ts 文件和 Fixture 目录。2
调度
结合并发、结果沿用、
attempts 和首过即停,生成这次要跑的 Attempt。3
调用被测对象
t.send() 调用 Experiment 选中的 Adapter,得到标准的 Turn。4
检查
NiceEval 登记每一项检查:值断言、Turn 和 Session 上的断言、Judge 打分,以及各项的分数贡献。
5
判定
通过制评估把检查结果汇总成最终判定;计分制评估累计分数。
6
保存与报告
终端和 Reporter 输出结果;Run 和已发布的 Attempt 写入
.niceeval/record.sqlite。四种判定
通过制评估的每个 Attempt 只会得到四种判定之一:passed
所有必须满足的 Boolean 检查都满足,所有设了
.gate(minimum) 的测量值都达到最低分,并且没有执行错误。failed
至少一项必须满足的 Boolean 检查没满足,或者某个设了
.gate(minimum) 的测量值低于最低分。errored
执行异常、超时或评估代码写错了,这次运行得不出可信的结论。
skipped
评估用例主动跳过,通常通过
t.skip(reason)。0。报告默认显示得分,不把它算进通过率,但仍然保留判定。判定为 failed 的结果即使分数算完了,也不会进入成功排名。
.score(points) 里的 points 是这一项的权重,不是总分。报告不会把得分自动换算成百分比。一个 Experiment 同时包含两种题型时,报告分别显示通过率和得分。
判定与测量值
通过制里,Boolean 检查默认影响判定;计分制里,Boolean 检查默认只记录结果。连续测量值和 Judge 打分是 0 到 1 之间的数,两种题型都用.gate(minimum) 设最低分,低于最低分判 failed。计分制里门槛没达到时,已经得到的分数仍然保留。完整规则见 Assertion 与 Match。
*.eval.ts 约定
只有以 .eval.ts 结尾的文件会被发现。目录只形成 ID 前缀:
数组导出与数据驱动测试(dataset fan-out)
一个文件也可以默认导出defineEval(...) 数组,用同一套逻辑生成多条评估用例:
sql/0000、sql/0001。详见 数据驱动测试。