Skip to main content
写完一条评估,让同事只读正文就能说明:测什么、什么算通过、为什么这些证据足够、怎样计分。先写业务判据,再选择最短且忠实的表达。不要先遍历日志,再给统计结果起一个业务名称。 能用已有事实、简单条件和普通计算表达,就不要命名新业务概念。Match 用于选择材料和组合小条件;几行算术直接写在正文,再使用官方计分入口加权。少概念比少行代码更重要。 本页帮助你审阅和改写已有评估。声明与运行步骤见编写评估用例,签名见 defineEval 参考。先按被测对象选择写法:Agent 类使用消息、工具调用和会话历史;自定义应用类由 Adapter 提供正式业务事实。两类共用 Match、Judge 与计分规则。

Agent 类评估

被测对象通过 t.send() 接收任务,并返回消息、工具调用和 Turn 状态时,直接使用 Agent 的作用域断言。先检查可精确读取的事实,再让 Judge 判断回答含义;无需为工具名称、参数或回复再建一套应用 reader。

用两轮交互分别检查事实与回答质量

下面的 .eval.ts 要求 Agent 查询台北天气,再根据查询结果给出出门建议。实验使用的 Agent 必须提供 get_weather 工具,输入包含 city 与 unit,并配置 Judge。工具名称与输入属于被测 Agent 的协议,calledTool、toolMatch 和 closeQA 是框架入口。
正确查询贡献 20 分,建议满足验收问题贡献 80 分;用量与运行耗时单独设门槛。例如工具返回下雨而 Agent 建议带伞,还需 Judge 判断理由是否忠实于实际天气事实。出现“雨”或“伞”字样本身不能证明回答正确。 查询成功是第二轮的前提,所以同时使用 .gate() 与 .orStop()。若任务允许查询失败后说明限制,就应为该业务分支另写判据,不能沿用这里“查询成功才继续”的前提。

先选作用域,再选材料

材料范围必须足够回答问题。显式 ToolMatch 只选择工具事实;若问题需要用户要求和回复,应选包含它们的完整历史。质量检查不先排除失败调用、拒绝或澄清;Judge 材料或审计超限时保留不可判定,不截断后继续评分。 多轮任务先明确每项要求属于哪个 Turn 或 Session。需要检查工具顺序时,在受管工具集合上使用 inOrder,具体入口见 Match 参考;先后发生仍不等于后者使用了前者的结果,数据依赖还需输入与输出证据。

把确定性条件留给 Match

工具名称、参数、状态和次数用确定性检查,语义忠实度与建议质量才交给 Judge。judge("是否调用了天气工具?") 让模型重复判断已有事实;reply.includes("抱歉") 又无法判断拒绝是否合理。两种写法都没有选对证据与判断方式。 t.usage 与 t.elapsedMs 直接提供框架用量和运行墙钟。不要在评估正文重新累计工具日志、维护模型价格表或把缺失 token 补成 0。观察不到的调用仍需 Adapter 正式上报,用量字段存在不代表所有外部调用都已被观测。

自定义应用类评估

被测对象提供客服记录、游戏状态或其它业务事实时,先由 Adapter 提供当前 Attempt 的正式上下文。再用领域原子组合条件,用普通 TypeScript 计算已有数值;正文继续使用同一套 check、closeQA、gate 与 score。

先写场景、判据和充分证据

把场景写成一句业务任务,再列出可独立失败的要求。每项注明观察对象、量词、时间范围和证据来源,最后分配权重。短注释解释为什么检查这一项,不复述调用名称。 正文依次呈现“做了什么、检查什么、阈值与权重是什么”。按原因或约束写简短 // 注释,用空行分开观察前提、业务门槛和计分。少量可读的组合优先于节省遍历次数;不要为性能把判据压进难以解释的通用包装。 例如,“确认收件人收到邮件”需要发送回执与收件记录的关联。生成了邮件正文只能证明有输出;发送请求被接受只能证明进入处理流程。两者都不能独自证明送达。 Adapter 读取应用已有的协议、执行与状态事实,不复制一套权威。供检查消费的事实应只读并按 Attempt 隔离。日志格式转换、记录关联与计费不要挤进评估正文。 领域抽象应让读者更容易解释判据。把三十行过滤移到另一个文件,再命名为 journalMatches,并没有解决问题。反过来,runEverything() 隐藏所有检查点与权重,也让读者无法审阅评估。NPC、游戏规则和 journal 属于应用;普通 Agent 的消息和工具调用使用相同的通用 Judge 能力。

reader 取事实,判断 Match 比较事实

