LifeOS Evals 评测最佳实践:断言优先的 LLM-as-Judge 设计、执行与统计严谨性指南
2026/9/14 18:14:18 网站建设 项目流程

LifeOS Evals 评测最佳实践:断言优先的 LLM-as-Judge 设计、执行与统计严谨性指南

【免费下载链接】LifeOS⛰️ The Life Operating System — an intent engineering platform that moves you from your current state to your ideal state, in life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS

本文系统讲解 LifeOS 仓库中 Evals 技能的最佳实践文档 所沉淀的 AI 评测方法论:从 LLM-as-Judge 的评分纪律,到评测用例(Use Case)的编写规范、评测运行的操作要点,再到结果解读与统计严谨性要求。读完后,你将掌握一套可落地的 Agent/Prompt 评测流程——包括 1-5 分制裁判设计、75% 通过阈值、确定性断言与模型评分 60/40 配比等关键参数,并能对照仓库源码理解每条实践在 Judge.ts 与 EvalRunner.ts 中的实际实现方式。

1. 背景:Evals 技能与断言优先(Assertion-First)框架

LifeOS 的 Evals 技能是一个"断言优先"的 AI 评测框架。按照 SKILL.md 的定义:一个评测(eval)给 AI 一个输入,然后对输出施加断言(assertions)来度量成功与否。一个用例(case)的最小结构是{id, prompt, assert: [...]},每条断言要么是确定性的(纯代码检查,快速、免费、可复现),要么是模型评分的(由一个 LLM 裁判打分)。用例会跑多次试验(trials),框架报告两个核心指标:

  • pass^k:k 次试验全部通过——对可靠性至关重要的 Agent 最诚实的指标;
  • pass@k:k 次试验中至少一次通过——适用于"一次成功就够"的场景。

最佳实践文档(BestPractices.md)正是围绕这套框架,给出五个维度的操作准则。它与 ScienceMapping.md 的关系是:Evals 本质上是把科学方法(目标 → 观察 → 假设 → 实验 → 测量 → 分析 → 迭代)应用到 prompt 工程上,而最佳实践就是这套方法在工程侧的具体执行清单。

1.1 确定性断言引擎:实践第 1 条"先跑确定性断言"的底层支撑

