Skip to content

v0.23.0

Choose a tag to compare

@github-actions github-actions released this 29 Apr 15:10
· 575 commits to main since this release
85a656b

Added

  • 测评用例科学性 v1(对标 HELM / MMLU-Pro / Construct Validity 三件套 / HF Dataset Cards 行业共识):Sample schema 加 4 个可选元数据字段(capability / difficulty / construct / provenance),纯文档/诊断用,完全不参与 grading / judge / verdict / Report 顶层 schema(测量学不变量保护,跨版本 verdict / Δ 完全可比,跟 v0.22 strict-baseline 那次的 breaking-comparability 区分开)。
    • Sample 元数据(src/types/eval.ts):
      • capability?: string[] — 该用例覆盖的能力维度(如 ['api-selection', 'error-diagnosis']),归一时大小写/短横线/驼峰/下划线不敏感
      • difficulty?: 'easy' | 'medium' | 'hard' — 难度分层(强枚举,防错)
      • construct?: string — 该用例测的 construct 类型,suggested values:'necessity'(测必要性,baseline-vs-skill)/ 'quality'(测 skill 写得好不好,skill-v1-vs-skill-v2)/ 'capability'(测某具体能力);free-form string 允许自定义
      • provenance?: 'human' | 'llm-generated' | 'production-trace' — 数据来源
    • load-samples.ts 新增 enum 校验:difficulty / provenance 非法值含 sample_id 定位的错误信息(形如 samples[3] (s007) invalid difficulty: 'easy?', expected one of [easy, medium, hard]);capability 必须是 string[];construct 接受任意 string。
    • bench diagnose 加 2 类新 issue:
      • rubric_clarity_low(info):rubric < 20 字符 AND 不含任何评分级别词(中英 22 词清单)→ static rubric quality signal,跟现有 ambiguous_rubric(runtime/judge stddev)互补
      • capability_thin(warning):某 capability 只 ≤ max(2, N*0.2) 个 sample 撑(总 N≥10 才检测,小 N 自动跳过避免全报)
      • fine-grained discrimination signal(IRT 风格)留 follow-up
    • bench diagnose CLI 加 sample design coverage 块:capability / difficulty / construct / provenance 分桶呈现(ASCII),数据从 report.analysis.sampleQuality 取(分桶聚合)或 fresh 加载 samples 算
    • Report.analysis.sampleQuality:新增 SampleQualityAggregate 子结构,纯文档聚合(capabilityCoverage / difficultyDistribution / constructDistribution / provenanceBreakdown / avgRubricLength / sampleCountWith*)。不破老报告兼容:不传 samples 时不挂此字段,老 reader 读取仍正常。
    • bench gen-samples 自动注入 provenance: 'llm-generated':SYSTEM_PROMPT 加可选 hint 段(LLM 如能判断顺便填 capability / difficulty / construct,无法判断省略不强制)
    • 新建 docs/sample-design-spec.md:行业 8 条 gap 引用 + omk v1 映射 + 完整 yaml example + 11 条用例设计自检 checklist + verdict 解读跟 construct 配合 + §八 Schema 扩展候选(v2 路线 source_ids / status / 拒绝清单 tags / expected_facts / owner / risk_level 含理由)
    • HTML report 暂不显示 sample design coverage(只 CLI bench diagnose),HTML 渲染留 follow-up — 用户跑 HTML 报告需要看 coverage 时,从 report.jsonanalysis.sampleQuality
    • R11 防御测试:test/grading/judge-prompt-isolation.test.ts 锁住 judge prompt 不含任何 sample 元数据 token('capability:' / 'difficulty:' 等),防未来 refactor 把元数据意外注入 judge prompt 破坏 construct validity
    • 软兼容性 callout:如果用户之前用 sample.capability 作为自由 unknown 字段(string / object / 其它),v1 起此字段是 string[],类型校验会拒掉非数组值(此前 omk 没 publicize 过 capability 名字,概率极低)。provenance enum 简化:'evolved' / 'mixed' 留 follow-up 跟 evolver 升级一起做。

