oh-my-knowledge 0.18.0 → 0.20.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 +596 -326
- package/README.zh.md +917 -0
- package/dist/src/analysis/failure-clusterer.d.ts +96 -0
- package/dist/src/analysis/failure-clusterer.d.ts.map +1 -0
- package/dist/src/analysis/failure-clusterer.js +298 -0
- package/dist/src/analysis/failure-clusterer.js.map +1 -0
- package/dist/src/analysis/sample-diagnostics.d.ts +78 -0
- package/dist/src/analysis/sample-diagnostics.d.ts.map +1 -0
- package/dist/src/analysis/sample-diagnostics.js +259 -0
- package/dist/src/analysis/sample-diagnostics.js.map +1 -0
- package/dist/src/analysis/saturation.d.ts +85 -0
- package/dist/src/analysis/saturation.d.ts.map +1 -0
- package/dist/src/analysis/saturation.js +174 -0
- package/dist/src/analysis/saturation.js.map +1 -0
- package/dist/src/cli.js +772 -18
- package/dist/src/cli.js.map +1 -1
- package/dist/src/eval-core/bootstrap.d.ts +72 -0
- package/dist/src/eval-core/bootstrap.d.ts.map +1 -0
- package/dist/src/eval-core/bootstrap.js +174 -0
- package/dist/src/eval-core/bootstrap.js.map +1 -0
- package/dist/src/eval-core/evaluation-execution.d.ts +15 -1
- package/dist/src/eval-core/evaluation-execution.d.ts.map +1 -1
- package/dist/src/eval-core/evaluation-execution.js +37 -3
- package/dist/src/eval-core/evaluation-execution.js.map +1 -1
- package/dist/src/eval-core/evaluation-job.d.ts +10 -2
- package/dist/src/eval-core/evaluation-job.d.ts.map +1 -1
- package/dist/src/eval-core/evaluation-job.js +9 -1
- 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 +90 -0
- 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 +69 -0
- package/dist/src/eval-core/schema.js.map +1 -1
- package/dist/src/eval-core/verdict.d.ts +74 -0
- package/dist/src/eval-core/verdict.d.ts.map +1 -0
- package/dist/src/eval-core/verdict.js +283 -0
- package/dist/src/eval-core/verdict.js.map +1 -0
- package/dist/src/eval-workflows/each-evaluation-workflow.d.ts +16 -3
- package/dist/src/eval-workflows/each-evaluation-workflow.d.ts.map +1 -1
- package/dist/src/eval-workflows/each-evaluation-workflow.js +10 -2
- package/dist/src/eval-workflows/each-evaluation-workflow.js.map +1 -1
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts +17 -1
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts.map +1 -1
- package/dist/src/eval-workflows/evaluation-pipeline.js +45 -3
- package/dist/src/eval-workflows/evaluation-pipeline.js.map +1 -1
- package/dist/src/eval-workflows/run-evaluation.d.ts +23 -2
- package/dist/src/eval-workflows/run-evaluation.d.ts.map +1 -1
- package/dist/src/eval-workflows/run-evaluation.js +104 -4
- package/dist/src/eval-workflows/run-evaluation.js.map +1 -1
- package/dist/src/grading/assertions.d.ts +16 -0
- package/dist/src/grading/assertions.d.ts.map +1 -1
- package/dist/src/grading/assertions.js +385 -111
- package/dist/src/grading/assertions.js.map +1 -1
- package/dist/src/grading/debias-validate.d.ts +84 -0
- package/dist/src/grading/debias-validate.d.ts.map +1 -0
- package/dist/src/grading/debias-validate.js +173 -0
- package/dist/src/grading/debias-validate.js.map +1 -0
- package/dist/src/grading/gold-cli.d.ts +88 -0
- package/dist/src/grading/gold-cli.d.ts.map +1 -0
- package/dist/src/grading/gold-cli.js +251 -0
- package/dist/src/grading/gold-cli.js.map +1 -0
- package/dist/src/grading/gold-dataset.d.ts +73 -0
- package/dist/src/grading/gold-dataset.d.ts.map +1 -0
- package/dist/src/grading/gold-dataset.js +161 -0
- package/dist/src/grading/gold-dataset.js.map +1 -0
- package/dist/src/grading/human-gold.d.ts +102 -0
- package/dist/src/grading/human-gold.d.ts.map +1 -0
- package/dist/src/grading/human-gold.js +188 -0
- package/dist/src/grading/human-gold.js.map +1 -0
- package/dist/src/grading/index.d.ts +27 -2
- package/dist/src/grading/index.d.ts.map +1 -1
- package/dist/src/grading/index.js +36 -18
- package/dist/src/grading/index.js.map +1 -1
- package/dist/src/grading/judge.d.ts +65 -2
- package/dist/src/grading/judge.d.ts.map +1 -1
- package/dist/src/grading/judge.js +280 -23
- package/dist/src/grading/judge.js.map +1 -1
- package/dist/src/inputs/eval-config.js +19 -0
- package/dist/src/inputs/eval-config.js.map +1 -1
- package/dist/src/observability/{production-analyzer.d.ts → skill-health-analyzer.d.ts} +24 -2
- package/dist/src/observability/skill-health-analyzer.d.ts.map +1 -0
- package/dist/src/observability/{production-analyzer.js → skill-health-analyzer.js} +61 -6
- package/dist/src/observability/skill-health-analyzer.js.map +1 -0
- package/dist/src/observability/trace-adapter.d.ts.map +1 -1
- package/dist/src/observability/trace-adapter.js +27 -1
- package/dist/src/observability/trace-adapter.js.map +1 -1
- package/dist/src/renderer/html-renderer.d.ts.map +1 -1
- package/dist/src/renderer/html-renderer.js +40 -6
- package/dist/src/renderer/html-renderer.js.map +1 -1
- package/dist/src/renderer/layout.d.ts.map +1 -1
- package/dist/src/renderer/layout.js +138 -4
- package/dist/src/renderer/layout.js.map +1 -1
- package/dist/src/renderer/skill-health-renderer.d.ts +2 -2
- package/dist/src/renderer/skill-health-renderer.d.ts.map +1 -1
- package/dist/src/renderer/skill-health-renderer.js +39 -4
- package/dist/src/renderer/skill-health-renderer.js.map +1 -1
- package/dist/src/renderer/summary.d.ts +28 -1
- package/dist/src/renderer/summary.d.ts.map +1 -1
- package/dist/src/renderer/summary.js +322 -8
- package/dist/src/renderer/summary.js.map +1 -1
- package/dist/src/renderer/table.d.ts.map +1 -1
- package/dist/src/renderer/table.js +63 -2
- package/dist/src/renderer/table.js.map +1 -1
- package/dist/src/server/report-server.d.ts +2 -1
- package/dist/src/server/report-server.d.ts.map +1 -1
- package/dist/src/server/report-server.js +397 -2
- package/dist/src/server/report-server.js.map +1 -1
- package/dist/src/types.d.ts +247 -0
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +24 -6
- package/dist/src/observability/production-analyzer.d.ts.map +0 -1
- package/dist/src/observability/production-analyzer.js.map +0 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `omk bench debias-validate length <reportId>` — measure how much the judge's
|
|
3
|
+
* scores shift when the length-debias instruction is toggled.
|
|
4
|
+
*
|
|
5
|
+
* What it actually measures
|
|
6
|
+
* -------------------------
|
|
7
|
+
* Given a finished report, this command re-judges every (sample, variant) pair
|
|
8
|
+
* using the OPPOSITE length-debias setting from the original run. It then
|
|
9
|
+
* compares the two score distributions with a bootstrap CI on the mean
|
|
10
|
+
* difference.
|
|
11
|
+
*
|
|
12
|
+
* If the original report ran with debias-on (v3-cot-length), we re-judge with
|
|
13
|
+
* v2-cot (legacy). If the original ran with debias-off, we re-judge with
|
|
14
|
+
* v3-cot-length. Significant difference → the prompt change moves scores → the
|
|
15
|
+
* judge is sensitive to the length-debias instruction. That's *consistent with*
|
|
16
|
+
* length bias being present, but it doesn't prove it directly — a perfectly
|
|
17
|
+
* length-neutral judge could in principle also be sensitive to the wording for
|
|
18
|
+
* other reasons. We label the verdict accordingly.
|
|
19
|
+
*
|
|
20
|
+
* Cost
|
|
21
|
+
* ----
|
|
22
|
+
* Re-judging is a full second pass over all (sample, variant) cells. Cost
|
|
23
|
+
* doubles vs the original run. The CLI surfaces this so users running on
|
|
24
|
+
* large/expensive evaluations can opt in deliberately.
|
|
25
|
+
*/
|
|
26
|
+
import type { ExecutorFn, Report, Sample } from '../types.js';
|
|
27
|
+
import { type BootstrapDiffCI } from '../eval-core/bootstrap.js';
|
|
28
|
+
export interface DebiasValidateInput {
|
|
29
|
+
report: Report;
|
|
30
|
+
samples: Sample[];
|
|
31
|
+
judgeExecutor: ExecutorFn;
|
|
32
|
+
judgeModel: string;
|
|
33
|
+
/** Variant to validate. Defaults to first variant. */
|
|
34
|
+
variant?: string;
|
|
35
|
+
/** Bootstrap iterations for the diff CI. Default 1000. */
|
|
36
|
+
bootstrapSamples?: number;
|
|
37
|
+
seed?: number;
|
|
38
|
+
/** Progress hook. */
|
|
39
|
+
onProgress?: (info: {
|
|
40
|
+
sample_id: string;
|
|
41
|
+
completed: number;
|
|
42
|
+
total: number;
|
|
43
|
+
}) => void;
|
|
44
|
+
}
|
|
45
|
+
export interface DebiasValidateResult {
|
|
46
|
+
variant: string;
|
|
47
|
+
/** Original lengthDebias setting (true if debias-on at run time). */
|
|
48
|
+
originalLengthDebias: boolean;
|
|
49
|
+
/** Pairs of (originalScore, alternateScore) per sample. */
|
|
50
|
+
pairs: Array<{
|
|
51
|
+
sample_id: string;
|
|
52
|
+
originalScore: number;
|
|
53
|
+
alternateScore: number;
|
|
54
|
+
}>;
|
|
55
|
+
meanOriginal: number;
|
|
56
|
+
meanAlternate: number;
|
|
57
|
+
/** Mean of (alternate - original). Positive = alternate prompt scored higher. */
|
|
58
|
+
diffCI: BootstrapDiffCI;
|
|
59
|
+
/** Verdict in the {未检测, 弱, 中, 强} bucket plus an English shadow. */
|
|
60
|
+
verdict: {
|
|
61
|
+
zh: string;
|
|
62
|
+
en: string;
|
|
63
|
+
level: 'none' | 'weak' | 'medium' | 'strong';
|
|
64
|
+
};
|
|
65
|
+
/** Total cost burned re-judging. */
|
|
66
|
+
alternateJudgeCostUSD: number;
|
|
67
|
+
/** Sample_ids that the report had but lacked judge scores. */
|
|
68
|
+
unscored: string[];
|
|
69
|
+
/** Sample_ids in the samples file that are missing from the report. */
|
|
70
|
+
missing: string[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Re-judge every sample of `variant` in the given report with the OPPOSITE
|
|
74
|
+
* lengthDebias setting and compute the bootstrap CI on the mean difference.
|
|
75
|
+
*
|
|
76
|
+
* The judge call uses the rubric from the samples file and the output stored
|
|
77
|
+
* in the report — we do NOT re-execute the model. Only judging is repeated.
|
|
78
|
+
*
|
|
79
|
+
* Multi-dimensional samples currently use the rubric as fallback when there's
|
|
80
|
+
* no top-level rubric. Per-dimension validation can be added later if needed.
|
|
81
|
+
*/
|
|
82
|
+
export declare function validateLengthDebias(input: DebiasValidateInput): Promise<DebiasValidateResult>;
|
|
83
|
+
export declare function formatDebiasValidate(result: DebiasValidateResult): string;
|
|
84
|
+
//# sourceMappingURL=debias-validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debias-validate.d.ts","sourceRoot":"","sources":["../../../src/grading/debias-validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAElF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,UAAU,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACtF;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,oBAAoB,EAAE,OAAO,CAAC;IAC9B,2DAA2D;IAC3D,KAAK,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnF,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,MAAM,EAAE,eAAe,CAAC;IACxB,mEAAmE;IACnE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;KAAE,CAAC;IAClF,oCAAoC;IACpC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uEAAuE;IACvE,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAqBD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAuFpG;AAOD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CA8BzE"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `omk bench debias-validate length <reportId>` — measure how much the judge's
|
|
3
|
+
* scores shift when the length-debias instruction is toggled.
|
|
4
|
+
*
|
|
5
|
+
* What it actually measures
|
|
6
|
+
* -------------------------
|
|
7
|
+
* Given a finished report, this command re-judges every (sample, variant) pair
|
|
8
|
+
* using the OPPOSITE length-debias setting from the original run. It then
|
|
9
|
+
* compares the two score distributions with a bootstrap CI on the mean
|
|
10
|
+
* difference.
|
|
11
|
+
*
|
|
12
|
+
* If the original report ran with debias-on (v3-cot-length), we re-judge with
|
|
13
|
+
* v2-cot (legacy). If the original ran with debias-off, we re-judge with
|
|
14
|
+
* v3-cot-length. Significant difference → the prompt change moves scores → the
|
|
15
|
+
* judge is sensitive to the length-debias instruction. That's *consistent with*
|
|
16
|
+
* length bias being present, but it doesn't prove it directly — a perfectly
|
|
17
|
+
* length-neutral judge could in principle also be sensitive to the wording for
|
|
18
|
+
* other reasons. We label the verdict accordingly.
|
|
19
|
+
*
|
|
20
|
+
* Cost
|
|
21
|
+
* ----
|
|
22
|
+
* Re-judging is a full second pass over all (sample, variant) cells. Cost
|
|
23
|
+
* doubles vs the original run. The CLI surfaces this so users running on
|
|
24
|
+
* large/expensive evaluations can opt in deliberately.
|
|
25
|
+
*/
|
|
26
|
+
import { llmJudge } from './judge.js';
|
|
27
|
+
import { bootstrapDiffCI } from '../eval-core/bootstrap.js';
|
|
28
|
+
/**
|
|
29
|
+
* Map a bootstrap diff CI to a verdict bucket. The ranges are deliberately
|
|
30
|
+
* conservative: we only label "strong" when the CI fully sits >= |0.5| away
|
|
31
|
+
* from zero (about half a point on a 1-5 scale).
|
|
32
|
+
*/
|
|
33
|
+
function classifyVerdict(diff) {
|
|
34
|
+
if (!diff.significant) {
|
|
35
|
+
return { zh: '未检测到显著差异', en: 'no significant shift', level: 'none' };
|
|
36
|
+
}
|
|
37
|
+
const mag = Math.min(Math.abs(diff.low), Math.abs(diff.high));
|
|
38
|
+
if (mag >= 0.5) {
|
|
39
|
+
return { zh: '强差异 — prompt 改动对评分影响大', en: 'strong shift', level: 'strong' };
|
|
40
|
+
}
|
|
41
|
+
if (mag >= 0.2) {
|
|
42
|
+
return { zh: '中等差异 — 校正对结论有实质影响', en: 'medium shift', level: 'medium' };
|
|
43
|
+
}
|
|
44
|
+
return { zh: '弱差异 — 显著但幅度小', en: 'weak shift', level: 'weak' };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Re-judge every sample of `variant` in the given report with the OPPOSITE
|
|
48
|
+
* lengthDebias setting and compute the bootstrap CI on the mean difference.
|
|
49
|
+
*
|
|
50
|
+
* The judge call uses the rubric from the samples file and the output stored
|
|
51
|
+
* in the report — we do NOT re-execute the model. Only judging is repeated.
|
|
52
|
+
*
|
|
53
|
+
* Multi-dimensional samples currently use the rubric as fallback when there's
|
|
54
|
+
* no top-level rubric. Per-dimension validation can be added later if needed.
|
|
55
|
+
*/
|
|
56
|
+
export async function validateLengthDebias(input) {
|
|
57
|
+
const { report, samples, judgeExecutor, judgeModel, bootstrapSamples = 1000, seed, onProgress } = input;
|
|
58
|
+
const variant = input.variant ?? report.meta.variants?.[0];
|
|
59
|
+
if (!variant)
|
|
60
|
+
throw new Error('report has no variants — nothing to validate');
|
|
61
|
+
// Detect original lengthDebias setting from meta. Default to true (v0.21+).
|
|
62
|
+
// Older reports without debiasMode set are treated as legacy (debias-off).
|
|
63
|
+
const debiasModeList = report.meta.debiasMode ?? [];
|
|
64
|
+
const originalLengthDebias = debiasModeList.includes('length');
|
|
65
|
+
const alternateLengthDebias = !originalLengthDebias;
|
|
66
|
+
const sampleById = new Map();
|
|
67
|
+
for (const s of samples)
|
|
68
|
+
sampleById.set(s.sample_id, s);
|
|
69
|
+
// Pre-pass: collect (sample_id, output, originalScore) tuples.
|
|
70
|
+
const tasks = [];
|
|
71
|
+
const unscored = [];
|
|
72
|
+
const missing = [];
|
|
73
|
+
for (const entry of report.results ?? []) {
|
|
74
|
+
const v = entry.variants?.[variant];
|
|
75
|
+
if (!v || !v.fullOutput)
|
|
76
|
+
continue;
|
|
77
|
+
const sample = sampleById.get(entry.sample_id);
|
|
78
|
+
if (!sample) {
|
|
79
|
+
missing.push(entry.sample_id);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (typeof v.llmScore !== 'number' || v.llmScore <= 0) {
|
|
83
|
+
unscored.push(entry.sample_id);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
tasks.push({ sample, output: v.fullOutput, originalScore: v.llmScore });
|
|
87
|
+
}
|
|
88
|
+
// Re-judge with the opposite debias setting. We use the simplest path:
|
|
89
|
+
// single-rubric judge. Multi-dim samples fall back to the explicit rubric
|
|
90
|
+
// string if available. Samples without a rubric are skipped — we have
|
|
91
|
+
// nothing to feed the judge.
|
|
92
|
+
const pairs = [];
|
|
93
|
+
let alternateJudgeCostUSD = 0;
|
|
94
|
+
let completed = 0;
|
|
95
|
+
for (const t of tasks) {
|
|
96
|
+
completed++;
|
|
97
|
+
onProgress?.({ sample_id: t.sample.sample_id, completed, total: tasks.length });
|
|
98
|
+
const rubric = t.sample.rubric
|
|
99
|
+
?? (t.sample.dimensions ? Object.values(t.sample.dimensions).join('\n') : '');
|
|
100
|
+
if (!rubric)
|
|
101
|
+
continue;
|
|
102
|
+
const altResult = await llmJudge({
|
|
103
|
+
output: t.output,
|
|
104
|
+
rubric,
|
|
105
|
+
prompt: t.sample.prompt,
|
|
106
|
+
executor: judgeExecutor,
|
|
107
|
+
model: judgeModel,
|
|
108
|
+
lengthDebias: alternateLengthDebias,
|
|
109
|
+
});
|
|
110
|
+
if (altResult.judgeCostUSD)
|
|
111
|
+
alternateJudgeCostUSD += altResult.judgeCostUSD;
|
|
112
|
+
if (altResult.score > 0) {
|
|
113
|
+
pairs.push({
|
|
114
|
+
sample_id: t.sample.sample_id,
|
|
115
|
+
originalScore: t.originalScore,
|
|
116
|
+
alternateScore: altResult.score,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const meanOriginal = avg(pairs.map((p) => p.originalScore));
|
|
121
|
+
const meanAlternate = avg(pairs.map((p) => p.alternateScore));
|
|
122
|
+
const diffCI = bootstrapDiffCI(pairs.map((p) => p.originalScore), pairs.map((p) => p.alternateScore), 0.05, bootstrapSamples, seed);
|
|
123
|
+
const verdict = classifyVerdict(diffCI);
|
|
124
|
+
return {
|
|
125
|
+
variant,
|
|
126
|
+
originalLengthDebias,
|
|
127
|
+
pairs,
|
|
128
|
+
meanOriginal: Number(meanOriginal.toFixed(3)),
|
|
129
|
+
meanAlternate: Number(meanAlternate.toFixed(3)),
|
|
130
|
+
diffCI,
|
|
131
|
+
verdict,
|
|
132
|
+
alternateJudgeCostUSD: Number(alternateJudgeCostUSD.toFixed(6)),
|
|
133
|
+
unscored,
|
|
134
|
+
missing,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function avg(arr) {
|
|
138
|
+
if (arr.length === 0)
|
|
139
|
+
return 0;
|
|
140
|
+
return arr.reduce((s, x) => s + x, 0) / arr.length;
|
|
141
|
+
}
|
|
142
|
+
export function formatDebiasValidate(result) {
|
|
143
|
+
const lines = [];
|
|
144
|
+
const dirOrig = result.originalLengthDebias ? 'on (v3-cot-length)' : 'off (v2-cot)';
|
|
145
|
+
const dirAlt = result.originalLengthDebias ? 'off (v2-cot)' : 'on (v3-cot-length)';
|
|
146
|
+
lines.push(`\n Length-debias 灵敏度验证 (variant: ${result.variant})\n`);
|
|
147
|
+
lines.push(` 原始 prompt: ${dirOrig}`);
|
|
148
|
+
lines.push(` 对照 prompt: ${dirAlt}`);
|
|
149
|
+
lines.push(` 样本数: ${result.pairs.length}`);
|
|
150
|
+
if (result.pairs.length === 0) {
|
|
151
|
+
lines.push(' 无可比对样本 — 检查报告是否含 fullOutput / rubric。');
|
|
152
|
+
return lines.join('\n');
|
|
153
|
+
}
|
|
154
|
+
lines.push(` 原均值: ${result.meanOriginal.toFixed(3)}`);
|
|
155
|
+
lines.push(` 对照均值: ${result.meanAlternate.toFixed(3)}`);
|
|
156
|
+
const ci = result.diffCI;
|
|
157
|
+
lines.push(` 差值 (alt-orig): ${ci.estimate >= 0 ? '+' : ''}${ci.estimate}`);
|
|
158
|
+
lines.push(` 95% CI: [${ci.low}, ${ci.high}] (${ci.significant ? '显著' : '不显著'})`);
|
|
159
|
+
lines.push('');
|
|
160
|
+
lines.push(` 结论: ${result.verdict.zh}`);
|
|
161
|
+
lines.push('');
|
|
162
|
+
lines.push(` 注: 该结论反映"prompt 切换是否改变评分"。差异显著 = 评分对 length-debias 指令敏感,`);
|
|
163
|
+
lines.push(` 间接支持 length bias 存在;但 prompt 文本变化也可能因其他原因影响评分。`);
|
|
164
|
+
lines.push(` 重判 cost: ${result.alternateJudgeCostUSD.toFixed(6)} USD`);
|
|
165
|
+
if (result.missing.length) {
|
|
166
|
+
lines.push(` 缺样本 ID: ${result.missing.length} 条`);
|
|
167
|
+
}
|
|
168
|
+
if (result.unscored.length) {
|
|
169
|
+
lines.push(` 无 LLM 分: ${result.unscored.length} 条`);
|
|
170
|
+
}
|
|
171
|
+
return lines.join('\n');
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=debias-validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debias-validate.js","sourceRoot":"","sources":["../../../src/grading/debias-validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `omk bench gold` subcommands: init / validate / compare.
|
|
3
|
+
*
|
|
4
|
+
* Kept out of cli.ts to keep that file from growing further; cli.ts only
|
|
5
|
+
* dispatches subcommand strings to the handlers exported here.
|
|
6
|
+
*/
|
|
7
|
+
import type { Report, ReportHumanAgreement } from '../types.js';
|
|
8
|
+
import { type GoldDataset } from './gold-dataset.js';
|
|
9
|
+
import { type AgreementResult } from './human-gold.js';
|
|
10
|
+
export interface GoldCompareInput {
|
|
11
|
+
report: Report;
|
|
12
|
+
gold: GoldDataset;
|
|
13
|
+
/** Variant to compare against gold. Default: first variant in report.meta.variants. */
|
|
14
|
+
variant?: string;
|
|
15
|
+
/** Bootstrap parameters. */
|
|
16
|
+
samples?: number;
|
|
17
|
+
seed?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface GoldCompareResult {
|
|
20
|
+
agreement: AgreementResult;
|
|
21
|
+
/** Sample-level comparison rows for the renderer / per-row UI. */
|
|
22
|
+
rows: Array<{
|
|
23
|
+
sample_id: string;
|
|
24
|
+
goldScore: number;
|
|
25
|
+
judgeScore: number;
|
|
26
|
+
diff: number;
|
|
27
|
+
}>;
|
|
28
|
+
/** Sample IDs in the gold set that were missing from the report. */
|
|
29
|
+
missing: string[];
|
|
30
|
+
/** Sample IDs in the gold set whose judge score was missing/non-numeric. */
|
|
31
|
+
unscored: string[];
|
|
32
|
+
/** Contamination warning string if annotator id matches any judge model id. */
|
|
33
|
+
contaminationWarning?: string;
|
|
34
|
+
/** Variant actually used. */
|
|
35
|
+
variant: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Compute agreement between gold annotations and the LLM judge's scores from
|
|
39
|
+
* a finished report.
|
|
40
|
+
*
|
|
41
|
+
* Pure function — does not touch fs or stdout. The CLI handler wraps it.
|
|
42
|
+
*/
|
|
43
|
+
export declare function compareGoldToReport(input: GoldCompareInput): GoldCompareResult;
|
|
44
|
+
/**
|
|
45
|
+
* Format the comparison result as a human-readable terminal report.
|
|
46
|
+
*/
|
|
47
|
+
export declare function formatGoldCompare(result: GoldCompareResult, gold: GoldDataset): string;
|
|
48
|
+
/**
|
|
49
|
+
* Generate a starter dataset directory with a metadata.yaml and an
|
|
50
|
+
* annotations.yaml stub. Errors out if the directory already has yaml files
|
|
51
|
+
* (refuses to clobber).
|
|
52
|
+
*/
|
|
53
|
+
export declare function initGoldDataset(targetDir: string, options?: {
|
|
54
|
+
annotator?: string;
|
|
55
|
+
}): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Convert an in-memory comparison result into the persisted ReportMeta shape.
|
|
58
|
+
*/
|
|
59
|
+
export declare function toPersistedAgreement(result: GoldCompareResult, gold: GoldDataset): ReportHumanAgreement;
|
|
60
|
+
/**
|
|
61
|
+
* Side-effecting helper for `omk bench run --gold-dir`: load gold, compute
|
|
62
|
+
* agreement, mutate report.meta.humanAgreement, re-persist the report file,
|
|
63
|
+
* print the human-readable comparison to stderr.
|
|
64
|
+
*
|
|
65
|
+
* Returns the comparison result so the CLI can also surface contamination
|
|
66
|
+
* warnings programmatically.
|
|
67
|
+
*/
|
|
68
|
+
export declare function attachGoldAgreementToReport(input: {
|
|
69
|
+
report: Report;
|
|
70
|
+
goldDir: string;
|
|
71
|
+
outputDir: string;
|
|
72
|
+
samples?: number;
|
|
73
|
+
seed?: number;
|
|
74
|
+
variant?: string;
|
|
75
|
+
}): {
|
|
76
|
+
result?: GoldCompareResult;
|
|
77
|
+
gold?: GoldDataset;
|
|
78
|
+
loadIssues: string[];
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Validate-only entry point. Returns issues; CLI exits non-zero if any.
|
|
82
|
+
*/
|
|
83
|
+
export declare function validateGoldDataset(dir: string): {
|
|
84
|
+
ok: boolean;
|
|
85
|
+
issues: string[];
|
|
86
|
+
sampleCount: number;
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=gold-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gold-cli.d.ts","sourceRoot":"","sources":["../../../src/grading/gold-cli.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAA8B,MAAM,aAAa,CAAC;AAE5F,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,WAAW,CAAC;IAClB,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,eAAe,CAAC;IAC3B,kEAAkE;IAClE,IAAI,EAAE,KAAK,CAAC;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,oEAAoE;IACpE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAqE9E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,CA8BtF;AAgBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,EAAE,CAwDjG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,WAAW,GAChB,oBAAoB,CAetB;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG;IAAE,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAU3E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAWvG"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `omk bench gold` subcommands: init / validate / compare.
|
|
3
|
+
*
|
|
4
|
+
* Kept out of cli.ts to keep that file from growing further; cli.ts only
|
|
5
|
+
* dispatches subcommand strings to the handlers exported here.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, mkdirSync, writeFileSync, readdirSync } from 'node:fs';
|
|
8
|
+
import { resolve, join } from 'node:path';
|
|
9
|
+
import { persistReport } from '../eval-core/evaluation-reporting.js';
|
|
10
|
+
import { loadGoldDataset, dumpYaml } from './gold-dataset.js';
|
|
11
|
+
import { computeAgreementWithCI, } from './human-gold.js';
|
|
12
|
+
/**
|
|
13
|
+
* Compute agreement between gold annotations and the LLM judge's scores from
|
|
14
|
+
* a finished report.
|
|
15
|
+
*
|
|
16
|
+
* Pure function — does not touch fs or stdout. The CLI handler wraps it.
|
|
17
|
+
*/
|
|
18
|
+
export function compareGoldToReport(input) {
|
|
19
|
+
const { report, gold, samples = 1000, seed } = input;
|
|
20
|
+
const variants = report.meta?.variants ?? [];
|
|
21
|
+
const variant = input.variant ?? variants[0];
|
|
22
|
+
if (!variant) {
|
|
23
|
+
throw new Error('report has no variants — cannot compare to gold');
|
|
24
|
+
}
|
|
25
|
+
// Build sample_id → judge score lookup. We use llmScore (composite mean
|
|
26
|
+
// across dimensions if multi-dim, single score otherwise) — that's the
|
|
27
|
+
// number a single human gold rater is most directly comparable to.
|
|
28
|
+
const judgeScoreById = new Map();
|
|
29
|
+
for (const entry of report.results ?? []) {
|
|
30
|
+
const v = entry.variants?.[variant];
|
|
31
|
+
if (!v)
|
|
32
|
+
continue;
|
|
33
|
+
const s = v.llmScore;
|
|
34
|
+
if (typeof s === 'number' && Number.isFinite(s)) {
|
|
35
|
+
judgeScoreById.set(entry.sample_id, s);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const pairs = [];
|
|
39
|
+
const rows = [];
|
|
40
|
+
const missing = [];
|
|
41
|
+
const unscored = [];
|
|
42
|
+
for (const anno of gold.annotations) {
|
|
43
|
+
const judge = judgeScoreById.get(anno.sample_id);
|
|
44
|
+
if (judge === undefined) {
|
|
45
|
+
// Differentiate "sample doesn't exist in this report" vs "sample exists
|
|
46
|
+
// but had no score" (e.g. assertions-only sample, judge skipped).
|
|
47
|
+
const hasEntry = (report.results ?? []).some((r) => r.sample_id === anno.sample_id);
|
|
48
|
+
if (hasEntry)
|
|
49
|
+
unscored.push(anno.sample_id);
|
|
50
|
+
else
|
|
51
|
+
missing.push(anno.sample_id);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
pairs.push({ unitId: anno.sample_id, coderA: anno.score, coderB: judge });
|
|
55
|
+
rows.push({
|
|
56
|
+
sample_id: anno.sample_id,
|
|
57
|
+
goldScore: anno.score,
|
|
58
|
+
judgeScore: judge,
|
|
59
|
+
diff: Number((judge - anno.score).toFixed(4)),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const scaleMeta = gold.metadata.scale ?? { min: 1, max: 5 };
|
|
63
|
+
const agreement = computeAgreementWithCI(pairs, { samples, seed, scale: scaleMeta });
|
|
64
|
+
// Contamination check: gold annotator id matching any judge model id is a
|
|
65
|
+
// statistical hazard (model-judges-itself inflates agreement). We only warn
|
|
66
|
+
// — users may have one model available and proceed knowingly.
|
|
67
|
+
const annotator = gold.metadata.annotator.trim().toLowerCase();
|
|
68
|
+
const judgeIds = [
|
|
69
|
+
report.meta?.judgeModel ?? '',
|
|
70
|
+
...(report.meta?.judgeModels ?? []),
|
|
71
|
+
].filter(Boolean).map((s) => s.toLowerCase());
|
|
72
|
+
const contaminated = judgeIds.find((j) => j.includes(annotator) || annotator.includes(j));
|
|
73
|
+
const contaminationWarning = contaminated
|
|
74
|
+
? `gold annotator "${gold.metadata.annotator}" overlaps with judge model "${contaminated}" — agreement is inflated; treat α as upper bound only`
|
|
75
|
+
: undefined;
|
|
76
|
+
return {
|
|
77
|
+
agreement,
|
|
78
|
+
rows,
|
|
79
|
+
missing,
|
|
80
|
+
unscored,
|
|
81
|
+
contaminationWarning,
|
|
82
|
+
variant,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Format the comparison result as a human-readable terminal report.
|
|
87
|
+
*/
|
|
88
|
+
export function formatGoldCompare(result, gold) {
|
|
89
|
+
const lines = [];
|
|
90
|
+
const a = result.agreement;
|
|
91
|
+
lines.push(`\n 人工锚点对比 (variant: ${result.variant})\n`);
|
|
92
|
+
lines.push(` 样本数: ${a.sampleCount}`);
|
|
93
|
+
if (a.sampleCount === 0) {
|
|
94
|
+
lines.push(' 无可比对样本 — 检查 sample_id 是否对应。');
|
|
95
|
+
if (result.missing.length)
|
|
96
|
+
lines.push(` 报告缺失: ${result.missing.join(', ')}`);
|
|
97
|
+
return lines.join('\n');
|
|
98
|
+
}
|
|
99
|
+
lines.push(` Krippendorff α: ${fmt(a.alpha)} (主指标,序数加权)`);
|
|
100
|
+
lines.push(` α 95% CI: [${fmt(a.alphaCI.low)}, ${fmt(a.alphaCI.high)}]`);
|
|
101
|
+
lines.push(` 加权 κ: ${fmt(a.weightedKappa)} (副指标)`);
|
|
102
|
+
lines.push(` Pearson r: ${fmt(a.pearson)} (仅查 rank order)`);
|
|
103
|
+
lines.push('');
|
|
104
|
+
lines.push(` 解读: ${interpret(a.alpha)}`);
|
|
105
|
+
if (result.missing.length) {
|
|
106
|
+
lines.push(` 报告缺 sample: ${result.missing.length} 条 (${result.missing.slice(0, 5).join(', ')}${result.missing.length > 5 ? '...' : ''})`);
|
|
107
|
+
}
|
|
108
|
+
if (result.unscored.length) {
|
|
109
|
+
lines.push(` 缺 LLM 分: ${result.unscored.length} 条 (${result.unscored.slice(0, 5).join(', ')}${result.unscored.length > 5 ? '...' : ''})`);
|
|
110
|
+
}
|
|
111
|
+
if (result.contaminationWarning) {
|
|
112
|
+
lines.push('');
|
|
113
|
+
lines.push(` ⚠ 污染警告: ${result.contaminationWarning}`);
|
|
114
|
+
}
|
|
115
|
+
lines.push('');
|
|
116
|
+
lines.push(` gold annotator: ${gold.metadata.annotator} (${gold.metadata.annotatedAt}, v${gold.metadata.version})`);
|
|
117
|
+
lines.push('');
|
|
118
|
+
return lines.join('\n');
|
|
119
|
+
}
|
|
120
|
+
function fmt(x) {
|
|
121
|
+
if (Number.isNaN(x))
|
|
122
|
+
return 'NaN';
|
|
123
|
+
return x.toFixed(3);
|
|
124
|
+
}
|
|
125
|
+
function interpret(alpha) {
|
|
126
|
+
if (Number.isNaN(alpha))
|
|
127
|
+
return 'α 未定义(数据无方差,需要更多评分多样性)';
|
|
128
|
+
if (alpha >= 0.8)
|
|
129
|
+
return 'α ≥ 0.80 — 高度一致,结论可放心使用';
|
|
130
|
+
if (alpha >= 0.667)
|
|
131
|
+
return 'α ∈ [0.67, 0.80) — 可接受,但谨慎结论';
|
|
132
|
+
if (alpha >= 0.4)
|
|
133
|
+
return 'α ∈ [0.40, 0.67) — 较弱一致,结论需配合 CI 与人工抽检';
|
|
134
|
+
if (alpha >= 0)
|
|
135
|
+
return 'α < 0.40 — 评委与 gold 偏差较大,先排查 rubric / prompt';
|
|
136
|
+
return 'α < 0 — 评委与 gold 系统性反向,必须重新审视判分逻辑';
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Generate a starter dataset directory with a metadata.yaml and an
|
|
140
|
+
* annotations.yaml stub. Errors out if the directory already has yaml files
|
|
141
|
+
* (refuses to clobber).
|
|
142
|
+
*/
|
|
143
|
+
export function initGoldDataset(targetDir, options = {}) {
|
|
144
|
+
const abs = resolve(targetDir);
|
|
145
|
+
if (existsSync(abs)) {
|
|
146
|
+
const present = readdirSync(abs).filter((f) => /\.ya?ml$/.test(f));
|
|
147
|
+
if (present.length > 0) {
|
|
148
|
+
throw new Error(`目标目录已存在 YAML 文件 (${present.join(', ')}),避免覆盖请换目录`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
mkdirSync(abs, { recursive: true });
|
|
153
|
+
}
|
|
154
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
155
|
+
const metadata = {
|
|
156
|
+
annotator: options.annotator ?? 'YOUR-MODEL-OR-TEAM-ID',
|
|
157
|
+
annotatedAt: today,
|
|
158
|
+
version: '0.1',
|
|
159
|
+
scale: { min: 1, max: 5 },
|
|
160
|
+
notes: 'omk gold dataset — 标注者 id 与 omk 默认 judge 不同时(如 sonnet judge + opus gold),CLI 自动检查污染。',
|
|
161
|
+
};
|
|
162
|
+
const annotations = {
|
|
163
|
+
annotations: [
|
|
164
|
+
{ sample_id: 'EXAMPLE_001', score: 4, reason: '示例:替换为真实标注或删除' },
|
|
165
|
+
{ sample_id: 'EXAMPLE_002', score: 2 },
|
|
166
|
+
],
|
|
167
|
+
};
|
|
168
|
+
const metaPath = join(abs, 'metadata.yaml');
|
|
169
|
+
const annoPath = join(abs, 'annotations.yaml');
|
|
170
|
+
writeFileSync(metaPath, dumpYaml({ metadata }));
|
|
171
|
+
writeFileSync(annoPath, dumpYaml(annotations));
|
|
172
|
+
const readme = [
|
|
173
|
+
'# Gold dataset',
|
|
174
|
+
'',
|
|
175
|
+
'omk 用此目录作为人工锚点 (human gold) 与 LLM judge 对比。',
|
|
176
|
+
'',
|
|
177
|
+
'## 文件说明',
|
|
178
|
+
'- `metadata.yaml`: annotator / 时间 / 版本 / 评分量程',
|
|
179
|
+
'- `annotations.yaml`: 每条 `{ sample_id, score, reason? }`,按 sample_id 拼接',
|
|
180
|
+
'',
|
|
181
|
+
'## 重要约束',
|
|
182
|
+
'1. annotator 不应与 omk judge 模型同名 — CLI 检测到会警告',
|
|
183
|
+
'2. 单标注者只反映一个视角;30 条以下的 demo 不构成基准',
|
|
184
|
+
'3. score 必须在 metadata.scale 范围内 (默认 1-5)',
|
|
185
|
+
'',
|
|
186
|
+
'## 校验',
|
|
187
|
+
'```bash',
|
|
188
|
+
'omk bench gold validate <this-dir>',
|
|
189
|
+
'omk bench gold compare <reportId> --gold-dir <this-dir>',
|
|
190
|
+
'```',
|
|
191
|
+
'',
|
|
192
|
+
].join('\n');
|
|
193
|
+
const readmePath = join(abs, 'README.md');
|
|
194
|
+
if (!existsSync(readmePath))
|
|
195
|
+
writeFileSync(readmePath, readme);
|
|
196
|
+
return [metaPath, annoPath, readmePath];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Convert an in-memory comparison result into the persisted ReportMeta shape.
|
|
200
|
+
*/
|
|
201
|
+
export function toPersistedAgreement(result, gold) {
|
|
202
|
+
const a = result.agreement;
|
|
203
|
+
return {
|
|
204
|
+
alpha: a.alpha,
|
|
205
|
+
alphaCI: a.alphaCI,
|
|
206
|
+
weightedKappa: a.weightedKappa,
|
|
207
|
+
pearson: a.pearson,
|
|
208
|
+
sampleCount: a.sampleCount,
|
|
209
|
+
variant: result.variant,
|
|
210
|
+
goldAnnotator: gold.metadata.annotator,
|
|
211
|
+
goldVersion: gold.metadata.version,
|
|
212
|
+
contaminationWarning: result.contaminationWarning,
|
|
213
|
+
missingCount: result.missing.length,
|
|
214
|
+
unscoredCount: result.unscored.length,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Side-effecting helper for `omk bench run --gold-dir`: load gold, compute
|
|
219
|
+
* agreement, mutate report.meta.humanAgreement, re-persist the report file,
|
|
220
|
+
* print the human-readable comparison to stderr.
|
|
221
|
+
*
|
|
222
|
+
* Returns the comparison result so the CLI can also surface contamination
|
|
223
|
+
* warnings programmatically.
|
|
224
|
+
*/
|
|
225
|
+
export function attachGoldAgreementToReport(input) {
|
|
226
|
+
const { report, goldDir, outputDir, samples, seed, variant } = input;
|
|
227
|
+
const { dataset, issues } = loadGoldDataset(goldDir);
|
|
228
|
+
const loadIssues = issues.map((i) => i.message);
|
|
229
|
+
if (!dataset)
|
|
230
|
+
return { loadIssues };
|
|
231
|
+
const result = compareGoldToReport({ report, gold: dataset, samples, seed, variant });
|
|
232
|
+
report.meta.humanAgreement = toPersistedAgreement(result, dataset);
|
|
233
|
+
persistReport(report, outputDir);
|
|
234
|
+
return { result, gold: dataset, loadIssues };
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Validate-only entry point. Returns issues; CLI exits non-zero if any.
|
|
238
|
+
*/
|
|
239
|
+
export function validateGoldDataset(dir) {
|
|
240
|
+
const { dataset, issues } = loadGoldDataset(dir);
|
|
241
|
+
const formatted = issues.map((i) => {
|
|
242
|
+
const at = i.path ? ` (${i.path}${i.index !== undefined ? `:${i.index}` : ''})` : '';
|
|
243
|
+
return `${i.message}${at}`;
|
|
244
|
+
});
|
|
245
|
+
return {
|
|
246
|
+
ok: !!dataset && issues.length === 0,
|
|
247
|
+
issues: formatted,
|
|
248
|
+
sampleCount: dataset?.annotations.length ?? 0,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=gold-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gold-cli.js","sourceRoot":"","sources":["../../../src/grading/gold-cli.ts"],"names":[],"mappings":"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"}
|