oh-my-knowledge 0.23.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -84
- package/README.zh.md +144 -83
- package/dist/src/analysis/report-diagnostics.d.ts +3 -2
- package/dist/src/analysis/report-diagnostics.d.ts.map +1 -1
- package/dist/src/analysis/report-diagnostics.js +107 -80
- package/dist/src/analysis/report-diagnostics.js.map +1 -1
- package/dist/src/analysis/sample-diagnostics.d.ts +4 -1
- package/dist/src/analysis/sample-diagnostics.d.ts.map +1 -1
- package/dist/src/analysis/sample-diagnostics.js +123 -29
- package/dist/src/analysis/sample-diagnostics.js.map +1 -1
- package/dist/src/analysis/saturation.d.ts +2 -2
- package/dist/src/analysis/saturation.js +2 -2
- package/dist/src/authoring/evolver.d.ts +12 -4
- package/dist/src/authoring/evolver.d.ts.map +1 -1
- package/dist/src/authoring/evolver.js +35 -10
- package/dist/src/authoring/evolver.js.map +1 -1
- package/dist/src/cli/i18n-dict.d.ts +1 -1
- package/dist/src/cli/i18n-dict.d.ts.map +1 -1
- package/dist/src/cli/i18n-dict.js +241 -64
- package/dist/src/cli/i18n-dict.js.map +1 -1
- package/dist/src/cli/index.js +267 -152
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/parse-run-config.d.ts +32 -9
- package/dist/src/cli/parse-run-config.d.ts.map +1 -1
- package/dist/src/cli/parse-run-config.js +80 -25
- package/dist/src/cli/parse-run-config.js.map +1 -1
- package/dist/src/cli/parse-strict.d.ts +20 -0
- package/dist/src/cli/parse-strict.d.ts.map +1 -0
- package/dist/src/cli/parse-strict.js +25 -0
- package/dist/src/cli/parse-strict.js.map +1 -0
- package/dist/src/cli/progress.d.ts +1 -0
- package/dist/src/cli/progress.d.ts.map +1 -1
- package/dist/src/cli/progress.js +8 -1
- package/dist/src/cli/progress.js.map +1 -1
- package/dist/src/doctor/index.d.ts +19 -0
- package/dist/src/doctor/index.d.ts.map +1 -0
- package/dist/src/doctor/index.js +182 -0
- package/dist/src/doctor/index.js.map +1 -0
- package/dist/src/doctor/preflight.d.ts +32 -0
- package/dist/src/doctor/preflight.d.ts.map +1 -0
- package/dist/src/doctor/preflight.js +32 -0
- package/dist/src/doctor/preflight.js.map +1 -0
- package/dist/src/doctor/renderer.d.ts +13 -0
- package/dist/src/doctor/renderer.d.ts.map +1 -0
- package/dist/src/doctor/renderer.js +69 -0
- package/dist/src/doctor/renderer.js.map +1 -0
- package/dist/src/doctor/rules.d.ts +30 -0
- package/dist/src/doctor/rules.d.ts.map +1 -0
- package/dist/src/doctor/rules.js +216 -0
- package/dist/src/doctor/rules.js.map +1 -0
- package/dist/src/eval-core/bootstrap.d.ts +1 -1
- package/dist/src/eval-core/bootstrap.js +1 -1
- package/dist/src/eval-core/cache.d.ts +7 -5
- package/dist/src/eval-core/cache.d.ts.map +1 -1
- package/dist/src/eval-core/cache.js +11 -7
- package/dist/src/eval-core/cache.js.map +1 -1
- package/dist/src/eval-core/comparability.d.ts +11 -0
- package/dist/src/eval-core/comparability.d.ts.map +1 -0
- package/dist/src/eval-core/comparability.js +296 -0
- package/dist/src/eval-core/comparability.js.map +1 -0
- package/dist/src/eval-core/dependency-checker.js +1 -1
- package/dist/src/eval-core/dependency-checker.js.map +1 -1
- package/dist/src/eval-core/evaluation-execution.d.ts +23 -7
- package/dist/src/eval-core/evaluation-execution.d.ts.map +1 -1
- package/dist/src/eval-core/evaluation-execution.js +53 -21
- package/dist/src/eval-core/evaluation-execution.js.map +1 -1
- package/dist/src/eval-core/evaluation-job.d.ts +3 -5
- package/dist/src/eval-core/evaluation-job.d.ts.map +1 -1
- package/dist/src/eval-core/evaluation-job.js +2 -4
- package/dist/src/eval-core/evaluation-job.js.map +1 -1
- package/dist/src/eval-core/evaluation-reporting.d.ts +3 -1
- package/dist/src/eval-core/evaluation-reporting.d.ts.map +1 -1
- package/dist/src/eval-core/evaluation-reporting.js +67 -9
- package/dist/src/eval-core/evaluation-reporting.js.map +1 -1
- package/dist/src/eval-core/execution-strategy.js +2 -2
- package/dist/src/eval-core/execution-strategy.js.map +1 -1
- package/dist/src/eval-core/schema.d.ts.map +1 -1
- package/dist/src/eval-core/schema.js +20 -2
- package/dist/src/eval-core/schema.js.map +1 -1
- package/dist/src/eval-workflows/batch-evaluation-workflow.d.ts +113 -0
- package/dist/src/eval-workflows/batch-evaluation-workflow.d.ts.map +1 -0
- package/dist/src/eval-workflows/batch-evaluation-workflow.js +217 -0
- package/dist/src/eval-workflows/batch-evaluation-workflow.js.map +1 -0
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts +6 -4
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts.map +1 -1
- package/dist/src/eval-workflows/evaluation-pipeline.js +44 -38
- package/dist/src/eval-workflows/evaluation-pipeline.js.map +1 -1
- package/dist/src/eval-workflows/evaluation-preparation.d.ts +4 -17
- package/dist/src/eval-workflows/evaluation-preparation.d.ts.map +1 -1
- package/dist/src/eval-workflows/evaluation-preparation.js +3 -18
- package/dist/src/eval-workflows/evaluation-preparation.js.map +1 -1
- package/dist/src/eval-workflows/run-evaluation.d.ts +27 -23
- package/dist/src/eval-workflows/run-evaluation.d.ts.map +1 -1
- package/dist/src/eval-workflows/run-evaluation.js +137 -20
- package/dist/src/eval-workflows/run-evaluation.js.map +1 -1
- package/dist/src/executors/claude-cli.d.ts.map +1 -1
- package/dist/src/executors/claude-cli.js +11 -6
- package/dist/src/executors/claude-cli.js.map +1 -1
- package/dist/src/executors/codex-cli-trace.d.ts +10 -0
- package/dist/src/executors/codex-cli-trace.d.ts.map +1 -0
- package/dist/src/executors/codex-cli-trace.js +123 -0
- package/dist/src/executors/codex-cli-trace.js.map +1 -0
- package/dist/src/executors/codex-cli.d.ts +18 -0
- package/dist/src/executors/codex-cli.d.ts.map +1 -0
- package/dist/src/executors/codex-cli.js +254 -0
- package/dist/src/executors/codex-cli.js.map +1 -0
- package/dist/src/executors/codex-sdk.d.ts +18 -0
- package/dist/src/executors/codex-sdk.d.ts.map +1 -0
- package/dist/src/executors/codex-sdk.js +214 -0
- package/dist/src/executors/codex-sdk.js.map +1 -0
- package/dist/src/executors/gemini.d.ts.map +1 -1
- package/dist/src/executors/gemini.js +28 -24
- package/dist/src/executors/gemini.js.map +1 -1
- package/dist/src/executors/index.d.ts.map +1 -1
- package/dist/src/executors/index.js +7 -2
- package/dist/src/executors/index.js.map +1 -1
- package/dist/src/executors/runtime-fingerprint.d.ts +7 -0
- package/dist/src/executors/runtime-fingerprint.d.ts.map +1 -0
- package/dist/src/executors/runtime-fingerprint.js +277 -0
- package/dist/src/executors/runtime-fingerprint.js.map +1 -0
- package/dist/src/executors/script.d.ts.map +1 -1
- package/dist/src/executors/script.js +47 -55
- package/dist/src/executors/script.js.map +1 -1
- package/dist/src/executors/shared.d.ts +78 -1
- package/dist/src/executors/shared.d.ts.map +1 -1
- package/dist/src/executors/shared.js +203 -1
- package/dist/src/executors/shared.js.map +1 -1
- package/dist/src/grading/assertions.d.ts.map +1 -1
- package/dist/src/grading/assertions.js +22 -7
- package/dist/src/grading/assertions.js.map +1 -1
- package/dist/src/grading/gold-cli.js +4 -4
- package/dist/src/grading/gold-cli.js.map +1 -1
- package/dist/src/grading/human-gold.d.ts +1 -1
- package/dist/src/grading/human-gold.js +1 -1
- package/dist/src/grading/index.d.ts +20 -15
- package/dist/src/grading/index.d.ts.map +1 -1
- package/dist/src/grading/index.js +40 -16
- package/dist/src/grading/index.js.map +1 -1
- package/dist/src/grading/judge.d.ts +1 -1
- package/dist/src/grading/judge.d.ts.map +1 -1
- package/dist/src/grading/judge.js +76 -7
- package/dist/src/grading/judge.js.map +1 -1
- package/dist/src/inputs/eval-config.js +65 -7
- package/dist/src/inputs/eval-config.js.map +1 -1
- package/dist/src/inputs/skill-loader.d.ts +1 -1
- package/dist/src/inputs/skill-loader.d.ts.map +1 -1
- package/dist/src/inputs/skill-loader.js +1 -1
- package/dist/src/inputs/skill-loader.js.map +1 -1
- package/dist/src/renderer/html-renderer.d.ts +5 -4
- package/dist/src/renderer/html-renderer.d.ts.map +1 -1
- package/dist/src/renderer/html-renderer.js +240 -96
- package/dist/src/renderer/html-renderer.js.map +1 -1
- package/dist/src/renderer/layout.d.ts +2 -1
- package/dist/src/renderer/layout.d.ts.map +1 -1
- package/dist/src/renderer/layout.js +30 -42
- package/dist/src/renderer/layout.js.map +1 -1
- package/dist/src/renderer/summary.d.ts +3 -3
- package/dist/src/renderer/summary.d.ts.map +1 -1
- package/dist/src/renderer/summary.js +233 -43
- package/dist/src/renderer/summary.js.map +1 -1
- package/dist/src/renderer/trends.d.ts.map +1 -1
- package/dist/src/renderer/trends.js +5 -3
- package/dist/src/renderer/trends.js.map +1 -1
- package/dist/src/server/report-server.js +4 -4
- package/dist/src/server/report-server.js.map +1 -1
- package/dist/src/server/report-store.d.ts +7 -5
- package/dist/src/server/report-store.d.ts.map +1 -1
- package/dist/src/server/report-store.js +39 -11
- package/dist/src/server/report-store.js.map +1 -1
- package/dist/src/types/doctor.d.ts +95 -0
- package/dist/src/types/doctor.d.ts.map +1 -0
- package/dist/src/types/doctor.js +2 -0
- package/dist/src/types/doctor.js.map +1 -0
- package/dist/src/types/eval.d.ts +40 -19
- package/dist/src/types/eval.d.ts.map +1 -1
- package/dist/src/types/executor.d.ts +38 -0
- package/dist/src/types/executor.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +1 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +1 -0
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/judge.d.ts +21 -0
- package/dist/src/types/judge.d.ts.map +1 -1
- package/dist/src/types/report.d.ts +100 -35
- package/dist/src/types/report.d.ts.map +1 -1
- package/dist/src/types/storage.d.ts +7 -7
- package/dist/src/types/storage.d.ts.map +1 -1
- package/package.json +6 -5
- package/dist/src/eval-workflows/each-evaluation-workflow.d.ts +0 -153
- package/dist/src/eval-workflows/each-evaluation-workflow.d.ts.map +0 -1
- package/dist/src/eval-workflows/each-evaluation-workflow.js +0 -178
- package/dist/src/eval-workflows/each-evaluation-workflow.js.map +0 -1
- package/dist/src/executors/openai-cli.d.ts +0 -3
- package/dist/src/executors/openai-cli.d.ts.map +0 -1
- package/dist/src/executors/openai-cli.js +0 -60
- package/dist/src/executors/openai-cli.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,55 +1,22 @@
|
|
|
1
1
|
# oh-my-knowledge
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/oh-my-knowledge)
|
|
4
|
+
[](https://www.npmjs.com/package/oh-my-knowledge)
|
|
4
5
|
[](https://github.com/lizhiyao/oh-my-knowledge/actions/workflows/ci.yml)
|
|
5
6
|
[](./LICENSE)
|
|
6
7
|
[](https://nodejs.org)
|
|
7
8
|
|
|
8
9
|
**English** | [简体中文](./README.zh.md)
|
|
9
10
|
|
|
10
|
-
**omk** —
|
|
11
|
+
**omk** — The knowledge you give your LLM — what's it actually worth?
|
|
12
|
+
omk answers with objective data, not gut feeling.
|
|
11
13
|
|
|
12
|
-
**Fix the model, vary the knowledge artifact
|
|
14
|
+
**Fix the model, vary the knowledge artifact.**
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Teams doing knowledge engineering produce lots of knowledge artifacts (skills today, but also prompts, agents, workflows…). When someone asks "why is v2 better than v1", you need objective data instead of gut feeling. `oh-my-knowledge` solves this with controlled experiments: **same model, same test samples, only the knowledge artifact changes.**
|
|
17
|
-
|
|
18
|
-
## Key features
|
|
19
|
-
|
|
20
|
-
- **Controlled-variable offline bench** — fix the model and samples, vary only the artifact; works with Claude Code skills, CLAUDE.md prompts, RAG knowledge bases, or any markdown-based instruction
|
|
21
|
-
- **Six-dimension scoring** — separate signals for Fact / Behavior / LLM-judge / Cost / Efficiency / Stability, so a regression in one axis isn't hidden by gains in another
|
|
22
|
-
- **Production session observability** — parse Claude Code session JSONL traces, measure per-skill failure rate, latency, token cost, and knowledge-gap signals on real user sessions
|
|
23
|
-
- **Knowledge-gap detection** — severity-weighted signals (explicit markers / failed searches / hedging language / repeated failures) quantify risk exposure instead of claiming completeness
|
|
24
|
-
- **Pre-merge CI gate** — `omk bench gate` enforces three-layer all-pass (fact + behavior + llm-judge) semantics, catching single-layer regressions a composite score would hide
|
|
25
|
-
- **One-line ship/no-ship verdict** — `omk bench verdict <reportId>` aggregates bootstrap CI / three-layer ci-gate / saturation / human α into a six-tier verdict (PROGRESS / CAUTIOUS / REGRESS / NOISE / UNDERPOWERED / SOLO) plus an action recommendation; the exit code reflects whether to ship
|
|
26
|
-
|
|
27
|
-
### Statistical rigor
|
|
28
|
-
|
|
29
|
-
The biggest LLM-eval failure mode is "confident bias" — narrow CIs around the wrong answer. omk's statistical layer ships four pieces so conclusions can be externally audited:
|
|
30
|
-
|
|
31
|
-
- **Bootstrap CI** (`--bootstrap`) — distribution-free confidence intervals. The t-test breaks on ordinal LLM scores; bootstrap resamples raw observations and stays valid at small N (< 30) and on skewed data. Pairwise diff CI not crossing 0 = significant.
|
|
32
|
-
- **Human Gold + Krippendorff α** (`--gold-dir`) — bring an external annotation as anchor. CI tells you "is the judge stable", α tells you "is the judge correct" — two complementary axes. omk warns when the gold annotator and the judge are the same model (would inflate α).
|
|
33
|
-
- **Length-controlled judge prompt** (default ON) — research shows LLM judges over-weight verbosity. omk's judge prompt explicitly states "length is not a quality signal"; template hash is `v3-cot-length` so older reports (with the legacy hash) are visibly different. `omk bench debias-validate length <reportId>` re-judges with the opposite setting and reports the score shift.
|
|
34
|
-
- **Saturation curve** — answers "have I run enough samples?". With `--repeat ≥ 5` we accumulate cumulative N → bootstrap CI; when CI shrink rate stays under 5% across 3 windows, more samples buy nothing. The HTML report inlines the SVG curve plus a verdict.
|
|
35
|
-
|
|
36
|
-
## Why omk over alternatives
|
|
37
|
-
|
|
38
|
-
| | omk | promptfoo | DeepEval | RAGAS | LangSmith |
|
|
39
|
-
|--|--|--|--|--|--|
|
|
40
|
-
| Bootstrap CI | ✓ | ✗ | ✗ | ✗ | ✗ |
|
|
41
|
-
| Krippendorff α (judge ↔ human) | ✓ | ✗ | ✗ | ✗ | ✗ |
|
|
42
|
-
| Length-debias judge prompt | ✓ default | ✗ | ✗ | ✗ | ✗ |
|
|
43
|
-
| Saturation curve | ✓ | ✗ | ✗ | ✗ | ✗ |
|
|
44
|
-
| Three-layer scoring isolation | ✓ | ✗ | partial | ✗ | ✗ |
|
|
45
|
-
| Per-variant skill isolation (construct validity) | ✓ default | ✗ | ✗ | ✗ | ✗ |
|
|
46
|
-
| Native Claude Code skill | ✓ | ✗ | ✗ | ✗ | ✗ |
|
|
47
|
-
| Full Chinese docs | ✓ | ✗ | ✗ | ✗ | ✗ |
|
|
48
|
-
| Hosted SaaS dashboard | ✗ | ✗ | ✓ | ✗ | ✓ |
|
|
49
|
-
|
|
50
|
-
omk's moat is **statistical rigor** — every conclusion is auditable by a researcher. If you need a hosted SaaS dashboard, choose LangSmith. If you want quick local prompt iteration without statistics, choose promptfoo. **If you ship to production and someone will ask "why should I trust this number?", choose omk**.
|
|
16
|
+
<a id="statistical-rigor"></a>
|
|
17
|
+
> Built-in: Bootstrap CI · Krippendorff α (judge ↔ human) · length-debias · saturation curves · construct-validity isolation. [Why these matter →](docs/statistical-rigor.md)
|
|
51
18
|
|
|
52
|
-
|
|
19
|
+

|
|
53
20
|
|
|
54
21
|
## Quick start
|
|
55
22
|
|
|
@@ -70,46 +37,93 @@ cd my-eval
|
|
|
70
37
|
omk bench run --dry-run
|
|
71
38
|
|
|
72
39
|
# run the evaluation (auto-discovers everything under skills/)
|
|
73
|
-
omk bench run
|
|
40
|
+
omk bench run # → HTML report with verdict in 5 minutes
|
|
41
|
+
# (omk doctor + LLM connectivity check both run as mandatory gates;
|
|
42
|
+
# --skip-connectivity available for connectivity, doctor is unconditional)
|
|
74
43
|
|
|
75
44
|
# CLI output language: zh (default) / en — flag wins over env
|
|
76
45
|
omk bench run --lang en
|
|
77
46
|
OMK_LANG=en omk bench report
|
|
78
47
|
```
|
|
79
48
|
|
|
80
|
-
## Use inside
|
|
49
|
+
## Use inside AI Coding Agents
|
|
81
50
|
|
|
82
|
-
|
|
51
|
+
### Use inside Claude Code
|
|
83
52
|
|
|
84
|
-
|
|
53
|
+
When the `omk` skill is available in Claude Code, you can invoke it directly like this:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
85
56
|
/omk eval # evaluate the artifact(s) in the current project
|
|
86
57
|
/omk evolve # auto-iterate to improve an artifact
|
|
87
58
|
/omk gen-samples # generate test cases
|
|
88
59
|
```
|
|
89
60
|
|
|
90
|
-
You can also just say "compare v1 vs v2 for me" or "improve this artifact"
|
|
61
|
+
You can also just say "compare v1 vs v2 for me" or "improve this artifact" and omk picks the right command.
|
|
62
|
+
|
|
63
|
+
### Use inside Codex
|
|
64
|
+
|
|
65
|
+
Codex does not support Claude Code style `/omk ...` slash commands by default. In Codex, the usual pattern is to ask the agent to run the `omk` CLI directly, for example:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
omk bench run
|
|
69
|
+
omk bench evolve
|
|
70
|
+
omk bench gen-samples skills/my-skill.md
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
You can also describe the goal in natural language, such as "compare v1 vs v2" or "generate test cases for this skill".
|
|
74
|
+
|
|
75
|
+
## Why this tool
|
|
76
|
+
|
|
77
|
+
Teams doing knowledge engineering produce lots of knowledge artifacts (skills today, but also prompts, agents, workflows…). When someone asks "why is v2 better than v1", you need objective data instead of gut feeling. `oh-my-knowledge` solves this with controlled experiments: **same model, same test samples, only the knowledge artifact changes.**
|
|
78
|
+
|
|
79
|
+
## Key features
|
|
80
|
+
|
|
81
|
+
- **Pre-evaluation health check** — `omk doctor` runs as a mandatory gate before `bench run` / `bench gate`; checks skill readability, metadata, dependencies, samples contract — pure static, zero LLM calls (like lint + typecheck for knowledge artifacts). Executor / judge connectivity is a separate phase, controllable via `--skip-connectivity`
|
|
82
|
+
- **Controlled-variable offline bench** — fix the model and samples, vary only the artifact; works with Claude Code skills, CLAUDE.md prompts, RAG knowledge bases, or any markdown-based instruction
|
|
83
|
+
- **Six-dimension scoring** — separate signals for Fact / Behavior / LLM-judge / Cost / Efficiency / Stability, so a regression in one axis isn't hidden by gains in another
|
|
84
|
+
- **Production session observability** — parse Claude Code session JSONL traces, measure per-skill failure rate, latency, token cost, and knowledge-gap signals on real user sessions
|
|
85
|
+
- **Knowledge-gap detection** — severity-weighted signals (explicit markers / failed searches / hedging language / repeated failures) quantify risk exposure instead of claiming completeness
|
|
86
|
+
- **Pre-merge CI gate** — `omk bench gate` enforces three-layer all-pass (fact + behavior + llm-judge) semantics, catching single-layer regressions a composite score would hide
|
|
87
|
+
- **One-line ship/no-ship verdict** — `omk bench verdict <reportId>` aggregates bootstrap CI / three-layer ci-gate / saturation / human α into a six-tier verdict (PROGRESS / CAUTIOUS / REGRESS / NOISE / UNDERPOWERED / SOLO) plus an action recommendation; the exit code reflects whether to ship
|
|
88
|
+
|
|
89
|
+
## Why omk over alternatives
|
|
90
|
+
|
|
91
|
+
| | omk | promptfoo | DeepEval | LangSmith |
|
|
92
|
+
|--|--|--|--|--|
|
|
93
|
+
| Bootstrap CI | ✓ default | ✗ | ✗ | ✗ |
|
|
94
|
+
| Krippendorff α (judge ↔ human) | ✓ default | ✗ | ✗ | ✗ |
|
|
95
|
+
| Length-debias judge prompt | ✓ default | ✗ | ✗ | ✗ |
|
|
96
|
+
| Saturation curve | ✓ | ✗ | ✗ | ✗ |
|
|
97
|
+
| Three-layer scoring isolation | ✓ | ✗ | partial | ✗ |
|
|
98
|
+
| Per-variant skill isolation (construct validity) | ✓ default | ✗ | ✗ | ✗ |
|
|
99
|
+
| Native Claude Code skill | ✓ | ✗ | ✗ | ✗ |
|
|
100
|
+
| Hosted SaaS dashboard | ✗ | ✗ | ✓ | ✓ |
|
|
101
|
+
|
|
102
|
+
omk's moat is **default-on safety net** — Bootstrap CI, judge ↔ human α, and length-debias aren't advanced flags; they're the default. Other tools let you opt into confidence intervals; omk makes them unavoidable. Need a hosted SaaS dashboard? Choose LangSmith. Want quick local prompt iteration without statistics? Choose promptfoo. **Shipping to production and someone will ask "why should I trust this number?" Choose omk.**
|
|
103
|
+
|
|
104
|
+
RAG-specific evals: see RAGAS (separate niche, complementary to omk). Full comparison with 7 tools across 25+ dimensions: [docs/comparison.md](docs/comparison.md).
|
|
91
105
|
|
|
92
106
|
## Features
|
|
93
107
|
|
|
94
108
|
| Feature | What it does |
|
|
95
109
|
|---|---|
|
|
96
|
-
| **21+ assertion types** | substring, regex, JSON Schema, ROUGE/BLEU/Levenshtein similarity, agent tool-call assertions, semantic similarity, custom JS, and more |
|
|
97
|
-
| **Assertion negation + composition** | universal `not: true` field + `assert-set` (any/all) with arbitrary nesting |
|
|
98
|
-
| **Six-dim evaluation** | Fact / Behavior / LLM-judge / Cost / Efficiency / Stability shown independently |
|
|
99
|
-
| **Statistical rigor** | Bootstrap CI / Krippendorff α / length-debias / saturation curve |
|
|
100
|
-
| **Construct-validity isolation** | `--strict-baseline` (default ON) cuts three contamination channels so baseline doesn't silently see the skill it's being compared against: (1) SDK skill auto-discovery, (2) subagent Skill tool, (3) cwd file-system access via the `skills/<name>/` symlink that's normally there for the treatment variant. eval.yaml `allowedSkills` for per-variant whitelists |
|
|
101
|
-
| **Sample design science** | Sample schema with `capability` / `difficulty` / `construct` / `provenance` metadata fields (HF Dataset Cards style). `bench diagnose` shows coverage breakdown + flags `rubric_clarity_low` (short rubric without grading keywords) / `capability_thin` (capability supported by ≤ N×0.2 samples). `bench gen-samples` auto-stamps provenance. See [docs/sample-design-spec.md](docs/sample-design-spec.md) for the 8 industry-gap mapping |
|
|
102
110
|
| **One-line verdict** | `omk bench verdict <id>` six-tier verdict + ship recommendation + exit-code routing; HTML pill shares the same rules |
|
|
103
|
-
| **
|
|
111
|
+
| **Six-dim evaluation** | Fact / Behavior / LLM-judge / Cost / Efficiency / Stability shown independently |
|
|
112
|
+
| **Multi-executor** | Claude CLI / Claude SDK / Codex CLI / Codex SDK / OpenAI / Gemini / any custom command |
|
|
113
|
+
| **21+ assertion types** | substring, regex, JSON Schema, ROUGE/BLEU/Levenshtein similarity, agent tool-call assertions, semantic similarity, custom JS, and more |
|
|
114
|
+
| **Statistical rigor** | Bootstrap CI / Krippendorff α / length-debias / saturation curve — all on by default. [Details →](docs/statistical-rigor.md) |
|
|
104
115
|
| **Sample diagnostics** | `omk bench diagnose <id>` — 7 issue kinds (low discrimination / duplicates / ambiguous rubric / cost outliers / etc.) + 0-100 healthScore |
|
|
105
116
|
| **Failure clustering** | `omk bench failures <id>` — single LLM call clusters failed samples and emits per-cluster fixes |
|
|
117
|
+
| **RAG metrics** | `faithfulness` / `answer_relevancy` / `context_recall` — anti-hallucination + answer relevance + context coverage; auto-inherits length-debias |
|
|
106
118
|
| **Hard budget caps** | `--budget-usd / --budget-per-sample-usd / --budget-per-sample-ms` — abort on total-cost overrun, flag per-sample overruns; partial report persisted |
|
|
107
|
-
| **
|
|
119
|
+
| **Construct-validity isolation** | `--strict-baseline` (default ON) cuts three contamination channels so baseline doesn't silently see the skill it's being compared against: (1) SDK skill auto-discovery, (2) subagent Skill tool, (3) cwd file-system access via the `skills/<name>/` symlink that's normally there for the treatment variant. eval.yaml `allowedSkills` for per-variant whitelists |
|
|
120
|
+
| **Sample design science** | Sample schema with `capability` / `difficulty` / `construct` / `provenance` metadata fields (HF Dataset Cards style). `bench diagnose` shows coverage breakdown + flags `rubric_clarity_low` (short rubric without grading keywords) / `capability_thin` (capability supported by ≤ N×0.2 samples). `bench gen-samples` auto-stamps provenance. See [docs/sample-design-spec.md](docs/sample-design-spec.md) for the 8 industry-gap mapping |
|
|
108
121
|
| **Multi-judge ensemble** | `--judge-models claude:opus,openai:gpt-4o` cross-vendor scoring + agreement metrics |
|
|
109
122
|
| **MCP URL fetching** | pull content from private-doc URLs via an MCP server (SSO-protected knowledge bases, etc.) |
|
|
110
123
|
| **Blind A/B** | `--blind` hides variant names; HTML report has a reveal button |
|
|
111
|
-
| **Parallel execution** | `--concurrency N` runs N tasks at once |
|
|
112
124
|
| **Multi-run variance** | `--repeat N` repeats the eval and computes mean / SD / CI / t-test |
|
|
125
|
+
| **Parallel execution** | `--concurrency N` runs N tasks at once |
|
|
126
|
+
| **Assertion negation + composition** | universal `not: true` field + `assert-set` (any/all) with arbitrary nesting |
|
|
113
127
|
| **Auto analysis** | detects low-discrimination assertions, flat scores, all-pass / all-fail, expensive samples |
|
|
114
128
|
| **Traceability** | reports carry CLI version, Node version, artifact version fingerprint, judge prompt hash |
|
|
115
129
|
| **EN / ZH switch** | one-click language toggle in the HTML report |
|
|
@@ -135,8 +149,8 @@ flowchart TD
|
|
|
135
149
|
end
|
|
136
150
|
|
|
137
151
|
subgraph Exec["④ Executor (fixed model)"]
|
|
138
|
-
E["claude / claude-sdk / openai / gemini<br/>anthropic-api / openai-api / custom"]
|
|
139
|
-
T["claude-sdk
|
|
152
|
+
E["claude / claude-sdk / codex / openai / gemini<br/>anthropic-api / openai-api / custom"]
|
|
153
|
+
T["claude-sdk / codex extract<br/>turns / toolCalls trace"]
|
|
140
154
|
E -.-> T
|
|
141
155
|
end
|
|
142
156
|
|
|
@@ -373,14 +387,16 @@ options:
|
|
|
373
387
|
--control <expr> control-group variant expression (experiment role = control)
|
|
374
388
|
--treatment <v1,v2> treatment-group variant expressions, comma-separated
|
|
375
389
|
at least one of --control / --treatment is required
|
|
376
|
-
(unless you use --config or --
|
|
390
|
+
(unless you use --config or --batch)
|
|
377
391
|
special values: baseline (empty artifact), git:name (git HEAD),
|
|
378
392
|
git:ref:name (specific commit), path with "/" (read file directly)
|
|
379
393
|
--config <path> YAML/JSON config file (evaluation-as-code); declares
|
|
380
394
|
samples + variants + model + executor in one file; CLI
|
|
381
395
|
flags override config fields when both are provided
|
|
382
|
-
--model <name>
|
|
383
|
-
--judge-
|
|
396
|
+
--model <name> task execution model (default: sonnet)
|
|
397
|
+
--judge-models <list> judge config; 1 entry = single judge (default
|
|
398
|
+
claude:haiku), ≥ 2 entries = ensemble. Format:
|
|
399
|
+
`executor:model[,executor:model]`
|
|
384
400
|
--output-dir <path> output dir (default: ~/.oh-my-knowledge/reports/)
|
|
385
401
|
--no-judge skip the LLM judge
|
|
386
402
|
--no-cache disable result cache (on by default; identical inputs reuse)
|
|
@@ -390,16 +406,17 @@ options:
|
|
|
390
406
|
--timeout <sec> per-task executor timeout (default: 120)
|
|
391
407
|
--repeat <n> repeat N times for variance analysis (default: 1)
|
|
392
408
|
--executor <name> executor (default: claude); supports custom commands
|
|
393
|
-
--skip-
|
|
409
|
+
--skip-connectivity skip the LLM connectivity check (doctor still runs;
|
|
410
|
+
doctor is mandatory and has no skip flag).
|
|
411
|
+
Auto-applied on --resume (the original run already
|
|
412
|
+
verified connectivity).
|
|
394
413
|
--mcp-config <path> MCP config for fetching private-doc URLs via MCP Server
|
|
395
414
|
(default: .mcp.json in cwd)
|
|
396
415
|
--no-serve don't auto-start the report server after the run
|
|
397
416
|
--verbose print per-sample details (duration, tokens, output preview)
|
|
398
|
-
--
|
|
417
|
+
--batch batch mode: evaluate each artifact independently vs baseline
|
|
399
418
|
requires {name}.eval-samples.json paired with each artifact
|
|
400
419
|
--judge-repeat <n> run the LLM judge N times per (sample × dimension) and report stddev
|
|
401
|
-
--judge-models <list> multi-judge ensemble: "executor1:model1,executor2:model2"
|
|
402
|
-
≥ 2 judges enables ensemble + inter-judge agreement output
|
|
403
420
|
--bootstrap enable distribution-free CIs: bootstrap CI per variant +
|
|
404
421
|
pairwise diff CI (CI containing 0 = not significant)
|
|
405
422
|
--bootstrap-samples N bootstrap resample count (default 1000)
|
|
@@ -418,11 +435,34 @@ options:
|
|
|
418
435
|
|
|
419
436
|
**eval.yaml budget**: declare `budget: { totalUSD?, perSampleUSD?, perSampleMs? }` (all optional, must be ≥ 0). CLI flags of the same name override the config values.
|
|
420
437
|
|
|
438
|
+
**eval.yaml experiment-design fields**: the same flags above can be set in `eval.yaml` for reproducible experiment configuration (CLI > eval.yaml > default):
|
|
439
|
+
|
|
440
|
+
```yaml
|
|
441
|
+
samples: ./eval-samples.yaml
|
|
442
|
+
model: sonnet
|
|
443
|
+
repeat: 5 # multi-run variance, ≥ 1
|
|
444
|
+
judgeRepeat: 3 # per (sample × dim) judge self-consistency, ≥ 1
|
|
445
|
+
bootstrap: true # distribution-free CI per variant
|
|
446
|
+
bootstrapSamples: 2000 # default 1000, ≥ 100
|
|
447
|
+
goldDir: ./gold # post-run α / κ / Pearson against human anchor
|
|
448
|
+
lengthDebias: true # default; set false to reproduce pre-v0.21 hash
|
|
449
|
+
strictBaseline: true # default; set false to disable skill isolation
|
|
450
|
+
noJudge: false # default; set true to skip LLM judge entirely
|
|
451
|
+
judgeModels: # 1 entry = single judge; ≥ 2 = ensemble
|
|
452
|
+
- { executor: claude, model: opus }
|
|
453
|
+
- { executor: openai-api, model: gpt-4o }
|
|
454
|
+
variants:
|
|
455
|
+
- { name: baseline, role: control, artifact: baseline }
|
|
456
|
+
- { name: my-skill, role: treatment, artifact: ./skills/my-skill.md }
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
**Field entry points**: `bench run` reads every field above. `bench gate` goes through `parseRunConfig` and picks up the shared subset (`variants` / `executor` / `model` / `judgeModels` — both single-judge and ensemble — / `noJudge` / `noCache` / `blind` / `strictBaseline` / `budget` / `mcpConfig` / `variantAllowedSkills`); the experiment-design fields handled by `handleRun` (`repeat` / `judgeRepeat` / `bootstrap` / `bootstrapSamples` / `goldDir` / `lengthDebias`) are intentionally not read by `gate` and can be extended later. Other subcommands (`evolve` / `verdict` / `diff` / `analyze` / …) do not read `eval.yaml`.
|
|
460
|
+
|
|
421
461
|
**Difference from `cost_max` / `latency_max` assertions**: assertions are **per-sample scoring rules** (exceeding the cap fails that one assertion, the run continues); budget caps are **workflow-level hard limits** (`totalUSD` overrun aborts the run and persists a partial report; per-sample overruns fail the offending sample but the run continues). Assertions answer "is quality acceptable?"; budgets answer "are cost/time within the envelope?".
|
|
422
462
|
|
|
423
|
-
### `omk bench run --
|
|
463
|
+
### `omk bench run --batch` (batch mode)
|
|
424
464
|
|
|
425
|
-
When `skills/` contains several **independent** artifacts, use `--
|
|
465
|
+
When `skills/` contains several **independent** artifacts, use `--batch` to evaluate each one against baseline and produce a BatchEvaluationReport with child EvaluationReports.
|
|
426
466
|
|
|
427
467
|
```
|
|
428
468
|
skills/
|
|
@@ -442,8 +482,8 @@ Pairing rules:
|
|
|
442
482
|
- artifacts without paired samples are skipped with a warning
|
|
443
483
|
|
|
444
484
|
```bash
|
|
445
|
-
omk bench run --
|
|
446
|
-
omk bench run --
|
|
485
|
+
omk bench run --batch
|
|
486
|
+
omk bench run --batch --dry-run
|
|
447
487
|
```
|
|
448
488
|
|
|
449
489
|
### `omk bench gen-samples` (generate test cases)
|
|
@@ -455,7 +495,7 @@ Reads an artifact's content and uses an LLM to auto-generate eval-samples. Revie
|
|
|
455
495
|
omk bench gen-samples skills/my-skill.md
|
|
456
496
|
|
|
457
497
|
# batch-generate for every artifact under skills/ that lacks samples
|
|
458
|
-
omk bench gen-samples --
|
|
498
|
+
omk bench gen-samples --batch
|
|
459
499
|
|
|
460
500
|
# specify sample count
|
|
461
501
|
omk bench gen-samples skills/my-skill.md --count 10
|
|
@@ -464,10 +504,10 @@ omk bench gen-samples skills/my-skill.md --count 10
|
|
|
464
504
|
Options:
|
|
465
505
|
|
|
466
506
|
```
|
|
467
|
-
--
|
|
507
|
+
--batch batch-generate for every artifact missing samples
|
|
468
508
|
--count <n> samples per artifact (default: 5)
|
|
469
509
|
--model <name> model used for generation (default: sonnet)
|
|
470
|
-
--skill-dir <path> artifact dir (default: skills), used with --
|
|
510
|
+
--skill-dir <path> artifact dir (default: skills), used with --batch
|
|
471
511
|
```
|
|
472
512
|
|
|
473
513
|
### `omk bench evolve` (self-iterating improvement)
|
|
@@ -505,6 +545,26 @@ omk bench gate [options]
|
|
|
505
545
|
independently to fact / behavior / judge
|
|
506
546
|
```
|
|
507
547
|
|
|
548
|
+
### `omk doctor` (pre-evaluation health check)
|
|
549
|
+
|
|
550
|
+
Pure static / zero-LLM checks — analogous to lint + typecheck in the SE toolchain. Runs as a mandatory gate before `bench run` / `bench gate` so a typo'd YAML or missing dependency aborts with an actionable error instead of producing a garbage-in verdict. Also runnable standalone for local iteration or CI.
|
|
551
|
+
|
|
552
|
+
```bash
|
|
553
|
+
omk doctor # batch check every skill in current dir / ./skills
|
|
554
|
+
omk doctor skills/v1.md # single file
|
|
555
|
+
omk doctor skills/ --json # JSON output for CI consumption
|
|
556
|
+
omk doctor --gate; echo $? # silent mode — exit 1 if any fatal check fails
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
What `doctor` checks:
|
|
560
|
+
|
|
561
|
+
- **skill readable** — file exists, content non-empty, has minimum length
|
|
562
|
+
- **skill metadata** — front-matter (if present) is valid YAML; directory-skills have `SKILL.md`
|
|
563
|
+
- **dependencies present** — referenced CLI tools, files, env vars all available (reuses `preflightDependencies`)
|
|
564
|
+
- **samples ↔ skill contract** — when samples are provided, validate they're non-empty and have prompt fields (warn-level)
|
|
565
|
+
|
|
566
|
+
Executor / judge connectivity is verified by a separate evaluation preflight phase, not by doctor — clean boundary: doctor is static, eval is dynamic. `bench run` / `bench gate` abort with `exit 1` and stderr `doctor failed:` prefix when doctor fails. **Doctor is mandatory and not skippable** (static checks have no cost reason to skip); LLM connectivity is separately controllable via `--skip-connectivity` (auto-skipped on `--resume`).
|
|
567
|
+
|
|
508
568
|
### `omk bench report`
|
|
509
569
|
|
|
510
570
|
Start the report server to browse historical reports, submit feedback, and delete reports.
|
|
@@ -549,7 +609,7 @@ Re-judges every (sample × variant) of an existing report with the OPPOSITE leng
|
|
|
549
609
|
```bash
|
|
550
610
|
omk bench debias-validate length <reportId> [options]
|
|
551
611
|
--variant <name> check a single variant only
|
|
552
|
-
--judge-
|
|
612
|
+
--judge-models <executor:model> override the report's judge (single-judge only)
|
|
553
613
|
--bootstrap-samples N bootstrap iterations (default 1000)
|
|
554
614
|
--seed N deterministic seed
|
|
555
615
|
```
|
|
@@ -605,8 +665,7 @@ When 14 of 50 samples failed, reading them one by one is slow. This command send
|
|
|
605
665
|
|
|
606
666
|
```bash
|
|
607
667
|
omk bench failures <reportId> [options]
|
|
608
|
-
--judge-
|
|
609
|
-
--judge-model <id> clustering model (default: from report.meta.judgeModel)
|
|
668
|
+
--judge-models <executor:model> clustering judge (default: from report.meta.judgeModels[0]; single-judge only)
|
|
610
669
|
--max-clusters <n> maximum clusters (default 5)
|
|
611
670
|
--threshold <num> failure score threshold (default 3)
|
|
612
671
|
--max-feed <n> max failures fed to LLM (default 50; takes the worst)
|
|
@@ -671,13 +730,16 @@ The command writes `~/.oh-my-knowledge/analyses/<timestamp>-skill-health.json`.
|
|
|
671
730
|
|---|---|---|
|
|
672
731
|
| `claude` | default | invokes `claude -p` via Claude CLI |
|
|
673
732
|
| `claude-sdk` | structured output | uses Claude Agent SDK — no stdout parsing, avoids buffer truncation |
|
|
674
|
-
| `
|
|
733
|
+
| `codex` | OpenAI agent CLI | invokes `codex exec --json` (`@openai/codex` npm); best-effort tool trace; **costUSD not reported** (codex CLI does not emit USD; check usage externally) |
|
|
734
|
+
| `codex-sdk` | OpenAI agent SDK | uses `@openai/codex-sdk` with its bundled `@openai/codex` binary and streamed SDK events; **costUSD not reported** |
|
|
675
735
|
| `gemini` | cross-vendor comparison | invokes `gemini` CLI |
|
|
676
736
|
| `anthropic-api` | no CLI needed | calls Anthropic HTTP API directly (needs `ANTHROPIC_API_KEY`) |
|
|
677
737
|
| `openai-api` | no CLI needed | calls OpenAI HTTP API directly (needs `OPENAI_API_KEY`) |
|
|
678
738
|
|
|
679
739
|
API-direct executors support custom base URLs via env: `ANTHROPIC_BASE_URL`, `OPENAI_BASE_URL`.
|
|
680
740
|
|
|
741
|
+
Codex construct-validity notes: (1) `codex` uses the `codex` binary on `PATH`; `codex-sdk` uses the bundled `@openai/codex` binary resolved by `@openai/codex-sdk`. Reports persist per-variant `meta.executorRuntimes`, `meta.executorRuntime`, and per-judge `meta.judgeModels[].runtime` fingerprints (binary or SDK version + capability snapshot), and `bench diff` / `bench verdict` warn when strict comparability cannot be audited. If runtime fingerprints differ, treat results as an executor-runtime comparison, not only prompt/template behavior. (2) Both executors isolate user-level config: `codex` passes `--ephemeral` + `--ignore-user-config`; `codex-sdk` redirects `$CODEX_HOME` to a per-process tmp dir (auth.json symlinked through). User-level `~/.codex/config.toml` does not leak into eval runs in either case.
|
|
742
|
+
|
|
681
743
|
### Custom executor
|
|
682
744
|
|
|
683
745
|
Any shell command can serve as an executor, communicating via stdin/stdout JSON:
|
|
@@ -721,7 +783,7 @@ skills/
|
|
|
721
783
|
| `./path/to/file.md` | path with `/`: read the file directly as an artifact |
|
|
722
784
|
| `variant@/path/to/project` | attach a run dir to any variant; supports `name@cwd`, `git:name@cwd`, `/file.md@cwd` |
|
|
723
785
|
|
|
724
|
-
When both `--control` and `--treatment` are omitted, use `--config eval.yaml` or `--
|
|
786
|
+
When both `--control` and `--treatment` are omitted, use `--config eval.yaml` or `--batch`. With `--batch`, `baseline` is auto-added as control and every discovered artifact becomes a treatment.
|
|
725
787
|
|
|
726
788
|
```bash
|
|
727
789
|
# explicit: one control, one or more treatments
|
|
@@ -862,25 +924,25 @@ omk bench run \
|
|
|
862
924
|
export OPENAI_API_KEY="your Zhipu API key"
|
|
863
925
|
export OPENAI_BASE_URL="https://open.bigmodel.cn/api/paas/v4"
|
|
864
926
|
omk bench run --executor openai-api --model glm-4-plus \
|
|
865
|
-
--judge-
|
|
927
|
+
--judge-models openai-api:glm-4-plus --no-cache
|
|
866
928
|
|
|
867
929
|
# Qwen (Alibaba)
|
|
868
930
|
export OPENAI_API_KEY="your Qwen API key"
|
|
869
931
|
export OPENAI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|
870
932
|
omk bench run --executor openai-api --model qwen-plus \
|
|
871
|
-
--judge-
|
|
933
|
+
--judge-models openai-api:qwen-plus
|
|
872
934
|
|
|
873
935
|
# DeepSeek
|
|
874
936
|
export OPENAI_API_KEY="your DeepSeek API key"
|
|
875
937
|
export OPENAI_BASE_URL="https://api.deepseek.com"
|
|
876
938
|
omk bench run --executor openai-api --model deepseek-chat \
|
|
877
|
-
--judge-
|
|
939
|
+
--judge-models openai-api:deepseek-chat
|
|
878
940
|
|
|
879
941
|
# Moonshot (Kimi)
|
|
880
942
|
export OPENAI_API_KEY="your Moonshot API key"
|
|
881
943
|
export OPENAI_BASE_URL="https://api.moonshot.cn/v1"
|
|
882
944
|
omk bench run --executor openai-api --model moonshot-v1-8k \
|
|
883
|
-
--judge-
|
|
945
|
+
--judge-models openai-api:moonshot-v1-8k
|
|
884
946
|
```
|
|
885
947
|
|
|
886
948
|
**Ollama local model:**
|
|
@@ -890,11 +952,11 @@ omk bench run --executor "python examples/custom-executor/ollama-executor.py" \
|
|
|
890
952
|
--model llama3 --no-judge
|
|
891
953
|
```
|
|
892
954
|
|
|
893
|
-
**About the judge
|
|
955
|
+
**About the judge:**
|
|
894
956
|
|
|
895
|
-
- `--judge-
|
|
896
|
-
-
|
|
897
|
-
- If you don't have Claude, point `--judge-
|
|
957
|
+
- `--judge-models <list>` picks the LLM judge(s). Format: `executor:model[,executor:model]`. Default: `${executor}:haiku` (or claude:haiku when no `--executor` set)
|
|
958
|
+
- 1 entry = single judge; ≥ 2 entries = multi-judge ensemble + inter-judge agreement
|
|
959
|
+
- If you don't have Claude, point `--judge-models` at whatever you have, e.g. `--judge-models openai-api:glm-4-plus`
|
|
898
960
|
- Add `--no-judge` to skip the LLM judge and rely on assertions alone
|
|
899
961
|
|
|
900
962
|
## Environment variables
|
|
@@ -927,4 +989,4 @@ This tool is designed for **local trusted environments** (dev machines, CI pipel
|
|
|
927
989
|
|
|
928
990
|
---
|
|
929
991
|
|
|
930
|
-
See [
|
|
992
|
+
See [GitHub Releases](https://github.com/lizhiyao/oh-my-knowledge/releases) for release notes. Contributions welcome — see [CONTRIBUTING](./CONTRIBUTING.md).
|