oh-my-knowledge 0.24.0 → 0.25.1
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 +85 -22
- package/README.zh.md +82 -22
- package/dist/src/analysis/saturation.d.ts +2 -2
- package/dist/src/analysis/saturation.js +2 -2
- package/dist/src/authoring/evolver.d.ts +7 -4
- package/dist/src/authoring/evolver.d.ts.map +1 -1
- package/dist/src/authoring/evolver.js +15 -7
- 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 +213 -40
- package/dist/src/cli/i18n-dict.js.map +1 -1
- package/dist/src/cli/index.js +188 -87
- 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 +76 -21
- 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/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/comparability.d.ts.map +1 -1
- package/dist/src/eval-core/comparability.js +82 -57
- package/dist/src/eval-core/comparability.js.map +1 -1
- 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 +20 -7
- package/dist/src/eval-core/evaluation-execution.d.ts.map +1 -1
- package/dist/src/eval-core/evaluation-execution.js +29 -5
- package/dist/src/eval-core/evaluation-execution.js.map +1 -1
- package/dist/src/eval-core/evaluation-job.d.ts +2 -4
- package/dist/src/eval-core/evaluation-job.d.ts.map +1 -1
- package/dist/src/eval-core/evaluation-job.js +1 -3
- package/dist/src/eval-core/evaluation-job.js.map +1 -1
- package/dist/src/eval-core/evaluation-reporting.d.ts.map +1 -1
- package/dist/src/eval-core/evaluation-reporting.js +12 -14
- package/dist/src/eval-core/evaluation-reporting.js.map +1 -1
- package/dist/src/eval-core/schema.d.ts.map +1 -1
- package/dist/src/eval-core/schema.js +7 -2
- package/dist/src/eval-core/schema.js.map +1 -1
- package/dist/src/eval-workflows/batch-evaluation-workflow.d.ts +6 -4
- package/dist/src/eval-workflows/batch-evaluation-workflow.d.ts.map +1 -1
- package/dist/src/eval-workflows/batch-evaluation-workflow.js +14 -12
- package/dist/src/eval-workflows/batch-evaluation-workflow.js.map +1 -1
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts +2 -2
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts.map +1 -1
- package/dist/src/eval-workflows/evaluation-pipeline.js +39 -34
- package/dist/src/eval-workflows/evaluation-pipeline.js.map +1 -1
- package/dist/src/eval-workflows/evaluation-preparation.d.ts +5 -20
- package/dist/src/eval-workflows/evaluation-preparation.d.ts.map +1 -1
- package/dist/src/eval-workflows/evaluation-preparation.js +2 -21
- package/dist/src/eval-workflows/evaluation-preparation.js.map +1 -1
- package/dist/src/eval-workflows/run-evaluation.d.ts +11 -10
- package/dist/src/eval-workflows/run-evaluation.d.ts.map +1 -1
- package/dist/src/eval-workflows/run-evaluation.js +123 -16
- package/dist/src/eval-workflows/run-evaluation.js.map +1 -1
- package/dist/src/grading/assertions.js +4 -4
- 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 +29 -16
- package/dist/src/grading/index.js.map +1 -1
- package/dist/src/grading/judge.d.ts +1 -1
- package/dist/src/grading/judge.js +1 -1
- package/dist/src/inputs/eval-config.js +65 -7
- package/dist/src/inputs/eval-config.js.map +1 -1
- package/dist/src/renderer/html-renderer.d.ts.map +1 -1
- package/dist/src/renderer/html-renderer.js +32 -12
- package/dist/src/renderer/html-renderer.js.map +1 -1
- package/dist/src/renderer/summary.js +1 -1
- package/dist/src/renderer/summary.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 +36 -17
- package/dist/src/types/eval.d.ts.map +1 -1
- package/dist/src/types/executor.d.ts +33 -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 +11 -0
- package/dist/src/types/judge.d.ts.map +1 -1
- package/dist/src/types/report.d.ts +21 -52
- package/dist/src/types/report.d.ts.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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)
|
|
@@ -10,7 +11,7 @@
|
|
|
10
11
|
**omk** — The knowledge you give your LLM — what's it actually worth?
|
|
11
12
|
omk answers with objective data, not gut feeling.
|
|
12
13
|
|
|
13
|
-
**Fix the model, vary the
|
|
14
|
+
**Evaluation framework for LLM knowledge inputs** — prompts, RAG corpora, skills, agent workflows. Fix the model, vary the artifact.
|
|
14
15
|
|
|
15
16
|
<a id="statistical-rigor"></a>
|
|
16
17
|
> Built-in: Bootstrap CI · Krippendorff α (judge ↔ human) · length-debias · saturation curves · construct-validity isolation. [Why these matter →](docs/statistical-rigor.md)
|
|
@@ -37,23 +38,39 @@ omk bench run --dry-run
|
|
|
37
38
|
|
|
38
39
|
# run the evaluation (auto-discovers everything under skills/)
|
|
39
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)
|
|
40
43
|
|
|
41
44
|
# CLI output language: zh (default) / en — flag wins over env
|
|
42
45
|
omk bench run --lang en
|
|
43
46
|
OMK_LANG=en omk bench report
|
|
44
47
|
```
|
|
45
48
|
|
|
46
|
-
## Use inside
|
|
49
|
+
## Use inside AI Coding Agents
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
### Use inside Claude Code
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
When the `omk` skill is available in Claude Code, you can invoke it directly like this:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
51
56
|
/omk eval # evaluate the artifact(s) in the current project
|
|
52
57
|
/omk evolve # auto-iterate to improve an artifact
|
|
53
58
|
/omk gen-samples # generate test cases
|
|
54
59
|
```
|
|
55
60
|
|
|
56
|
-
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".
|
|
57
74
|
|
|
58
75
|
## Why this tool
|
|
59
76
|
|
|
@@ -61,6 +78,7 @@ Teams doing knowledge engineering produce lots of knowledge artifacts (skills to
|
|
|
61
78
|
|
|
62
79
|
## Key features
|
|
63
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`
|
|
64
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
|
|
65
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
|
|
66
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
|
|
@@ -376,7 +394,9 @@ options:
|
|
|
376
394
|
samples + variants + model + executor in one file; CLI
|
|
377
395
|
flags override config fields when both are provided
|
|
378
396
|
--model <name> task execution model (default: sonnet)
|
|
379
|
-
--judge-
|
|
397
|
+
--judge-models <list> judge config; 1 entry = single judge (default
|
|
398
|
+
claude:haiku), ≥ 2 entries = ensemble. Format:
|
|
399
|
+
`executor:model[,executor:model]`
|
|
380
400
|
--output-dir <path> output dir (default: ~/.oh-my-knowledge/reports/)
|
|
381
401
|
--no-judge skip the LLM judge
|
|
382
402
|
--no-cache disable result cache (on by default; identical inputs reuse)
|
|
@@ -386,7 +406,10 @@ options:
|
|
|
386
406
|
--timeout <sec> per-task executor timeout (default: 120)
|
|
387
407
|
--repeat <n> repeat N times for variance analysis (default: 1)
|
|
388
408
|
--executor <name> executor (default: claude); supports custom commands
|
|
389
|
-
--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).
|
|
390
413
|
--mcp-config <path> MCP config for fetching private-doc URLs via MCP Server
|
|
391
414
|
(default: .mcp.json in cwd)
|
|
392
415
|
--no-serve don't auto-start the report server after the run
|
|
@@ -394,8 +417,6 @@ options:
|
|
|
394
417
|
--batch batch mode: evaluate each artifact independently vs baseline
|
|
395
418
|
requires {name}.eval-samples.json paired with each artifact
|
|
396
419
|
--judge-repeat <n> run the LLM judge N times per (sample × dimension) and report stddev
|
|
397
|
-
--judge-models <list> multi-judge ensemble: "executor1:model1,executor2:model2"
|
|
398
|
-
≥ 2 judges enables ensemble + inter-judge agreement output
|
|
399
420
|
--bootstrap enable distribution-free CIs: bootstrap CI per variant +
|
|
400
421
|
pairwise diff CI (CI containing 0 = not significant)
|
|
401
422
|
--bootstrap-samples N bootstrap resample count (default 1000)
|
|
@@ -414,6 +435,29 @@ options:
|
|
|
414
435
|
|
|
415
436
|
**eval.yaml budget**: declare `budget: { totalUSD?, perSampleUSD?, perSampleMs? }` (all optional, must be ≥ 0). CLI flags of the same name override the config values.
|
|
416
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
|
+
|
|
417
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?".
|
|
418
462
|
|
|
419
463
|
### `omk bench run --batch` (batch mode)
|
|
@@ -501,6 +545,26 @@ omk bench gate [options]
|
|
|
501
545
|
independently to fact / behavior / judge
|
|
502
546
|
```
|
|
503
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
|
+
|
|
504
568
|
### `omk bench report`
|
|
505
569
|
|
|
506
570
|
Start the report server to browse historical reports, submit feedback, and delete reports.
|
|
@@ -545,7 +609,7 @@ Re-judges every (sample × variant) of an existing report with the OPPOSITE leng
|
|
|
545
609
|
```bash
|
|
546
610
|
omk bench debias-validate length <reportId> [options]
|
|
547
611
|
--variant <name> check a single variant only
|
|
548
|
-
--judge-
|
|
612
|
+
--judge-models <executor:model> override the report's judge (single-judge only)
|
|
549
613
|
--bootstrap-samples N bootstrap iterations (default 1000)
|
|
550
614
|
--seed N deterministic seed
|
|
551
615
|
```
|
|
@@ -601,8 +665,7 @@ When 14 of 50 samples failed, reading them one by one is slow. This command send
|
|
|
601
665
|
|
|
602
666
|
```bash
|
|
603
667
|
omk bench failures <reportId> [options]
|
|
604
|
-
--judge-
|
|
605
|
-
--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)
|
|
606
669
|
--max-clusters <n> maximum clusters (default 5)
|
|
607
670
|
--threshold <num> failure score threshold (default 3)
|
|
608
671
|
--max-feed <n> max failures fed to LLM (default 50; takes the worst)
|
|
@@ -675,7 +738,7 @@ The command writes `~/.oh-my-knowledge/analyses/<timestamp>-skill-health.json`.
|
|
|
675
738
|
|
|
676
739
|
API-direct executors support custom base URLs via env: `ANTHROPIC_BASE_URL`, `OPENAI_BASE_URL`.
|
|
677
740
|
|
|
678
|
-
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
|
|
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.
|
|
679
742
|
|
|
680
743
|
### Custom executor
|
|
681
744
|
|
|
@@ -861,25 +924,25 @@ omk bench run \
|
|
|
861
924
|
export OPENAI_API_KEY="your Zhipu API key"
|
|
862
925
|
export OPENAI_BASE_URL="https://open.bigmodel.cn/api/paas/v4"
|
|
863
926
|
omk bench run --executor openai-api --model glm-4-plus \
|
|
864
|
-
--judge-
|
|
927
|
+
--judge-models openai-api:glm-4-plus --no-cache
|
|
865
928
|
|
|
866
929
|
# Qwen (Alibaba)
|
|
867
930
|
export OPENAI_API_KEY="your Qwen API key"
|
|
868
931
|
export OPENAI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|
869
932
|
omk bench run --executor openai-api --model qwen-plus \
|
|
870
|
-
--judge-
|
|
933
|
+
--judge-models openai-api:qwen-plus
|
|
871
934
|
|
|
872
935
|
# DeepSeek
|
|
873
936
|
export OPENAI_API_KEY="your DeepSeek API key"
|
|
874
937
|
export OPENAI_BASE_URL="https://api.deepseek.com"
|
|
875
938
|
omk bench run --executor openai-api --model deepseek-chat \
|
|
876
|
-
--judge-
|
|
939
|
+
--judge-models openai-api:deepseek-chat
|
|
877
940
|
|
|
878
941
|
# Moonshot (Kimi)
|
|
879
942
|
export OPENAI_API_KEY="your Moonshot API key"
|
|
880
943
|
export OPENAI_BASE_URL="https://api.moonshot.cn/v1"
|
|
881
944
|
omk bench run --executor openai-api --model moonshot-v1-8k \
|
|
882
|
-
--judge-
|
|
945
|
+
--judge-models openai-api:moonshot-v1-8k
|
|
883
946
|
```
|
|
884
947
|
|
|
885
948
|
**Ollama local model:**
|
|
@@ -889,11 +952,11 @@ omk bench run --executor "python examples/custom-executor/ollama-executor.py" \
|
|
|
889
952
|
--model llama3 --no-judge
|
|
890
953
|
```
|
|
891
954
|
|
|
892
|
-
**About the judge
|
|
955
|
+
**About the judge:**
|
|
893
956
|
|
|
894
|
-
- `--judge-
|
|
895
|
-
-
|
|
896
|
-
- 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`
|
|
897
960
|
- Add `--no-judge` to skip the LLM judge and rely on assertions alone
|
|
898
961
|
|
|
899
962
|
## Environment variables
|
|
@@ -926,4 +989,4 @@ This tool is designed for **local trusted environments** (dev machines, CI pipel
|
|
|
926
989
|
|
|
927
990
|
---
|
|
928
991
|
|
|
929
|
-
See [
|
|
992
|
+
See [GitHub Releases](https://github.com/lizhiyao/oh-my-knowledge/releases) for release notes. Contributions welcome — see [CONTRIBUTING](./CONTRIBUTING.md).
|
package/README.zh.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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)
|
|
@@ -10,7 +11,7 @@
|
|
|
10
11
|
**omk** — 你给 LLM 的知识,价值在哪里?
|
|
11
12
|
omk 帮你用客观数据回答,而不是凭感觉。
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
**面向 LLM 知识输入(prompt / RAG / skill / agent)的评测框架** —— 固定模型,只变知识载体。
|
|
14
15
|
|
|
15
16
|
<a id="statistical-rigor"></a>
|
|
16
17
|
> 默认带:Bootstrap 置信区间 · Krippendorff α(评委 ↔ 人工)· 长度去偏 · 饱和曲线 · 用例隔离(construct validity)。[这些为什么重要 →](docs/zh/statistical-rigor.md)
|
|
@@ -37,17 +38,21 @@ omk bench run --dry-run
|
|
|
37
38
|
|
|
38
39
|
# 运行评测(自动发现 skills/ 目录下的所有 artifact)
|
|
39
40
|
omk bench run # → 5 分钟出 HTML 报告 + verdict
|
|
41
|
+
# (omk doctor 和 LLM 连通性检测都是强制前置门禁;
|
|
42
|
+
# --skip-connectivity 可跳连通性,doctor 无 skip flag)
|
|
40
43
|
|
|
41
44
|
# CLI 输出语言: zh (默认) / en — flag 优先级高于环境变量
|
|
42
45
|
omk bench run --lang en
|
|
43
46
|
OMK_LANG=en omk bench report
|
|
44
47
|
```
|
|
45
48
|
|
|
46
|
-
## 在
|
|
49
|
+
## 在 AI Coding Agent 中使用
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
### 在 Claude Code 中使用
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
当 `omk` skill 已在 Claude Code 中可用时,可以直接这样调用:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
51
56
|
/omk eval # 评测当前项目的 artifact
|
|
52
57
|
/omk evolve # 自动迭代改进 artifact
|
|
53
58
|
/omk gen-samples # 生成测试用例
|
|
@@ -55,12 +60,25 @@ OMK_LANG=en omk bench report
|
|
|
55
60
|
|
|
56
61
|
或直接说"帮我评测 v1 和 v2 的差异"、"改进一下这个 artifact",omk 会自动理解意图并调用对应命令。
|
|
57
62
|
|
|
63
|
+
### 在 Codex 中使用
|
|
64
|
+
|
|
65
|
+
Codex 默认不支持 `/omk ...` 这种 Claude Code 风格的 slash command。通常直接让 agent 执行 `omk` CLI,例如:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
omk bench run
|
|
69
|
+
omk bench evolve
|
|
70
|
+
omk bench gen-samples skills/my-skill.md
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
也可以直接用自然语言描述目标,例如"比较 v1 和 v2 的评测差异"、"为这个 skill 生成测试用例"。
|
|
74
|
+
|
|
58
75
|
## 为什么需要这个工具
|
|
59
76
|
|
|
60
77
|
做知识工程的团队会产出大量知识载体(当前常见是 skill,也包括 prompt、agent、workflow 等)。当被问到"v2 比 v1 好在哪"时,需要客观数据而非主观判断。`oh-my-knowledge` 通过控制变量实验解决这个问题:相同模型、相同测试用例,只改变知识载体。
|
|
61
78
|
|
|
62
79
|
## 核心能力
|
|
63
80
|
|
|
81
|
+
- **评测前置健康检查** — `omk doctor` 在 `bench run` / `bench gate` 之前**强制**运行,检查 skill 可读性、元数据合法性、依赖完整性、samples 契约——纯静态零 LLM 调用,类比 SE 工具栈的 lint + typecheck。executor / judge 连通性是独立阶段,可用 `--skip-connectivity` 单独跳过
|
|
64
82
|
- **控制变量离线评测** — 固定模型和用例,只变知识载体;兼容 Claude Code skill、CLAUDE.md prompt、RAG 知识库等任何 markdown 形式的指令
|
|
65
83
|
- **六维独立打分** — Fact / Behavior / LLM-judge / Cost / Efficiency / Stability 分别出信号,单一维度的回退不会被其他维度的收益掩盖
|
|
66
84
|
- **线上 session 观测** — 解析 Claude Code session JSONL,在真实用户会话上测量各 skill 的失败率、耗时、token 成本和知识缺口信号
|
|
@@ -374,7 +392,8 @@ omk bench run [选项]
|
|
|
374
392
|
--config <路径> YAML/JSON 配置文件(evaluation-as-code);在一个文件里声明
|
|
375
393
|
samples + variants + model + executor;CLI 参数会覆盖 config
|
|
376
394
|
--model <名称> 被测模型(默认:sonnet)
|
|
377
|
-
--judge-
|
|
395
|
+
--judge-models <list> 评委配置;1 条 = 单评委 (默认 claude:haiku),
|
|
396
|
+
≥ 2 条 = ensemble。格式 `executor:model[,executor:model]`
|
|
378
397
|
--output-dir <路径> 输出目录(默认:~/.oh-my-knowledge/reports/)
|
|
379
398
|
--no-judge 跳过 LLM 评分
|
|
380
399
|
--no-cache 禁用结果缓存(默认开启,相同输入自动复用)
|
|
@@ -384,7 +403,8 @@ omk bench run [选项]
|
|
|
384
403
|
--timeout <秒> 单个任务的执行器超时时间(默认:120)
|
|
385
404
|
--repeat <n> 重复 N 次做方差分析(默认:1)
|
|
386
405
|
--executor <名称> 执行器(默认:claude),支持自定义命令
|
|
387
|
-
--skip-
|
|
406
|
+
--skip-connectivity 跳过评测前 LLM 连通性检测(doctor 仍然强制执行,无 skip flag)。
|
|
407
|
+
--resume 时自动跳过(原 run 已验过连通性)。
|
|
388
408
|
--mcp-config <路径> MCP 配置文件,用于通过 MCP Server 获取私有文档 URL 内容
|
|
389
409
|
(默认:当前目录的 .mcp.json)
|
|
390
410
|
--no-serve 评测完成后不自动启动报告服务
|
|
@@ -392,8 +412,6 @@ omk bench run [选项]
|
|
|
392
412
|
--batch 批量评测:每个 artifact 独立和 baseline 对比
|
|
393
413
|
需要每个 artifact 配对 {name}.eval-samples.json
|
|
394
414
|
--judge-repeat <n> 每条 sample × dimension 跑 LLM 评委 N 次,输出 stddev (评委自一致性)
|
|
395
|
-
--judge-models <list> 多评委 ensemble: "executor1:model1,executor2:model2"
|
|
396
|
-
≥ 2 个 judge 触发 ensemble + inter-judge agreement 输出
|
|
397
415
|
--bootstrap 启用 distribution-free CI:每个 variant 加 bootstrap CI,
|
|
398
416
|
pairwise diff CI 含 0 = 不显著
|
|
399
417
|
--bootstrap-samples N bootstrap 重采样次数 (默认 1000)
|
|
@@ -409,6 +427,29 @@ omk bench run [选项]
|
|
|
409
427
|
|
|
410
428
|
**eval.yaml 预算字段**: `budget: { totalUSD?, perSampleUSD?, perSampleMs? }`,所有字段可选且必须 ≥ 0。CLI 同名 flag 覆盖配置值。
|
|
411
429
|
|
|
430
|
+
**eval.yaml 实验设计字段**: 上面 CLI flag 同样可以写到 `eval.yaml` 让实验配置可复现 (CLI > eval.yaml > 默认):
|
|
431
|
+
|
|
432
|
+
```yaml
|
|
433
|
+
samples: ./eval-samples.yaml
|
|
434
|
+
model: sonnet
|
|
435
|
+
repeat: 5 # 多轮方差分析, ≥ 1
|
|
436
|
+
judgeRepeat: 3 # 每条 (sample × dim) 评委自一致性次数, ≥ 1
|
|
437
|
+
bootstrap: true # 每 variant distribution-free CI
|
|
438
|
+
bootstrapSamples: 2000 # 默认 1000, ≥ 100
|
|
439
|
+
goldDir: ./gold # 跑完自动对比 human anchor 算 α / κ / Pearson
|
|
440
|
+
lengthDebias: true # 默认; 设 false 复现 v0.21 之前的 hash
|
|
441
|
+
strictBaseline: true # 默认; 设 false 关掉 skill 隔离
|
|
442
|
+
noJudge: false # 默认; 设 true 完全跳过 LLM 评委
|
|
443
|
+
judgeModels: # 1 条 = 单评委; ≥ 2 条 = ensemble
|
|
444
|
+
- { executor: claude, model: opus }
|
|
445
|
+
- { executor: openai-api, model: gpt-4o }
|
|
446
|
+
variants:
|
|
447
|
+
- { name: baseline, role: control, artifact: baseline }
|
|
448
|
+
- { name: my-skill, role: treatment, artifact: ./skills/my-skill.md }
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**字段入口**: `bench run` 完整支持上述全部字段; `bench gate` 通过 `parseRunConfig` 共享 variants / executor / model / `judgeModels`(单评委 + ensemble 都生效)/ noJudge / noCache / blind / strictBaseline / budget / mcpConfig / variantAllowedSkills,但 `handleRun` 自己处理的实验设计字段(`repeat` / `judgeRepeat` / `bootstrap` / `bootstrapSamples` / `goldDir` / `lengthDebias`)gate 不读,后续按需扩展到 gate。其他子命令(`evolve` / `verdict` / `diff` / `analyze` 等)完全不读 eval.yaml。
|
|
452
|
+
|
|
412
453
|
**和 `cost_max` / `latency_max` 断言的区别**: 断言是**单样本评分维度**(超出直接打 0 分,run 继续);budget 是**工作流级硬阈值**(`totalUSD` 超出整个 run abort 保留 partial report,per-sample 超出该样本失败但 run 继续)。一个回答"质量是否达标",一个回答"花钱/时间是否在预算内"。
|
|
413
454
|
|
|
414
455
|
### `omk bench run --batch`(批量评测)
|
|
@@ -496,6 +537,26 @@ omk bench gate [选项]
|
|
|
496
537
|
fact / behavior / judge 三层
|
|
497
538
|
```
|
|
498
539
|
|
|
540
|
+
### `omk doctor`(评测前置健康检查)
|
|
541
|
+
|
|
542
|
+
纯静态 / 零 LLM 调用,类比 SE 工具栈的 lint + typecheck。`bench run` / `bench gate` 之前强制运行,YAML 写错、依赖缺失这类问题会 abort 评测并给可操作错误,而不是让你拿到 garbage-in 的 verdict 数字。也可独立调用,适合本地迭代或 CI 单跑。
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
omk doctor # 批量检查当前目录或 ./skills 下所有 skill
|
|
546
|
+
omk doctor skills/v1.md # 单个文件
|
|
547
|
+
omk doctor skills/ --json # JSON 输出供 CI 消费
|
|
548
|
+
omk doctor --gate; echo $? # 静默模式 — 任意 fatal 失败 exit 1
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
doctor 检查项:
|
|
552
|
+
|
|
553
|
+
- **skill 文件可读** — 文件存在、内容非空、有最低长度
|
|
554
|
+
- **skill 元数据合法** — front-matter(若有)YAML 合法;directory-skill 有 `SKILL.md`
|
|
555
|
+
- **前置依赖完整** — 引用的 CLI 工具、文件、环境变量都可用(复用 `preflightDependencies`)
|
|
556
|
+
- **用例 ↔ skill 输入约定** — 传 samples 时校验非空且含 prompt 字段(warn 级)
|
|
557
|
+
|
|
558
|
+
executor / judge 连通性由独立的 evaluation preflight 阶段负责,不在 doctor 范围内 — 边界清晰:doctor 静态,eval 动态。`bench run` / `bench gate` 在 doctor 失败时 abort(exit 1,stderr 前缀 `doctor failed:`)。**doctor 是评测必经环节,无 skip flag**(静态检查零成本无理由跳过);LLM 连通性可用 `--skip-connectivity` 单独控制(`--resume` 时自动跳过)。
|
|
559
|
+
|
|
499
560
|
### `omk bench report`
|
|
500
561
|
|
|
501
562
|
启动报告服务,浏览历史报告、提交反馈、删除报告。
|
|
@@ -540,7 +601,7 @@ gold-dir/
|
|
|
540
601
|
```bash
|
|
541
602
|
omk bench debias-validate length <reportId> [选项]
|
|
542
603
|
--variant <name> 只测一个 variant
|
|
543
|
-
--judge-
|
|
604
|
+
--judge-models <executor:model> override report 的评委(仅支持单评委)
|
|
544
605
|
--bootstrap-samples N bootstrap 迭代数 (默认 1000)
|
|
545
606
|
--seed N 确定性种子
|
|
546
607
|
```
|
|
@@ -596,8 +657,7 @@ omk bench diagnose <reportId> [选项]
|
|
|
596
657
|
|
|
597
658
|
```bash
|
|
598
659
|
omk bench failures <reportId> [选项]
|
|
599
|
-
--judge-
|
|
600
|
-
--judge-model <id> 聚类用 model (默认沿用 report.meta.judgeModel)
|
|
660
|
+
--judge-models <executor:model> 聚类评委 (默认沿用 report.meta.judgeModels[0],仅支持单评委)
|
|
601
661
|
--max-clusters <n> 最多多少 cluster (默认 5)
|
|
602
662
|
--threshold <num> 算失败的分数阈值 (默认 3)
|
|
603
663
|
--max-feed <n> 最多喂给 LLM 多少条 (默认 50,超出取最差)
|
|
@@ -670,7 +730,7 @@ omk analyze ~/.claude/projects/my-project --kb /path/to/project
|
|
|
670
730
|
|
|
671
731
|
API 直调执行器支持通过环境变量自定义 Base URL:`ANTHROPIC_BASE_URL`、`OPENAI_BASE_URL`。
|
|
672
732
|
|
|
673
|
-
Codex construct-validity 说明:(1) `codex` 使用 `PATH` 上找到的 `codex` binary;`codex-sdk` 使用 `@openai/codex-sdk` 解析到的自带 `@openai/codex` binary。报告会持久化 per-variant `meta.executorRuntimes
|
|
733
|
+
Codex construct-validity 说明:(1) `codex` 使用 `PATH` 上找到的 `codex` binary;`codex-sdk` 使用 `@openai/codex-sdk` 解析到的自带 `@openai/codex` binary。报告会持久化 per-variant `meta.executorRuntimes`、`meta.executorRuntime`,以及每个评委的 `meta.judgeModels[].runtime` 指纹(binary 或 SDK 版本 + 能力快照),`bench diff` / `bench verdict` 会在 strict comparability 无法审计时提示。runtime 指纹不一致时,结果应解释为 executor runtime 对比,而不只是 prompt/template 行为对比。(2) 两个 executor 都隔离用户级 config:`codex` 传 `--ephemeral` + `--ignore-user-config`,`codex-sdk` 把 `$CODEX_HOME` 重定向到 per-process tmp 目录(auth.json 通过 symlink 透传)。用户的 `~/.codex/config.toml` 不会渗入任意一个 executor 的 eval。
|
|
674
734
|
|
|
675
735
|
### 自定义执行器
|
|
676
736
|
|
|
@@ -856,25 +916,25 @@ omk bench run \
|
|
|
856
916
|
export OPENAI_API_KEY="你的智谱 API Key"
|
|
857
917
|
export OPENAI_BASE_URL="https://open.bigmodel.cn/api/paas/v4"
|
|
858
918
|
omk bench run --executor openai-api --model glm-4-plus \
|
|
859
|
-
--judge-
|
|
919
|
+
--judge-models openai-api:glm-4-plus --no-cache
|
|
860
920
|
|
|
861
921
|
# 通义千问
|
|
862
922
|
export OPENAI_API_KEY="你的通义 API Key"
|
|
863
923
|
export OPENAI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|
864
924
|
omk bench run --executor openai-api --model qwen-plus \
|
|
865
|
-
--judge-
|
|
925
|
+
--judge-models openai-api:qwen-plus
|
|
866
926
|
|
|
867
927
|
# DeepSeek
|
|
868
928
|
export OPENAI_API_KEY="你的 DeepSeek API Key"
|
|
869
929
|
export OPENAI_BASE_URL="https://api.deepseek.com"
|
|
870
930
|
omk bench run --executor openai-api --model deepseek-chat \
|
|
871
|
-
--judge-
|
|
931
|
+
--judge-models openai-api:deepseek-chat
|
|
872
932
|
|
|
873
933
|
# Moonshot(Kimi)
|
|
874
934
|
export OPENAI_API_KEY="你的 Moonshot API Key"
|
|
875
935
|
export OPENAI_BASE_URL="https://api.moonshot.cn/v1"
|
|
876
936
|
omk bench run --executor openai-api --model moonshot-v1-8k \
|
|
877
|
-
--judge-
|
|
937
|
+
--judge-models openai-api:moonshot-v1-8k
|
|
878
938
|
```
|
|
879
939
|
|
|
880
940
|
**Ollama 本地模型:**
|
|
@@ -884,12 +944,12 @@ omk bench run --executor "python examples/custom-executor/ollama-executor.py" \
|
|
|
884
944
|
--model llama3 --no-judge
|
|
885
945
|
```
|
|
886
946
|
|
|
887
|
-
|
|
947
|
+
**关于评委:**
|
|
888
948
|
|
|
889
|
-
- `--judge-model`
|
|
890
|
-
-
|
|
891
|
-
-
|
|
892
|
-
- 加 `--no-judge` 可跳过 LLM
|
|
949
|
+
- `--judge-models <list>` 指定评委,格式 `executor:model[,executor:model]`。默认 `${executor}:haiku`(没设 `--executor` 时为 claude:haiku)
|
|
950
|
+
- 1 条 = 单评委;≥ 2 条 = 多评委 ensemble + inter-judge agreement
|
|
951
|
+
- 没有 Claude 时把 `--judge-models` 指向你可用的模型,例如 `--judge-models openai-api:glm-4-plus`
|
|
952
|
+
- 加 `--no-judge` 可跳过 LLM 评委,仅使用断言评分
|
|
893
953
|
|
|
894
954
|
## 环境变量
|
|
895
955
|
|
|
@@ -921,4 +981,4 @@ omk bench run --executor "python examples/custom-executor/ollama-executor.py" \
|
|
|
921
981
|
|
|
922
982
|
---
|
|
923
983
|
|
|
924
|
-
版本变更记录见 [
|
|
984
|
+
版本变更记录见 [GitHub Releases](https://github.com/lizhiyao/oh-my-knowledge/releases)。欢迎贡献 — 详见 [CONTRIBUTING](./CONTRIBUTING.md)。
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* is "is N=30 enough, or should I keep running?". Without a principled
|
|
8
8
|
* answer, users either over-pay (running 200 when 50 was enough) or
|
|
9
9
|
* under-pay (calling skill effects null at N=30 when N=80 would have
|
|
10
|
-
* shown clearly significant — Bootstrap CI
|
|
10
|
+
* shown clearly significant — Bootstrap CI just hasn't
|
|
11
11
|
* converged yet).
|
|
12
12
|
*
|
|
13
13
|
* Saturation analysis fits the right tool to the question: track a
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* checkpoints. Easy to explain. Fragile to outlier samples.
|
|
20
20
|
* - **bootstrap-ci-width** (default): CI shrinks as O(1/√N); when its
|
|
21
21
|
* decay rate flattens, more samples buy little. Statistically
|
|
22
|
-
* grounded; pairs naturally with
|
|
22
|
+
* grounded; pairs naturally with the Bootstrap CI module.
|
|
23
23
|
* - **plateau-height**: range of mean across the last K checkpoints.
|
|
24
24
|
* Conservative — slow to declare saturation, hard to fool.
|
|
25
25
|
*
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* is "is N=30 enough, or should I keep running?". Without a principled
|
|
8
8
|
* answer, users either over-pay (running 200 when 50 was enough) or
|
|
9
9
|
* under-pay (calling skill effects null at N=30 when N=80 would have
|
|
10
|
-
* shown clearly significant — Bootstrap CI
|
|
10
|
+
* shown clearly significant — Bootstrap CI just hasn't
|
|
11
11
|
* converged yet).
|
|
12
12
|
*
|
|
13
13
|
* Saturation analysis fits the right tool to the question: track a
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* checkpoints. Easy to explain. Fragile to outlier samples.
|
|
20
20
|
* - **bootstrap-ci-width** (default): CI shrinks as O(1/√N); when its
|
|
21
21
|
* decay rate flattens, more samples buy little. Statistically
|
|
22
|
-
* grounded; pairs naturally with
|
|
22
|
+
* grounded; pairs naturally with the Bootstrap CI module.
|
|
23
23
|
* - **plateau-height**: range of mean across the last K checkpoints.
|
|
24
24
|
* Conservative — slow to declare saturation, hard to fool.
|
|
25
25
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ProgressCallback, Report, Sample } from '../types/index.js';
|
|
1
|
+
import type { JudgeConfig, ProgressCallback, Report, Sample } from '../types/index.js';
|
|
2
2
|
interface WeakSample {
|
|
3
3
|
sample_id: string;
|
|
4
4
|
compositeScore: number;
|
|
@@ -29,12 +29,15 @@ interface EvolveOptions {
|
|
|
29
29
|
rounds?: number;
|
|
30
30
|
target?: number | null;
|
|
31
31
|
model?: string;
|
|
32
|
-
|
|
32
|
+
/** Single-judge config. evolve 不支持 ensemble — CLI 在 length>=2 时 exit 2,
|
|
33
|
+
* programmatic API 在 evolveSkill 入口同样 throw,二者一致。Default
|
|
34
|
+
* `[{ executor: <executorName>, model: 'haiku' }]`. */
|
|
35
|
+
judgeModels?: JudgeConfig[];
|
|
33
36
|
improveModel?: string;
|
|
34
37
|
executorName?: string;
|
|
35
38
|
concurrency?: number;
|
|
36
39
|
timeoutMs?: number;
|
|
37
|
-
|
|
40
|
+
skipConnectivity?: boolean;
|
|
38
41
|
onProgress?: ProgressCallback | null;
|
|
39
42
|
onRoundProgress?: ((progress: EvolveRoundProgressInfo) => void) | null;
|
|
40
43
|
}
|
|
@@ -64,6 +67,6 @@ export interface RoundReport {
|
|
|
64
67
|
report: Report;
|
|
65
68
|
}
|
|
66
69
|
export declare function mergeEvolveReports(roundReports: RoundReport[], skillName: string, totalCostUSD: number, samples?: Sample[]): Report;
|
|
67
|
-
export declare function evolveSkill({ skillPath, samplesPath, rounds, target, model,
|
|
70
|
+
export declare function evolveSkill({ skillPath, samplesPath, rounds, target, model, judgeModels, improveModel, executorName, concurrency, timeoutMs, skipConnectivity, onProgress, onRoundProgress, }: EvolveOptions): Promise<EvolveResult>;
|
|
68
71
|
export {};
|
|
69
72
|
//# sourceMappingURL=evolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evolver.d.ts","sourceRoot":"","sources":["../../../src/authoring/evolver.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAe,MAAM,EAAiB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"evolver.d.ts","sourceRoot":"","sources":["../../../src/authoring/evolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -149,7 +149,15 @@ export function mergeEvolveReports(roundReports, skillName, totalCostUSD, sample
|
|
|
149
149
|
report.analysis = analyzeResults(report, { samples });
|
|
150
150
|
return report;
|
|
151
151
|
}
|
|
152
|
-
export async function evolveSkill({ skillPath, samplesPath, rounds = 5, target = null, model = DEFAULT_MODEL,
|
|
152
|
+
export async function evolveSkill({ skillPath, samplesPath, rounds = 5, target = null, model = DEFAULT_MODEL, judgeModels, improveModel = DEFAULT_MODEL, executorName = 'claude', concurrency = 1, timeoutMs, skipConnectivity = false, onProgress = null, onRoundProgress = null, }) {
|
|
153
|
+
if (judgeModels && judgeModels.length > 1) {
|
|
154
|
+
throw new Error('evolveSkill does not support multi-judge ensemble (received '
|
|
155
|
+
+ `${judgeModels.length} judges). Pass a single-judge array, e.g. `
|
|
156
|
+
+ `[{ executor: 'claude', model: 'haiku' }]`);
|
|
157
|
+
}
|
|
158
|
+
const effectiveJudgeModels = judgeModels && judgeModels.length > 0
|
|
159
|
+
? judgeModels
|
|
160
|
+
: [{ executor: executorName, model: JUDGE_MODEL }];
|
|
153
161
|
const absSkillPath = resolve(skillPath);
|
|
154
162
|
const absSamplesPath = resolve(samplesPath);
|
|
155
163
|
const skillDir = dirname(absSkillPath);
|
|
@@ -177,7 +185,7 @@ export async function evolveSkill({ skillPath, samplesPath, rounds = 5, target =
|
|
|
177
185
|
const reportHasUnreportedCost = (rep) => Object.values(rep.summary).some((v) => v.execCostReported === false || v.judgeCostReported === false);
|
|
178
186
|
// Round 0: baseline evaluation
|
|
179
187
|
const baselineReport = await evaluate(r0Path, {
|
|
180
|
-
samplesPath: absSamplesPath, skillDir, model,
|
|
188
|
+
samplesPath: absSamplesPath, skillDir, model, judgeModels: effectiveJudgeModels, executorName, concurrency, timeoutMs, skipConnectivity, onProgress,
|
|
181
189
|
});
|
|
182
190
|
const baselineVariantKey = Object.keys(baselineReport.summary)[0];
|
|
183
191
|
bestScore = baselineReport.summary[baselineVariantKey]?.avgCompositeScore ?? 0;
|
|
@@ -203,7 +211,7 @@ export async function evolveSkill({ skillPath, samplesPath, rounds = 5, target =
|
|
|
203
211
|
}
|
|
204
212
|
else {
|
|
205
213
|
lastReport = await evaluate(allVersions[bestRound], {
|
|
206
|
-
samplesPath: absSamplesPath, skillDir, model,
|
|
214
|
+
samplesPath: absSamplesPath, skillDir, model, judgeModels: effectiveJudgeModels, executorName, concurrency, timeoutMs, skipConnectivity, onProgress,
|
|
207
215
|
});
|
|
208
216
|
totalCostUSD += lastReport.meta.totalCostUSD;
|
|
209
217
|
if (reportHasUnreportedCost(lastReport))
|
|
@@ -235,7 +243,7 @@ export async function evolveSkill({ skillPath, samplesPath, rounds = 5, target =
|
|
|
235
243
|
allVersions.push(candidatePath);
|
|
236
244
|
// Evaluate candidate
|
|
237
245
|
const candidateReport = await evaluate(candidatePath, {
|
|
238
|
-
samplesPath: absSamplesPath, skillDir, model,
|
|
246
|
+
samplesPath: absSamplesPath, skillDir, model, judgeModels: effectiveJudgeModels, executorName, concurrency, timeoutMs, skipConnectivity, onProgress,
|
|
239
247
|
});
|
|
240
248
|
const candidateVariantKey = Object.keys(candidateReport.summary)[0];
|
|
241
249
|
const candidateScore = candidateReport.summary[candidateVariantKey]?.avgCompositeScore ?? 0;
|
|
@@ -289,19 +297,19 @@ export async function evolveSkill({ skillPath, samplesPath, rounds = 5, target =
|
|
|
289
297
|
reportId,
|
|
290
298
|
};
|
|
291
299
|
}
|
|
292
|
-
async function evaluate(skillFilePath, { samplesPath, skillDir, model,
|
|
300
|
+
async function evaluate(skillFilePath, { samplesPath, skillDir, model, judgeModels, executorName, concurrency, timeoutMs, skipConnectivity, onProgress }) {
|
|
293
301
|
const { report } = await runEvaluation({
|
|
294
302
|
samplesPath,
|
|
295
303
|
skillDir,
|
|
296
304
|
// evolve 评测每一轮只跑当前迭代的 skill,没有对照组;标为 treatment。
|
|
297
305
|
variantSpecs: [{ name: skillFilePath, role: 'treatment', expr: skillFilePath }],
|
|
298
306
|
model,
|
|
299
|
-
|
|
307
|
+
judgeModels,
|
|
300
308
|
outputDir: null, // don't persist intermediate reports
|
|
301
309
|
concurrency,
|
|
302
310
|
timeoutMs,
|
|
303
311
|
executorName,
|
|
304
|
-
|
|
312
|
+
skipConnectivity,
|
|
305
313
|
onProgress,
|
|
306
314
|
});
|
|
307
315
|
return report;
|