Skip to main content
“讲解是否适合小学生”“回答有没有编造事实”这类问题,正则写不出来,要交给裁判模型 Judge 打分。 Judge 本身也会出错:API Key 不对、端点写错、模型名拼错。这些问题如果等到 200 条评估跑完才发现,前面的 Judge 分数全都拿不到。所以先配好,再用一条最小评估跑一次真实判分,确认能拿到分数再大批使用。

配置 Judge 用哪个服务

在 niceeval.config.ts 里用具名 Provider 写明服务、模型和端点。下面用 OpenAI 兼容网关举例:
niceeval.config.ts
apiKeyEnv 只写变量名。Key 本身放进环境变量,或放进项目的 .env:

写一条最小评估

写一条只有一个 Judge 断言的评估,用来确认配置能拿到分数:
evals/judge-smoke.eval.ts
turn.closeQA(question) 把这个 Turn 的完整对话交给 Judge,让它回答你写的问题并给出 0 到 1 的分数。.gate(0.8) 表示分数低于 0.8 时这条评估不通过。 材料是空的时,这条断言直接得 0 分,不调用 Judge。材料不全、无法判断时,结果是 unavailable,不会被算成 0 分。 只想让 Judge 看特定的消息或工具调用时,给 closeQA 传入对应的 Match;应用自己的业务材料用自定义的 MaterialMatch。写法见 NiceEval Taste。

附加图片材料

只有判据确实需要看图时才附图。沿用同一个 defineJudge 和 t.judge,不用增加第二个 Judge 或评分门槛。 先在现有聊天 Provider 的配置里设置 supportsImages: true,并把 model 换成同时支持图片和工具调用的模型。TypesafeProvider 不支持图片。 下面的评估读取应用已经保存的 screenshot.png,不会为了评估重新截图:
图片必须是 PNG 或 JPEG,每张最多 4 MiB。超过大小或文件头无效时,NiceEval 在发送前就拒绝。不要传路径、URL 或普通 base64 字符串来代替图片。 跑完后,用 query 的 attempt.assertion.detail 查看这条断言,结果里有图片的 imageId 和摘要。要取回原图,用 attempt.assertion.image,传入同一个 Attempt 的 entryId 和 imageId,分段读取:offset 是字节偏移,limit 最多 256 KiB。它读的是保存下来的图片,不会重新读文件或调用模型。

运行一次,确认拿到分数

确保现有 Experiment 的 evals 包含 judge-smoke,再运行:
NiceEval 加载配置时不会访问 Judge 端点,只有真正执行 Judge 断言时才发请求。所以配置写错了,要跑一次才会暴露。 跑完后,从终端 NEXT 面板复制 Run ID,打开这次运行:
复制 judge-smoke 那个 Attempt 的 locator,查看断言结果:
配置正确时,这条断言会显示分数和是否达到阈值。也可以用 pnpm exec niceeval view --run <run-id> 在浏览器里看。需要 Judge 给出的理由和实际发给它的材料时,用 query 的 attempt.assertion.detail,示例见查看运行结果。 没拿到分数时,按结果判断该查什么: 要比较不同的 Judge,让多个 Experiment 使用不同的模型字符串或具名 Provider,再用 labels 标明对比的维度。