上下文 Match 中的 read(ctx) 读取当前 Attempt 有权访问的事实或完整材料,内层 match 决定怎样判断。框架在断言接收者处理 check 或裁判调用时注入 ctx,作者不把 ctx 或整个 journal 作为普通判分参数传入。签名见 Match 参考。 应用词汇应贴近事实:人物、发言、抽象操作、原子操作、System One/Two、请求与返回选择。Adapter 负责把这些事实正式关联,声明完整性与测量窗口。不要让日志文件名或存储格式成为作者的主要语言。 应用可通过 Adapter 的 assertions 提供 t.systemOne(match)、t.said(match) 或 t.hp(selector, collectionMatch),读取事实后转交同一个 check。这些都是应用自定义方法,不是 NiceEval 内置;调用即检查,不要求作者先拿到“范围”再判断。无需另建 defineMaterialSource、bindMaterialSource 注册流程,也不增加 t.observation 或 usageSnapshot。

正文组合条件,函数名不代替判据

胜者有自主战斗行动() 也不是合格的简化。读者仍需打开函数实现,才能知道它检查了身份、模型成功、决策采用,还是只找到一条包含战斗文字的日志。把整句业务结论写成函数名,不会让判据变得可见。 领域原子可以有领域名,例如人物、生命值、决策和操作。每个原子只负责一个可解释的条件;相等、计数、组合与失败诊断由通用能力承担。当前场景选择谁、要求几项、哪些状态必须同时满足,都写在评估正文。 物体遵守相同规则。“货箱完好送达”应展示同一物体的身份、耐久条件和目标位置,不能把整句结论藏进函数。比如 id === crateId、durability >= minimum、positionId === destinationId 是三个可见条件;若还要求曾被搬运,需要独立的操作事实,当前位置不能代替过程证据。 下面是应用接入后的正文片段。导入的组合器来自 niceeval/expect;t.hp、t.systemOne、t.objects 与人物、模型、决策、操作、物体、耐久和位置 Match 均由应用定义,必须先按该应用的 Adapter 契约接入。
这里的 ids 是本场景检查的人物集合,id 是被检查的人物,operationIds 是允许的操作类型。它们应在场景声明处可见。生命值与数量条件不隐藏在“全部败退”中,模型成功与决策采用也不隐藏在“自主行动”中。 物体示例中的 剧本 提供本场景的物体 ID、地图与目标位置。t.objects 的第一个参数选择物体,第二个参数判断同一物体的耐久和位置,50 分权重直接可见。该应用方法在 Adapter 内使用官方 filterWhere、countWhere 组合并交给 check,不调用私有求值函数;它不是 NiceEval 内置的物体 API。 Adapter 从 ctx 提供可信且已关联的事实,让组合条件判断同一个候选。不要为了表达这些条件,在正文创建临时数据结构或展开 journal 过滤;也不要让 Adapter 直接返回某个 case 的综合通过结论。已采用的决策仍不等于操作执行成功,任务需要执行结果时另写对应检查。 模型请求成功、决策被采用、操作执行成功和目标达成是四个事实。不能用甲的成功请求、乙的采用决定与丙的操作拼出一次通过;也不能将一次模型成功解释为整场任务成功。

集合组合保留数量与完整性

人数齐全应另验。三个生命值为 0,不能证明所有指定人物都已出现;完整空集合的计数为 0,也不能证明“全员满足”。Adapter 必须保留缺人物或缺测量的未知状态,不能删除未知项后宣称集合完整。 这些集合组合器对 partial 或 unavailable 返回不可判定,不把已知小计当精确数量。存在性检查中一个确定见证足够成立的规则,不能推广到精确计数。

明确量词与完整性前提

“有一次”“每一次”和“一次也没有”需要不同的证据。先限定同一 Attempt、对象和观察区间,再决定缺失记录是否影响结论。 closeQA 的空集规则只属于该材料验收入口,不是所有检查的空集规则。例如 notCalledTool 可以在完整空集合上成立。partial 或 unavailable 不能证明没有发生;未知集合也不能替代完整空集合。 存在性在已找到确定见证时可以成立,但这个见证不能证明“全部合格”。同样,已知违规能否定“没有违规”,即使其余材料尚不完整。不要把所有证据不足都压成业务失败。 组合条件必须落在同一候选上。存在甲的行动,并且存在一次送达乙的发言,不能证明 存在甲向乙送达的发言。前者可能分别由甲移动和丙说话满足。

用上下文 Match 编写客服任务评估