Fixed

  • VariantSummary.toolDistribution 修真实 call count:之前 aggregate 阶段按 result.toolNames(per-sample dedup 列表)累加,语义是"出现该 tool 的 sample 数",跟字段名"工具调用分布"不符 — 用户读 summary 看到 Read: 5 以为模型调了 5 次 Read,实际是"5 个样本里出现过 Read"。修法:VariantResult 加 per-sample toolDistribution(从 toolCalls reduce 得到真实 call count map),aggregate 时 sum per-sample 字段。旧报告 result 没 toolDistribution 字段时 fallback 到老 toolNames 语义保兼容。

Changed

  • ⚠️ BREAKING:report server URL 从 /run/<id> 改为 /reports/<id>:命名跟 codebase 内一致语义(Report 类型 / ~/.oh-my-knowledge/reports/ 目录 / omk bench report CLI 命令)对齐。/run/ 是 omk 内部把 "evaluation run" 当 entity 的旧叫法,但用户打开 URL 是来"看报告"的——/reports/ 直接匹配心智。同步改:/api/run/<id>/api/reports/<id>,/api/runs/api/reports直接删旧路径,不留兼容 alias(omk 0-1 阶段)。已有书签需要更新。

  • ⚠️ BREAKING-COMPARABILITY:bench run / bench gate 默认对 baseline-kind variant 启用 skill isolation(--strict-baseline default true)。这是 omk 测量学严谨性的根本承诺补全:之前 baseline 通过三条 channel(SDK skill auto-discovery / subagent Skill 工具 / cwd 文件系统)拿到 ~/.claude/skills/ 全部 skill,导致 baseline-vs-skill 比较 construct invalid——baseline 跟 treatment 看到的是同一份 skill 内容,Δ 接近 0 是必然结果。本版默认三堵(main session skills + subagent Skill 工具 + cwd 切到 isolated empty dir),baseline 真正干净。

    改动范围:

    • CLI flag:新增 --strict-baseline(default true) / --no-strict-baseline(显式 opt-out 逃生口)。bench run + bench gate 同步支持。pre-flight 在 --no-strict-baseline + ~/.claude/skills/ 非空时 stderr 显式提醒。
    • eval.yaml schema:新增 variants[].allowedSkills?: string[] 显式声明,优先级高于 CLI flag。undefined = 默认 / [] = 完全隔离 / [name1, name2] = 白名单。YAML allowedSkills: 不写值会被 parse 成 null,显式 reject(语义不清)。
    • executor 行为:claude-sdk 注入 skills + disallowedTools:['Skill'];claude-cli 等价(--disable-slash-commands + --disallowedTools Skill,文档说前者就是 "Disable all skills"),任意非空白名单 throw 提示改 sdk(CLI 没暴露 partial whitelist);script 仅 stderr warn 不参与 isolation。
    • cache key 升级 v2: prefix + 含 allowedSkills:旧 cache 一次性失效(避免 strict / non-strict 切换时误命中污染结果)。同 prompt 不同 isolation 必拿不同 cache key。
    • report.meta.skillIsolation:新字段记录每个 variant 的 allowedSkills 快照(undefined → null),供跨报告对比。--resume 时 isolation 状态不一致 stderr warn 不阻塞。
    • 隔离覆盖(三条 channel):
      1. main session skills(SDK options.skills):skills:[] 关 SDK 内部 skill 发现
      2. subagent Skill 工具(SDK options.disallowedTools):disallowedTools:['Skill'] 关 SDK 内置 task subagent 调 Skill 工具
      3. cwd 文件系统访问(切到 isolated empty dir):baseline 默认 cwd 是 process.cwd()(用户评测工作目录),那里通常有 skills/<name>/ symlink 给 treatment 用 — baseline 用 Glob/Read 直接顺 symlink 读 SKILL.md 就完全绕过 SDK 隔离。strict 模式 + 用户没显式 cwd 时切到 ~/.oh-my-knowledge/isolated-cwd/(空目录),Glob/Read 探索不到任何 skill 文件。这条是真正 load-bearing 的 channel — 仅堵 SDK 两条时 baseline 输出仍含被测 skill 的私有 token,加 cwd 隔离后才真正干净。
    • MCP servers:已默认堵(SDK settingSources 默认 [] + omk 不传 mcpServers)。
    • 已知 limit:AgentDefinition.skills 白名单精确控制留 follow-up(白名单场景 subagent 仍能调 Skill 工具,但 v1 用户主要用 [] 完全隔离,影响小)。

    breaking-comparability 标记:旧报告(无 meta.skillIsolation)与新报告 verdict / Δ 不可跨版本对比——等同 judge prompt bump 一档;CHANGELOG 显式 callout。迁移指南:

    • 已有 baseline-vs-skill 评测脚本无需改 flag 即享受 default strict;旧报告作为"污染基线"留存,新跑作为"干净基线"。
    • 需要老行为(测 baseline 走默认 skill 发现的效果)显式加 --no-strict-baseline
    • 跨版本对比 verdict / Δ 前先看 meta.skillIsolation 是否一致。

    设计 spec 见 docs/terminology-spec.md §七 Skill Isolation