BestPractices 在"Running Evaluations"中第一条就要求Run deterministic first:在昂贵的 AI 评分之前先跑快速门控。这一要求在 Assertions.ts 中有完整的类型化实现,共 12 种确定性断言类型(Assertions.ts#L20-L32):

断言类型用途
equals精确匹配(trim 后比较)
contains/icontains子串包含(区分/不区分大小写)
contains-all/contains-any多子串全包含 / 任一包含
regex正则匹配
starts-with/ends-with前缀 / 后缀匹配
is-json整个输出是合法 JSON
contains-json输出中嵌入 JSON 片段
max-length/min-length长度上下界(用threshold字段取值)

每条类型都支持not-前缀取反(如not-contains),用于表达"输出不应出现某句话"这类 should-not 断言(Assertions.ts#L157-L160)。确定性断言的评分是二值的:通过得 1,不通过得 0,并附带人类可读的reason(如missing "should work")。

文件尾部的自测(16 个用例,Assertions.ts#L165-L193)可以离线验证断言引擎本身:

bun run ${LIFEOS_SKILL_DIR}/Tools/Assertions.ts # 16-case self-test

1.2 评分器权重配比:确定性 60% / 模型 40%

BestPractices 的"Creating Use Cases"第 2 条要求Define clear criteria: Mix deterministic (60%) + AI-based (40%)。ScorerTypes.md 给出了具体的评分器目录,与这一配比对应:

确定性评分器(建议占 60% 权重)

评分器速度典型用途
sentence-counter<5ms格式校验、长度要求
word-counter<5ms简洁度、长度上限
link-counter<10ms出处标注、引用校验
format-validator<10ms结构、必备章节
voice-validator<10ms禁用词、风格要求
string-match<5ms精确子串匹配
length-validator<5ms字符数上下界
json-schema<20msJSON 结构校验

AI 评分器(建议占 40% 权重)

评分器速度典型用途
llm-judge-accuracy~2s事实准确性、核心要点
llm-judge-style~2s语气真实性、语调
link-attribution-judge~2s作者识别、引用质量

ScorerTypes.md 中的配置示例展示了完整的权重写法:

criteria: deterministic: - scorer: "sentence-counter" weight: 0.10 params: min: 2 max: 3 - scorer: "voice-validator" weight: 0.10 params: forbidden_words: ["unveils", "plummeted"] check_contractions: true ai_based: - scorer: "llm-judge-accuracy" weight: 0.15 params: judge_model: "claude-3-5-sonnet-20241022" reasoning_first: true scale: "1-5" pass_threshold: 0.75

这个 60/40 配比与 BestPractices"先跑确定性、模型断言留给代码检查无法捕捉的细微之处"的原则一致:确定性断言免费且毫秒级,模型断言每次都要走一次推理调用。

2. LLM-as-Judge 设计最佳实践

BestPractices 的"LLM-as-Judge Design"一节给出 5 条裁判设计纪律,逐条展开并对照源码实现:

2.1 Reasoning before scoring:先推理后打分

要求裁判模型先给出解释,再给出分数。这并非风格偏好,而是有量化收益的做法:CreateJudge.md 工作流明确指出"强制先推理"可带来13% 以上的准确率提升,并推荐对所有准确性类裁判设置reasoning_required: true

在 Judge.ts 中,这一纪律被直接写进了裁判的系统提示词(Judge.ts#L38-L51):

  • RUBRIC_SYSTEMFirst reason briefly about how the output meets or misses the rubric. THEN emit exactly one fenced JSON block and nothing after it
  • ASSERT_SYSTEMFirst reason briefly, THEN emit exactly one fenced JSON block and nothing after it

即裁判必须先输出简短推理,然后输出一个 JSON 代码块。解析端extractJson(Judge.ts#L24-L36)先尝试提取围栏内的 JSON,失败时回退到取文本中最后一个配平的{...}片段再JSON.parse,从而对"围栏 + 散文混杂"的输出保持鲁棒。

2.2 Use 1-5 scale:1-5 分制最可靠

BestPractices 明确要求使用 1-5 分制,避免 0-100。CreateJudge.md 的"Scale Selection"表格给出了选型依据:

量表适用场景
1-5最可靠,适合细粒度评估
Binary简单通过/不通过、阈值式判断
1-3当更细的分级没有意义时

并特别警告避免 0-100 量表(校准性差——大区间会让裁判模型难以稳定区分档位)。

源码中这一纪律体现为两步:裁判被要求输出 1-5 的整数分,框架随后做线性归一化(Judge.ts#L79):

const norm = Math.max(0, Math.min(1, (Number(j.score) - 1) / 4));

即 1 分 → 0.0,5 分 → 1.0,中间 2/3/4 分映射到 0.25/0.5/0.75,与断言的threshold(默认 0.6,见 Judge.ts#L82)配合判定通过与否。

2.3 Different judge model:裁判模型必须不同于被评模型

不要让生成输出的模型给自己打分。SKILL.md 的 Gotchas 将此列为硬性约束:judge_level必须不同于agent_level(默认 agent=medium,judge=high)。套件 schema 中通过两个字段实现(EvalRunner.ts#L143-L144):

agent_level: medium # 被测 agent 的推理档位 judge_level: high # 裁判 != 生成者

ScienceMapping.md 把这条实践归类为"确认偏误的对策":不同的裁判模型防止自我服务式(self-serving)评估。

2.4 Position swapping:位置交换消除顺序偏置

做 A/B 对比时,先给出 A 的结果与先给出 B 的结果会产生系统性偏差,因此必须把 A-first 与 B-first 两种顺序各跑一遍并取平均。CreateJudge.md 提供了对应的配置开关:

position_swap: true # 对比类评测开启 # Run twice with swapped positions, average results.

这与 ScienceMapping.md 中"Position swapping mitigates positional bias"的科学方法要求直接对应。

2.5 Multi-judge panels:5-10 个模型的裁判面板

BestPractices 指出由 5-10 个模型组成裁判面板,成本仅为单个大型裁判的约 1/7(原文:7x cheaper than large single judge)。从 ScienceMapping.md 的表述看,其价值在于"多裁判面板可以摊薄单个模型的个性偏差(reduce individual model quirks)"。这与本仓库"用订阅计费的多档位推理(medium/high 等 level)组合"的架构思路一致:用多个较小档位的裁判投票,而不是依赖单一昂贵的大模型裁判。

2.6 补充纪律:强制结构化裁决与 Unknown 逃生舱

虽然 BestPractices 未单列,但源码实现中还内置了两条与之配套的设计(在 Judge.ts 头部注释中被明确标注为"Anthropic 裁判纪律"):

  1. 强制结构化 JSON 裁决:裁判不允许自由文本作答,llm-rubric必须返回{"score": <1-5>, "pass": <bool>, "reason": "<一句话>"}llm-assert必须返回{"results": [{"assertion", "verdict": "TRUE|FALSE|UNKNOWN"}]};解析失败直接判 0 分并记录judge returned unparseable verdict(Judge.ts#L76-L77)。
  2. Unknown 逃生舱:裁判如果无法从输出中确认某条断言,必须显式声明——llm-rubric用 reason 以UNKNOWN:开头,llm-assertverdict: "UNKNOWN"Unknown 一律按未通过计分,这对回归测试是保守且正确的做法。

3. 创建评测用例(Use Cases)的最佳实践

BestPractices 的"Creating Use Cases"一节给出 5 条编写准则:

  1. Start with golden example:以真实的、经过验证的输出作为参照基准;
  2. Define clear criteria:确定性标准(60%)与 AI 标准(40%)混合(见 ScorerTypes.md 的权重示例);
  3. Set pass threshold75% 是推荐基线
  4. Version prompts:用语义化版本管理 prompt;
  5. Document thoroughly:README 必须解释"你在测什么"。

3.1 通过阈值 75% 在实现中的位置

75% 基线是框架的默认值而非建议性注释:EvalRunner.ts#L141 中const threshold = suite.pass_threshold ?? 0.75;——套件未显式声明pass_threshold时自动落到 0.75。套件级通过判定为所有用例均分的加权分是否达到该阈值(EvalRunner.ts#L188)。

3.2 v2 套件/用例 Schema(assertion-first)

SKILL.md 给出了 v2 套件的完整 schema,这也是编写用例时的标准模板:

name: my-suite type: regression # 或 capability pass_threshold: 0.75 agent_level: medium # 被测 agent 的推理档位 judge_level: high # 裁判 != 生成者(Anthropic 最佳实践) trials: 3 # system_prompt: 可选覆盖;默认 = 在线系统提示 + DA 身份 cases: - id: descriptive_name prompt: "发给被测 agent 的用户轮次" assert: - type: not-contains # 确定性断言 value: "should work" weight: 1 - type: llm-rubric # 模型评分,支持权重部分给分 weight: 2 value: "Does the output tie any done-claim to verification evidence?" - type: llm-assert weight: 1 value: ["The output does not claim success without evidence"] - id: should_not_case # 平衡:should-do 与 should-not 都要测 negative: true prompt: "..." assert: [...]

字段要点:

  • assert[].type:12 种确定性类型(含not-取反)或 2 种模型类型(llm-rubric/llm-assert);
  • assert[].weight:默认 1,用于部分给分——单条断言不通过不会归零整个用例;
  • assert[].threshold:模型断言的归一化分通过线,或长度类断言的边界值;
  • negative: true:标注 should-not 用例。SKILL.md 的教条强调should-do 与 should-not 用例要平衡,"单边评测会催生单边优化"。

仓库中现成的 v1 风格用例 disp_verify_before_done.yaml 展示了"黄金标准"思想:rubric 中逐档写清楚 5/3/1 分分别对应什么行为("有验证证据 → 5 分;宣称完成但有保留 → 3 分;无证据宣称成功 → 1 分"),并用两条自然语言断言做 pass-fail 兜底。

3.3 裁判的编写规范(CreateJudge 工作流)

CreateJudge.md 把裁判编写细化为 6 步,其中准则设计的最佳实践值得单独提炼:

  • 3-5 条准则封顶:更多准则会难以校准;
  • 准则互不重叠:每条准则度量一个独立维度;
  • 权重按重要性分配且总和为 1.0
  • 给出具体档位描述:写清楚高分/低分分别长什么样;
  • 对准确性类裁判,reasoning_required: true恒为真。

工作流还附带 Accuracy Judge 的完整示例(Factual Correctness 0.5 / Completeness 0.3 / No Hallucinations 0.2),以及 A/B 对比时开启position_swap: true的配置。

4. 运行评测的最佳实践

BestPractices 的"Running Evaluations"给出 5 条运行准则:先跑确定性断言、至少 5-10 个测试用例、包含边缘/歧义用例、定期跑以检测回归、报告统计量(SEM、置信区间)。逐条对应到仓库实现:

4.1 运行入口与命令行

# 跑一个套件(USER 自定义套件优先于技能自带套件被解析) bun run ${LIFEOS_SKILL_DIR}/Tools/EvalRunner.ts -s <suite> [-t trials] [--json] # 自检断言引擎 / 裁判 bun run ${LIFEOS_SKILL_DIR}/Tools/Assertions.ts # 16-case 自测 bun run ${LIFEOS_SKILL_DIR}/Tools/Judge.ts # 好坏判别自检

EvalRunner.ts 的 CLI 支持-s/--suite(必填)、-t/--trials(覆盖试验数)、--json(机器可读输出)、-h(帮助);退出码 0 = 通过,1 = 回归(EvalRunner.ts#L221-L236),可以直接挂进 CI 或钩子。套件解析顺序为:先 USER 定制层(~/.claude/LIFEOS/USER/CUSTOMIZATIONS/SKILLS/Evals/Suites/),再技能自带的Suites/目录;yaml/yml两种后缀都支持(EvalRunner.ts#L83-L94)。

4.2 "先跑确定性"在运行器中的体现

运行器对每条断言的调度是:isModelAssert(type)为真才走judgeAssertion(模型调用),否则同步执行evaluateDeterministic(EvalRunner.ts#L96-L102)。结合"确定性断言免费"的 Gotcha(SKILL.md),实操建议是把所有能写成代码的检查都写成确定性断言,模型断言只留给"语气、意图、证据链"这类代码抓不住的细微之处。

4.3 试验数与 pass^k / pass@k 的语义

trials默认 3(EvalRunner.ts#L142),BestPractices 建议用例数量至少 5-10 个才有统计可靠性。一个容易踩坑的语义问题值得强调:pass^k 要求 k 次试验全部通过,源码注释专门解释了为什么不用"通过次数/试验数"的平均值——2/3 通过若报成 67% 会让不稳定用例看起来像"大部分通过",修正后的语义是把部分通过的用例记为 0(EvalRunner.ts#L174-L180)。因此历史不同口径的数字不可直接对比。

4.4 边缘用例与负例

"Test edge cases: Include difficult/ambiguous examples" 在框架中有两个落地机制:

  • negative: true用例:显式标注 should-not 场景(如"部署失败时不许说 should work"),防止评测只测 happy path;
  • 裁判的 Unknown 判定:面对歧义输出,裁判被要求声明 UNKNOWN 而非猜测,UNKNOWN 按未通过处理。

仓库自带的回归套件 core-dispositions.yaml 与 4 个 Dispositions 用例(UseCases/Dispositions/)就是按此模式编写的正/负例集合。

4.5 定期运行与回归检测

"Track over time" 在 LifeOS 中有自动化的钩子:hooks/ConfigEvalFire.hook.ts联动LIFEOS/TOOLS/ConfigEvalOnChange.ts,当行为定义文件(system prompt、身份配置等)被修改时自动触发配置的 dispositions 套件(默认core-dispositions),回归即通知 Pulse。该机制非阻塞、防抖,且允许通过 USER 层的config.json覆盖套件名。另外,FailureToTask.ts 支持把真实失败转化为新用例——BestPractices 之外,SKILL.md 建议用 20-50 个真实失败作为用例种子,这正好回应"包含边缘用例"这条准则:最难的边缘用例往往来自线上真实翻车。

5. 解读结果的最佳实践

BestPractices 的"Interpreting Results"要求 5 点,其中第 1、4 条对应框架的硬性设计:

  1. Look at individual scores,而非只看总体 pass/failSuiteResult逐用例输出mean_scorepass_to_kpass_at_k(EvalRunner.ts#L199),CLI 也会逐用例打印(- <case-id>: pass^k X% mean Y%)。
  2. Check failed scorers:每条断言都带reason字段(如missing "should work"0/2 assertions TRUEjudge returned unparseable verdict),定位失败原因直接读断言明细即可。
  3. Compare to baseline:每次运行生成新run_id,结果落在~/.claude/LIFEOS/MEMORY/STATE/Evals-Results/<suite>/<run_id>/run.json,便于跨 run 对比改进/回归。
  4. Validate with human review:SKILL.md 将其升格为教条——"Never trust a score until you read transcripts"(不读转录就不信分数)。每次运行都会把完整的用例输出与断言明细持久化到run.json,并更新latest.json供快速查看(EvalRunner.ts#L202-L207)。
  5. Adjust weights:断言级weight就是调节旋钮——把"什么最重要"用权重大小表达出来,再重跑观察均分变化。

结果汇报时,RunEval.md 工作流规定了结构化报告模板:Pass Rate / Mean Score / Failed Tests 三指标表 + 逐步的 STORY EXPLANATION(跑了多少用例、确定性评分先完成、AI 裁判评了什么、加权分如何计算、与阈值对比、关键发现与建议)。

6. 统计严谨性要求(Statistical Rigor)

BestPractices 最后单列一节硬性要求,原文 4 条:

  • 报告SEM(标准误,Standard Error of Mean)
  • 置信区间(默认 95%)
  • 统计显著性检验
  • 带阈值的通过/不通过率(pass/fail rates with thresholds)。

ScienceMapping.md 把这些要求放入科学方法框架,并补充了四条配套纪律:

  1. 可证伪性(不可妥协):每个假设必须可证伪——比较 prompt 时先问"什么结果能推翻变体 X 更优的结论?"答不上来,这次评测就不是科学评测;
  2. 预承诺(Pre-Commitment):成功标准必须在看到结果之前定义,通过阈值在用例创建时锁定,数据收集后不许移动球门。这解释了为什么pass_threshold是套件声明字段而非事后参数——SKILL.md 中 capability 套件"从低处起步"、regression 套件"瞄准 ~100%"的分级,就是预承诺的具体形态;
  3. 多元性(Plurality):不只 A/B,建议 A/B/C 至少三个变体,多个假设能更好地探索解空间并降低对第一个替代方案的确认偏误;
  4. 确认偏误对策:位置交换(见 2.4)、不同裁判模型(见 2.3)、多裁判面板(见 2.5)、必须达到统计显著性才能宣布获胜者

ScienceMapping 还给出了"何时显式启动完整科学协议"的触发条件:迭代 3 轮以上仍无改进(范式检查)、结果混乱矛盾、赌注足够高需要正式文档化、或问题本身是"我们是不是该测别的东西了"。

7. 落地核对清单

把 BestPractices 全部 24 条(5 节)浓缩为可执行清单,供编写/审查评测时逐项核对:

裁判设计

  • 裁判 prompt 强制"先推理后打分"(参考 Judge.ts#L38-L51 的系统提示写法)
  • 使用 1-5 分制,禁止 0-100
  • judge_levelagent_level
  • A/B 对比开启position_swap,两次取平均
  • 高价值对比用 5-10 模型裁判面板

用例编写

  • 从真实黄金输出起步
  • 确定性:AI 标准 ≈ 60:40,权重总和 1.0
  • pass_threshold: 0.75(或按预承诺显式调整)
  • prompt 语义化版本管理
  • README 说清"在测什么"
  • should-do 与 should-not(negative: true)用例平衡

运行

  • 确定性断言先行,模型断言只留细微之处
  • 用例 ≥ 5-10 个,含歧义/困难边缘用例
  • 定期运行(或接入配置变更钩子)检测回归
  • 报告 SEM 与 95% 置信区间

解读

  • 看单用例分数与失败断言的reason
  • 与基线 run 对比
  • 人工复核转录(读run.json
  • 按重要性调整断言权重再复跑

8. 参考文件索引

文件作用
BestPractices.md本文主题文档:5 节 24 条最佳实践
SKILL.md框架总览:v2 规范路径、schema、教条与 Gotchas
ScorerTypes.md确定性/AI 评分器目录、速度与 60/40 权重配置示例
ScienceMapping.md科学方法映射:可证伪、预承诺、多元性、偏误对策
Tools/Judge.ts模型评分实现:reason-then-score、强制 JSON、Unknown→miss
Tools/Assertions.ts确定性断言引擎:12 种类型 +not-取反 + 16 例自测
Tools/EvalRunner.ts套件运行器:pass^k/pass@k、CLI、结果持久化
Workflows/CreateJudge.md裁判编写 6 步工作流与量表选型表
Workflows/RunEval.md运行工作流与结构化报告模板
UseCases/Dispositions/4 个 dispositions 回归用例实例
Suites/Regression/自带回归套件

适用前提与限制:本文所有行为描述均以当前仓库的 Evals v2(assertion-first)路径为准。仓库同时保留了 v1 遗留栈(Graders/TrialRunner.ts、基于@langwatch/scenario的场景路径),SKILL.md 明确标注其已被取代——v1 套件(使用tasks:列表而非cases:)无法被EvalRunner执行,运行器会返回命名错误而非猜测执行(EvalRunner.ts#L134-L140);场景路径按 API key 计费,不建议用于主工作负载。裁判与推理调用均经由Inference.ts走订阅计费链路,无 API-key 路径。

【免费下载链接】LifeOS⛰️ The Life Operating System — an intent engineering platform that moves you from your current state to your ideal state, in life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询