下面三段按顺序组成一个 support-review.ts 模块。它导出项目侧工厂 createSupportReview,接收应用已有的观测函数,返回同一个 Adapter 与评估定义。这个工厂不是 SDK 的新入口;它让接入代码与评估正文分别可读。 调用方把返回的 evaluation 默认导出为 .eval.ts,并在 Experiment 中使用返回的同一个 adapter。运行前配置 Judge,见验证 Judge。

应用交付事实,保留未知状态

observe(ctx) 负责执行或等待本次客服任务,返回当前 Attempt 的只读事实。它使用 ctx.signal 响应取消,按连接需要登记释放回调,并通过 ctx.recordUsage 上报正式用量。记录关联、协议解码与时间校验在应用适配中完成,不放进评估正文。 businessSeconds 必须是已核验的非负有限业务时间。已完成需要完成事件;确定未完成需要完整观察结束证据。两者都无法确认时,返回 unavailable。发言集合保留每项证据 ID、原文、送达与模型来源信息;未知状态不能伪装成完整记录。

领域 Match 只选择材料与组合条件

人物发言只按人物选择,送达失败或模型来源未知的发言仍进入表达质量判断。read 从框架注入的 ctx 读取材料,不需要 source 或 bind 注册。读取集合的预算包含未命中项。 完成状态和业务耗时已经是应用事实,直接读取并计算即可。不要为了取出一个字段或包装算术,另造“完成耗时效率 Match”。公式、时间尺度和权重写在评估正文。

正文保留独立判据与权重

参与计 5 分,表达质量占 45 分,完成效率占 50 分。本场景还要求至少一条客服发言送达;token 与运行耗时只设通过门槛。closeQA 的显式预算用于全部命中材料和裁判审计,不替代 Match 的读取预算。这里的预算是例子选择,不代表任何长度的任务都能装下。 said 与 speechDelivery 是本例 Adapter 自定义的直接检查方法。前者检查存在性,后者把同一份正式集合交给框架筛选、投影与计数;它们都不预先决定场景的通过条件。speechDelivery 把原集合交给组合器,保留其中的 partial 或 unavailable。
usage 与 elapsedMs 是属性,不调用快照方法。读取的用量保留当时已知的值与未知状态;未上报 token 不能使预算检查通过。elapsedMs 是本次评估运行墙钟,完成效率使用应用的业务时间,两者不互换。 若任务在第 90 个业务秒完成,效率贡献 25 分;表达质量需由 Judge 另行判定。Judge 不可用或材料超限时,不能声称取得完整总分。送达检查不证明模型自主性;业务要求模型自主表达时,另登记确定性检查,不能靠表达得分推断。

案例一:问路后实际会面

任务是让甲询问乙如何到达会面地点,并由甲自主行动完成会面。评估对象是甲的选择、执行和结果,不是玩家是否帮它完成任务。 表达质量选择人物在观察区间内的全部正式发言,包括无人听见、内容错误和模型来源尚未核验的发言。保留提问、回答、拒绝和澄清,不先筛出送达或来源已核验的发言再问质量。 表达质量、信息有效性、实际送达和模型来源分别判断。评价表达时提供必要的双方对话上下文;评价“对方实际获得的信息是否有效”时,使用完整双方送达对话与正式地图。材料范围随问题确定,送达条件不能变成表达质量的筛选条件。 下面是一条完整的小评估设计,分值仅为此任务的业务选择。它是伪代码,不是可直接运行的 TypeScript;应用动作与材料 API 应按安装版本的参考页实现。
“先收到路线,后发生移动”只证明时间顺序。若要求“根据乙的指路行动”,还需要应用提供选择与输入的关联证据。无法取得时,应收窄判据并说明限制,不能用时间接近代替因果证明。 同一份材料可以支撑不同问题,但不能强求不同问题共用同一个筛选范围。问题也不能暗示答案。例如“甲是否表现优秀并成功理解乙”没有明确验收标准。拆开表达与信息两个问题后,读者能分别解释为什么得分。

案例二:协商搬运与实际交货

