Skip to main content
让 Agent 把一个开源项目装起来并跑通健康检查,一共五步。它做完了三步,卡在第四步。 只看通过与否,这次就是“失败”,和一步都没做没有区别。可你想知道的是 Agent 离完成还差多远,改了 prompt 之后是从三步进步到了四步,还是原地不动。 NiceEval 因此有两种评估用例:
  • defineEval 是通过制。回答“这次做到了没有”,结果读通过率。适合必须全部满足才有意义的任务,例如测试必须通过、不能泄露密钥。
  • defineScoreEval 是计分制。回答“完成了多少”,结果读累计分数。适合有部分进展的任务,例如分步骤的安装、多项质量要求。
一个 Experiment 或评估组里只能有一种。niceeval check、--dry 和正常运行都会在启动 Agent 或 Sandbox 之前拒绝混用;两种读数都需要时,拆成两个 Experiment。

必须做到的事用 defineEval

Boolean matched 进入 Verdict;mismatched 使最终 Verdict 为 failed,但不会阻止其它 Assertion 继续登记和结算。需要让后续代码依赖这条结果时,await handle.orStop()。

连续质量线

similarity(...) 这类 Match 产生 [0, 1] 的 measurement。它计算字符级 Levenshtein 编辑相似度,不判断语义。通过制评估在 handle 上用 .gate(minimum) 建立质量门:
低于 Match 上形成的阈值时,这项要求失败。只想留下不影响判定的说明时用 t.diagnostic(...),不要登记无消费的测量值。

走完三步也要记三分

分步骤任务适合 defineScoreEval。Assertion 默认只保存 evaluation,不计分;.score(n) 才让该项贡献分数。Boolean matched 贡献 n,mismatched 贡献 0;measurement m 贡献 m * n。
t.score(n) 直接登记 contribution,n 必须 finite 且不小于零,返回的 handle 只能配置 key 与 label。Judge 或其他 measurement 可以在同一 handle 上调用 .gate(minimum) 和 .score(n);两者任意先后,evaluator 都只求值一次。 test 正常返回时,NiceEval 自动算出最终分数。没有计分项也是有效结果,得到正式 score: 0;这表示评估成功形成了零分,不是执行失败或证据不足。

两种题型的结果

计分制的 complete score 可以是 0 分。passed + complete 0 说明评估成功形成了零分,不等于执行失败或证据不足;failed + complete 则必须继续显示失败,不能因数值完整而改写成成功。

Judge 也是 Measurement

defineJudge 声明一个受管 Judge Match。作者把完成判断所需的值组成带语义字段的材料。 裁判可以直接传给 t.judge,无需在评估上登记。模型默认使用项目的 judgeRuntime;单题只换模型时设置 judge: "judge-model"。
可以独立失败、计权或显示原因的要求应各登记一条 Judge。计分制可以在同一条 Judge 上组合 .gate(minimum) 与 .score(points); measurement 乘 points 得到贡献值,gate 决定 Verdict。同一条 Judge 只执行一次。

代码任务用真实命令验收

判分标准本身是一份文件时,用 loadText 读取隐藏测试、参考实现或跑测脚本。文件改动会触发对应评估重跑,详见隐藏测试判分。

实用建议

  • 把每个必须成立的条件登记为 Boolean Assertion,让一次 Attempt 收集完整失败信息。
  • 把可以独立失败、独立计权或需要单独诊断的开放式标准拆成多个 Judge。
  • 只有不可分割的整体质量维度才使用一个 Judge 的 measurement 乘单项权重。
  • 后续步骤依赖某条结果时,await handle.orStop()。
  • 任务存在有意义的部分完成度时使用 defineScoreEval;test 正常返回时自动收尾。
  • 开放式语义用 Judge;可精确检查的文件、命令与结构化输出优先用确定性 Match。