Internal

  • 新增 buildSdkIsolationOptions(allowedSkills)(纯函数,可测) + buildIsolationWarnings(artifacts, strictBaseline) pre-flight helper。
  • resolveArtifacts(skillDir, variants, opts) 新增 opts: { strictBaseline?, variantAllowedSkills? },旧 caller 0 改动(opts 全 optional)。
  • cacheKey() signature 加 allowedSkills?: string[] 入参,旧 caller 不传时退化到默认行为(但 prefix 升级到 v2:,旧 cache 一次性失效)。
  • 单测覆盖:resolveArtifacts 三种优先级 / cache key 不同 isolation 不同键 + 顺序不敏感 / SDK option 形态契约 / claude-cli throw 非空白名单 / eval-config schema reject null + 非数组 / report.meta.skillIsolation populate / pre-flight isolation warning 触发条件。
  • lint 严格化三层防御:(1) yarn lint--max-warnings 0,任何 warning 都让 CI / yarn ci 红;(2) 新加 husky + lint-staged pre-commit hook,commit 前对 staged TS 文件跑 eslint --max-warnings 0,本地拦住坏 commit;(3) .claude/settings.jsonStop hook,Claude Code 协作时每次 turn 结束自动跑 yarn lint(只在 src/test TS 文件有改动时跑,避免无用 IO),AI 编辑出 warning 立刻被 feedback 回来。前置清掉 4 个 pre-existing unused-var warning(summary.ts 没用的 levelIcon helper;grader.test.ts 两处 { dirname, join } 解构里 join 没用;trace-adapter.test.ts 没用的 TestSession type alias)。
  • src/cli 模块化重构:src/cli.ts (1956 行单文件)→ src/cli/index.ts (1583 行 entry + dispatcher) + 抽 parse-run-config.ts / progress.ts / update-check.ts / coverage-renderer.ts(后者从 src/analysis/ 搬过来,本质 CLI 渲染)。修 sibling-folder 反模式(src/cli.tssrc/cli/ 同级)。package.json bin 路径同步:dist/src/cli.jsdist/src/cli/index.js。纯 file move + 路径调整,不动逻辑。
  • Reconcile main → develop:0.22.0 release 走的是从更早 develop 切出的 release/0.22.0,跟 PR #26(sample-design v1)并行,release prep 两处代码改动没回到 develop。本次补到 cli refactor 后的位置:checkUpdate 5 层向上找 package.json 落到 src/cli/update-check.ts(兼容 dist/src/cli/ 这条新路径);handleRunblind: { type: 'boolean' } + if (values.blind !== undefined) 守门(避免 CLI default 覆盖 eval.yamlblind: true)已通过 git rename detection 自动 merge 到 src/cli/index.ts。同时把 [0.22.0] CHANGELOG section 两处描述对齐到中性表述,跟 GitHub Release v0.22.0 notes 同步。

What's Changed

  • feat(sample-design): 测评用例科学性 v1 — 4 字段元数据 + 2 新诊断 + 行业 8 gap 映射 by @lizhiyao in #26
  • chore(reconcile): merge main → develop + 中性化 [0.22.0] CHANGELOG 描述 by @lizhiyao in #28
  • chore(release): 0.23.0 by @lizhiyao in #29

Full Changelog: v0.22.0...v0.23.0