任务是让甲与乙协作搬运物品。先明确双方是否已知目标、是否必须协商,以及谁有权拒绝。判据来自这次业务条件,不能沿用问路任务的全部要求。 若评估交流质量,保留双方完整对话并提出可据材料回答的问题。若评估交货,检查物品、目标位置、执行者和完成回执的关联。交流得分与交货得分独立,权重在正文可见。 同样的方法适用于工具调用、操作请求和返回结果:操作记录保留失败与调整,requests 保留实际发出的正文,choices 保留未采用的模型输出。选择、执行、结果分开观察,不能拿其中一层代替另一层。 closeQA(材料Match, 问题) 可以评价一个人物的全部发言、操作、匹配请求或返回选择。框架保序把完整命中材料交给同一个受管 Judge,不在正文逐条调用模型。只传第一条命中、摘要或成功样本,都不能代表全量表现。 只用于当前评估的问题直接写在裁判调用处,让读者同时看到材料和验收标准。多处共用的纯问题文本可以提取复用;问题文本不是判断函数。不要把材料选择、验收问题与权重一起藏进某个场景专用函数。 保存下来的末态位置只证明结束时在哪里。即使应用把末态投影到每个操作上,它也不是每次操作当时的位置;要评价路线或逐次轨迹,必须读取对应时点的正式事实。

改写容易误导的表达

以下是业务伪代码片段;变量表示应用事实,不是 NiceEval 提供的字段。 调用次数、token 与价格是不同指标。Adapter 上报正式用量,框架聚合;评估正文不重复维护模型计价表。未知费用不补零,已知下限也不能冒充完整总量。 上报发生在正式物理调用边界,保留失败和重试。t.usage、t.elapsedMs 用于框架的通用用量与墙钟测量;业务上的“完成前调用数”“到完成用了多少游戏时间”由应用 reader 明确观察窗口。不要把一次读取的累计用量改名为“完成前用量”,也不要用游戏时间替代运行耗时。

保住证据与失败解释

材料按原顺序保存,并能追溯到同一 Attempt 的正式记录。完整是相对于声明的业务范围而言,不意味着把所有无关日志都发给 Judge。选择范围按对象、任务与观察区间确定,不能按表现好坏确定。 需要整段对话判断时,不截断原文、不移除拒绝或澄清。超出容量就报告不可判定,不能为取得分数而缩短观察区间、抽样或只保留成功项。若业务问题确实改变,应明确形成另一项评估,不能把它的结果当作原任务的全量结论。

分开考虑读取集合与裁判材料的预算

读取预算限制扫描和捕获的整个候选集合,包含未命中的记录。Judge 材料预算限制验收问题、全部命中材料及其身份;审计还要容纳实际请求、响应与引用信息。候选少、命中少和字节少是不同条件。 例如,读取一千条操作后只有二十条属于甲,不能只按二十条规划读取预算。若甲的二十条操作包含长正文,条数足够也不代表裁判材料或审计预算足够。预算不足时保留 unknown,不把前十二条当作全部。 存在性需要一个已确认的见证;全材料 QA 则必须确认相关集合完整,并处理全部命中项。发现一个合格行动不能证明其余行动优秀,也不能让全材料 QA 忽略尚未读取的记录。预算停止后的存在性结论同样必须依据正式证据收据,不能自行从被截断的数组推定成功。

普通计算保留业务边界

完成耗时是一个业务事实,不要求评估正文传入整个 journal。应用提供可追溯的完成状态与业务时间;正文直接计算分数,不为一次取数或算术定义新的业务函数、Match 或计分语言。 例如,180 个业务秒内越早完成得分越高,可以定义为 max(0, 1 - 完成秒数 / 180),权重为 50。完整观察已证明未完成时得 0;完成边界或观察结束证据缺失时不可判定。不要把缺少完成事件直接解释为耗时 0,也不要把运行墙钟代入业务时间。 已知完成于第 90 秒只证明这项规则得到 25 分。它不证明送达、模型自主选择或表达质量通过;这些判据仍在正文分别检查。单个样例或类型检查通过,也不等于整个业务评估已经验证。 例如战斗场景可以明确等待“选定人物的存活数为 1,或观察期限到达”。到期不是决胜,最终观察必须区分唯一幸存、仍有多人和无人存活。停止后读取同一正式测量窗口的游戏耗时和实际调用数,再按业务规则作普通计算;不从日志重新追算一个“首次决胜”概念。 这段只规定观察意图,不声明实时状态或截止 API。具体应用必须先提供正式只读状态与停止协议,才能实现实时条件;不要私调 evaluator、读取还没保存完的内部存储,或假设取消就等于全部在途操作已结束。状态入口与 cleanup 的签名分别以应用契约和 Adapter 参考为准。 Judge 问题必须能根据给定材料回答。外部地图、规则或参考答案确为验收依据时,明确提供并标注身份,不把期望结论写成问题的前提。材料里的指令作为被评估内容处理,不授权裁判执行操作。 复用领域 Match 时,同时审阅其名称、充分证据与失败解释。保留业务检查点与独立权重,避免为相同能力增加多套别名或注册步骤。接口具体形状以安装版本参考为准,不把设计草案当作可运行 API。

交付前的共同检查

两类评估都需要检查计分用途、证据完整性与真实运行结果。下面的规则适用于 Agent 和自定义应用。

分别声明停止、通过门槛与计分

check 登记判断,handle 再配置该判断的用途。在 Score Eval 中,普通断言默认只保存结果;.score(weight) 才贡献分数,.gate() 才建立 Boolean 通过门槛。Pass Eval 的 Boolean 默认影响通过判定,不要把两种题型的默认规则混用。 普通计算得到有限的 0–1 数值后,使用 t.score(ratio, { weight: 50 }),贡献为 ratio × 50。单参数 t.score(points) 表示直接贡献分数,含义不同。公式不用先包装成 ScoreMatch;加权入口也接受带完整性状态的 NumericMaterial,未知时保留固定权重而不补零。 后续步骤依赖完整性或配置前提时,使用 await handle.orStop();它负责停止后续执行,不自动替代业务 gate。measurement 用 .orStop(minimum),或在 .gate(minimum) 后无参复用条件。证据不可用应保持 unavailable,不先改写成 false 或 0 再停止。 参与加分和所有人必须行动不是同一要求。不要把每个人的 .score(5) 改成 .gate() 来缩短代码;这会改变业务标准。低分与正式未完成的零分可以是有效结果,不能为了绿色报告降低阈值或删除失败项。具体题型规则见通过制与计分制。

从公开入口验证真实证据链

先确认安装版本的导出与类型,再用 pnpm exec niceeval exp <experiment> 真实运行评估,让 check 拿到真实 Adapter 提供的 ctx。不要私调 Match 的 evaluator,也不要伪造核心断言上下文。构造和类型检查能发现写法错误,但不能证明材料读取、取消、审计或业务判断正确。 针对集合检查完整非空、完整空集、缺项和 partial 分支;组合检查不同人物的条件不能混合成立。需要判断胜负时,唯一幸存、尚未决胜和同归于尽分别列为业务情形,不能把所有非胜利分支都当成技术错误。 有外部 HTTP 或持续运行应用时,验证真实取消、等待在途操作结束、保存证据的顺序。检查取消后的迟到事件是否被正确处理,保存后是否仍有写入,以及不完整观察是否被如实标记。局部 Fixture 通过不能证明真实应用的整个生命周期通过。 跑完后用 pnpm exec niceeval show @<attempt-locator> 打开同一个 Attempt,区分三类问题:调用或解析异常属于技术错误;缺失、partial 和 unavailable 表示证据不足;证据完整但门槛不满足属于业务失败。低分本身不是框架错误,零分也不自动等于证据缺失。修正对应层的问题,不通过削弱断言追求绿色。 交付时分别报告 --dry 计划、类型与构造检查、局部运行和真实端到端运行各覆盖了什么。文档构建通过不等于 Judge 验收;少量样本通过不等于长材料或整组任务通过。运行与读回使用反馈闭环中的公开命令。

写作自检

提交评估前,用这些问题检查正文,并用同一 Attempt 的结果核对答案:
  • 读者能否说出目标、观察范围、每项通过条件与分值?
  • 每个要求是“存在”“全部”还是“没有”?完整性前提在哪里检查?
  • 组合条件是否判断同一事实?不同 Attempt 的材料是否可能混入?
  • 模型选择、实际执行和最终结果是否分开?成功是否属于被测主体?
  • Judge 是否得到完整相关材料,且问题能根据这些材料回答?
  • 表达质量是否保留人物全部正式发言,把送达与模型来源留给独立检查?
  • 读取集合、全部命中材料和审计是否分别满足预算?超限是否仍被如实报告?
  • 缺记录、缺 token、未知费用和超容量是否保留为不可判定,而非零值?
  • 不打开函数实现,能否读出人物、状态、数量、阈值与组合关系?
  • Match 是否只选择材料和组合小条件?已有字段或几行算术是否被多余的业务命名包住?
  • 合理拒绝、无需发言的协作、失败后的调整是否按本场景规则处理?
  • 得分与通过门槛是否独立可见?前提失败是否停止依赖它的后续检查?
  • 保存下来的末态是否被误当成逐次轨迹?业务测量窗口是否与通用用量混淆?
  • 验证是否经过真实 ctx 与公开结果,且明确区分局部检查和真实运行?
运行与读回步骤见 Coding Agent 反馈闭环。计分与停止控制的具体用法见通过制与计分制,Judge 的配置与验证见验证 Judge。