skilldrop-cli 0.16.36 → 0.16.37
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 +1 -1
- package/catalogue.json +3 -1
- package/model-routing.json +8 -0
- package/package.json +1 -1
- package/packs/ai-engineering/skills/judge-audit/SKILL.md +157 -0
- package/packs/ai-engineering/skills/judge-audit/evals/eval_queries.json +11 -0
- package/packs/ai-engineering/skills/judge-audit/evals/evals.json +136 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/1/judgements.csv +321 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/1/notes.md +28 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/2/pairwise.csv +101 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/2/run-notes.md +16 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/4/grades.csv +97 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/5/pairwise_judgements.jsonl +120 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/6/rag-judge/README.md +36 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/6/rag-judge/judgments.csv +301 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/7/moderation/gold_labels.csv +101 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/7/moderation/run_1.jsonl +100 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/7/moderation/run_2.jsonl +100 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/8/patches.csv +241 -0
- package/packs/ai-engineering/skills/judge-audit/evals/files/9/adequacy_ratings.csv +151 -0
- package/packs/ai-engineering/skills/judge-audit/examples/summary-panel.md +70 -0
- package/packs/ai-engineering/skills/judge-audit/manifest.json +44 -0
- package/packs/ai-engineering/skills/judge-audit/reference.md +176 -0
- package/packs/ai-engineering/skills/judge-audit/scripts/judge_stats.py +1735 -0
- package/packs/frontend/pack.json +9 -3
- package/packs/frontend/skills/bundle-size-review/SKILL.md +114 -0
- package/packs/frontend/skills/bundle-size-review/evals/eval_queries.json +12 -0
- package/packs/frontend/skills/bundle-size-review/evals/evals.json +108 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/1/package.json +28 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/1/src/utils/format.js +26 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/1/stats.json +1334 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/2/PR.md +21 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/2/meta-after.json +440 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/2/meta-before.json +360 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/3/package.json +29 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/3/stats.json +1583 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/4/src/components/CommentBox.jsx +24 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/4/stats/after.json +299 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/4/stats/before.json +275 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/5/.browserslistrc +3 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/5/build/meta.json +371 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/5/build.mjs +18 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/5/package-lock.json +39 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/5/package.json +22 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/5/src/components/Icon.jsx +8 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/5/src/polyfills.js +7 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/5/src/utils/groupRows.js +4 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/.browserslistrc +3 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/package.json +25 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/App.tsx +8 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/i18n/chartLocales.ts +16 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/i18n/index.ts +8 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/i18n/messages/de.ts +5 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/i18n/messages/en.ts +5 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/i18n/useLocale.ts +14 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/main.tsx +10 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/pages/Home.tsx +14 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/pages/Reports.tsx +31 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/src/routes.tsx +17 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/stats.json +1869 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/6/vite.config.ts +13 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/backoffice/package.json +26 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/backoffice/src/App.tsx +27 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/backoffice/src/pages/Analytics.tsx +10 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/backoffice/src/pages/Users.tsx +13 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/backoffice/stats.json +1421 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/backoffice/webpack.config.js +25 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/storefront/package.json +27 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/storefront/src/App.tsx +18 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/storefront/src/index.tsx +4 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/storefront/src/pages/Home.tsx +10 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/storefront/src/pages/Product.tsx +13 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/storefront/stats.json +1496 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/apps/storefront/webpack.config.js +26 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/package.json +9 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/dist/Button.css +3 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/dist/Button.js +14 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/dist/Chart.js +21 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/dist/index.js +22 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/package.json +20 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/src/Button.css +3 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/src/Button.tsx +9 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/src/Chart.tsx +14 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/src/index.ts +6 -0
- package/packs/frontend/skills/bundle-size-review/evals/files/7/packages/ui/tsconfig.json +14 -0
- package/packs/frontend/skills/bundle-size-review/examples/inputs/stats-after.json +1358 -0
- package/packs/frontend/skills/bundle-size-review/examples/inputs/stats-before.json +1334 -0
- package/packs/frontend/skills/bundle-size-review/examples/larkspur-sparkline.md +52 -0
- package/packs/frontend/skills/bundle-size-review/manifest.json +52 -0
- package/packs/frontend/skills/bundle-size-review/reference.md +147 -0
- package/packs/frontend/skills/bundle-size-review/scripts/bundle_stats.py +1633 -0
- package/packs/frontend/skills/web-performance-review/SKILL.md +3 -3
- package/packs/frontend/skills/web-performance-review/manifest.json +2 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Worked example — a three-judge panel for a summary-faithfulness dashboard
|
|
2
|
+
|
|
3
|
+
## Input given to the skill
|
|
4
|
+
|
|
5
|
+
> We run three LLM judges (judge-x, judge-y, judge-z) over our article summaries and score each
|
|
6
|
+
> one 1–5 for "faithful to the article". 4 or 5 counts as a pass. Ines, our senior editor,
|
|
7
|
+
> marked 45 summaries pass/fail herself. Every judge scored every summary twice. From next month
|
|
8
|
+
> we want to put the panel's average pass rate on the newsroom quality dashboard instead of
|
|
9
|
+
> Ines's weekly spot check. Scores are in `panel.csv` (item, judge, trial, score, expert,
|
|
10
|
+
> length). Can we?
|
|
11
|
+
|
|
12
|
+
The file has 270 rows: 45 summaries × 3 judges × 2 trials, Ines's label on every summary, and
|
|
13
|
+
the summary's word count.
|
|
14
|
+
|
|
15
|
+
## What was run
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
python3 scripts/judge_stats.py panel.csv --threshold 4
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Excerpt of the output the reply rests on:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
| judge-x | all labelled | 45 | 87% [74%, 94%] | 56% | 0.70 [0.44, 0.90] |
|
|
25
|
+
| judge-y | all labelled | 45 | 87% [74%, 94%] | 57% | 0.69 [0.43, 0.90] |
|
|
26
|
+
| judge-z | all labelled | 45 | 78% [64%, 87%] | 56% | 0.50 [0.21, 0.75] |
|
|
27
|
+
- judge-x passes 3 of 15 items the expert failed (20% [7%, 45%])
|
|
28
|
+
- judge-x and judge-y agree on 39 expert-labelled items; on 3 of them both are wrong (S04, S33, S38).
|
|
29
|
+
**Fleiss' kappa** (first trial per judge), 3 raters on 45 items: 0.56 [0.34, 0.75]
|
|
30
|
+
| judge-x | 45 | 1 | 2% [0%, 12%] | S11 |
|
|
31
|
+
| judge-y | 45 | 2 | 4% [1%, 15%] | S17, S35 |
|
|
32
|
+
| judge-z | 45 | 9 | 20% [11%, 34%] | S02, S06, S13, S19, S21, S31, S34, S36, S40 |
|
|
33
|
+
| judge-x | 45 | -0.09 [-0.39, 0.20] |
|
|
34
|
+
| expert | 45 | -0.03 [-0.32, 0.26] |
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Output
|
|
40
|
+
|
|
41
|
+
**Use it with conditions: judge-x on its own is close to good enough for the dashboard number,
|
|
42
|
+
judge-z is pulling the panel down, and 15 failed summaries are too few to know how often the
|
|
43
|
+
judges miss an unfaithful one.**
|
|
44
|
+
|
|
45
|
+
- **judge-x and judge-y match Ines well.** Each agrees with her on 87% of the 45 summaries,
|
|
46
|
+
where about 56% would match by chance: kappa 0.70 (95% interval 0.44–0.90) and 0.69.
|
|
47
|
+
judge-z reaches 0.50 (0.21–0.75).
|
|
48
|
+
- **judge-z is unstable.** Scored twice, it changed its verdict on 9 of 45 summaries (20%);
|
|
49
|
+
judge-x changed 1, judge-y 2. With it in, the three judges agree with each other at
|
|
50
|
+
only 0.56 (Fleiss' kappa), against 0.69 for judge-x and judge-y alone.
|
|
51
|
+
- **The miss rate is not pinned down.** judge-x passed 3 of the 15 summaries Ines failed
|
|
52
|
+
(20%), but with 15 the true rate could be anywhere from 7% to 45%.
|
|
53
|
+
- **All three judges passed S33 and S38**, which Ines failed, and all three failed S04, which
|
|
54
|
+
she passed. Three judges agreeing on those is one blind spot, not three opinions.
|
|
55
|
+
- **Length isn't driving the scores:** judge-x's correlation with word count is −0.09, Ines's
|
|
56
|
+
−0.03.
|
|
57
|
+
|
|
58
|
+
**Conditions before the number goes on the dashboard**
|
|
59
|
+
|
|
60
|
+
1. Report judge-x's pass rate (judge-y as a cross-check), not the three-judge average.
|
|
61
|
+
2. Decide how many unfaithful summaries the dashboard can count as faithful; with 15 of
|
|
62
|
+
Ines's failures the miss rate could be 7% or 45%, and more of her failures is what narrows it.
|
|
63
|
+
3. Read S33 and S38 to see what the judges miss, and add that to the scoring instructions.
|
|
64
|
+
|
|
65
|
+
**Can't conclude yet:** whether judge-x misses 1 in 10 unfaithful summaries or 4 in 10.
|
|
66
|
+
|
|
67
|
+
To confirm: the miss rate the newsroom accepts on the dashboard number.
|
|
68
|
+
|
|
69
|
+
Next step: have Ines mark more of the summaries she expects to fail, re-run the comparison,
|
|
70
|
+
and switch the dashboard to judge-x if its miss rate sits inside what the newsroom accepts.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "judge-audit",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Audit whether an LLM-as-judge, or a panel of judges, can be trusted for the decision its scores drive, before anyone acts on them — above all whether the judge errs differently on the variants being compared (prompt v1 vs v2, model A vs B, short vs long inputs), plus chance-corrected and weighted agreement with expert labels, precision and recall on a rare class, each run reported separately with the items that flipped, position and length bias, and confidence intervals, checked against the user's own gate or criterion and ending in a direct answer (ship or not, which judge to use). Use when the user asks \"can we trust our LLM judge\", \"is our grader reliable enough to gate releases\", \"the grader says v2 is better, can we ship it\", \"which is the cheapest judge we can switch to\", \"our two judges agree 90%, is that good\", \"can we turn on auto-remove\", \"check our judge for position bias\", or has a file of judge scores and wants to know whether to act on them.",
|
|
5
|
+
"entrypoint": "SKILL.md",
|
|
6
|
+
"deps": {
|
|
7
|
+
"npm": [],
|
|
8
|
+
"pip": []
|
|
9
|
+
},
|
|
10
|
+
"env": {
|
|
11
|
+
"required": [],
|
|
12
|
+
"optional": []
|
|
13
|
+
},
|
|
14
|
+
"related": [
|
|
15
|
+
"ai-usage-report",
|
|
16
|
+
"eval-harness-generator",
|
|
17
|
+
"llm-eval-harness"
|
|
18
|
+
],
|
|
19
|
+
"handoff": [
|
|
20
|
+
{
|
|
21
|
+
"to": "llm-eval-harness",
|
|
22
|
+
"when": "the verdict is DO NOT RELY ON IT and the judge, its rubric or its labelled set has to be rebuilt",
|
|
23
|
+
"purpose": "Design the labelled set, the split criteria and the pass bar the rebuilt judge will be validated against.",
|
|
24
|
+
"fallback": "If llm-eval-harness is absent, list inline the criteria to split the rubric into, the number of expert-labelled items to collect (including failures), and the bar each must clear for the decision."
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"tags": [
|
|
28
|
+
"llm-as-judge",
|
|
29
|
+
"evals",
|
|
30
|
+
"inter-rater-agreement",
|
|
31
|
+
"ai-engineering",
|
|
32
|
+
"bias"
|
|
33
|
+
],
|
|
34
|
+
"permissions": {
|
|
35
|
+
"network": [],
|
|
36
|
+
"commands": [],
|
|
37
|
+
"files": "named-paths",
|
|
38
|
+
"notes": "judge_stats.py reads the judgement files, and the --gold file, named on the command line (or stdin) and writes only the -o path the user names; no network. --self-test reads and writes nothing."
|
|
39
|
+
},
|
|
40
|
+
"model": {
|
|
41
|
+
"tier": "standard",
|
|
42
|
+
"rationale": "The agreement and stability statistics are computed by its script; the model's work is reading them against the decision the judge serves."
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# judge-audit reference
|
|
2
|
+
|
|
3
|
+
## Reading the numbers against the decision
|
|
4
|
+
|
|
5
|
+
There is no universal pass mark for a judge. The criterion is the user's: a gate tolerance ("no
|
|
6
|
+
more than 1.0 point below production"), a recall target, a number of wrongful removals they can
|
|
7
|
+
live with. Translate the numbers into that criterion; when they gave none, say what the numbers
|
|
8
|
+
do to their decision and stop there.
|
|
9
|
+
|
|
10
|
+
| The user's decision | The number that answers it | `--gate` form |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| A tolerance on a difference between two arms (precision@5 within 1.0 point, mean score +0.3) | how much the judge's bias differs between the arms, in the same units, with its interval | `bias_diff<=1.0` with `--group-by` on what separates the arms |
|
|
13
|
+
| Act automatically on one class (remove, block, escalate) | recall on that class (what slips through) and false positives (what is wrongly acted on), per run | `recall>=0.9`, `false_positives<=0` |
|
|
14
|
+
| Publish one rate (pass rate, relevance rate) | the judge's rate minus the expert's, in points | `bias<=2` |
|
|
15
|
+
| Swap a judge for a cheaper one | the same check per judge; the cheapest judge that meets the user's criterion is the answer | any of the above |
|
|
16
|
+
|
|
17
|
+
Outcomes per judge and run: **clears** (the whole 95% interval meets the criterion), **fails**
|
|
18
|
+
(none of it does), **can't tell** (the interval spans it; say which side the point estimate is on
|
|
19
|
+
and how many more labelled items of the scarce class would narrow it).
|
|
20
|
+
|
|
21
|
+
Kappa bands (Landis and Koch, 1977: 0.41–0.60 "moderate", 0.61–0.80 "substantial") are labels
|
|
22
|
+
someone chose, not evidence. Quote one only as context, named as that convention, and never as
|
|
23
|
+
the reason to ship or block.
|
|
24
|
+
|
|
25
|
+
**Translating a difference gate.** A judge with the same bias on both arms leaves a difference
|
|
26
|
+
intact, whatever its overall accuracy. A judge whose bias moves with something that differs
|
|
27
|
+
between the arms (passage length, reply length, variant) adds that movement to the difference.
|
|
28
|
+
When a planned change shifts that property (re-chunking to long passages, a prompt that writes
|
|
29
|
+
longer replies), the shift in bias is what lands on the gate: compare it with the tolerance.
|
|
30
|
+
|
|
31
|
+
## Formulas for hand computation
|
|
32
|
+
|
|
33
|
+
**Cohen's kappa** for two raters on the same n items:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
p_o = (items where both gave the same label) / n
|
|
37
|
+
p_e = sum over labels k of (share rater 1 gave k) × (share rater 2 gave k)
|
|
38
|
+
kappa = (p_o - p_e) / (1 - p_e)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Worked: 50 items. Both "yes" on 20, both "no" on 15, rater 1 yes and rater 2 no on 5, the
|
|
42
|
+
reverse on 10. p_o = 35/50 = 0.70. Rater 1 says yes 25/50 = 0.5, rater 2 says yes 30/50 = 0.6,
|
|
43
|
+
so p_e = 0.5 × 0.6 + 0.5 × 0.4 = 0.50. kappa = (0.70 − 0.50) / 0.50 = 0.40. The bootstrap
|
|
44
|
+
interval on these 50 items runs from about 0.12 to 0.64.
|
|
45
|
+
|
|
46
|
+
**Weighted kappa** for ordinal scores (1–5 and the like), on numeric scores a (judge) and b
|
|
47
|
+
(expert), disagreement d = (a − b)² for quadratic, |a − b| for linear:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
D_o = mean over items of d(a_i, b_i)
|
|
51
|
+
D_e = sum over score pairs x, y of (share judge gave x) × (share expert gave y) × d(x, y)
|
|
52
|
+
kappa_w = 1 - D_o / D_e
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Worked, 10 items on a 1–3 scale: both 1 on 2, both 2 on 3, both 3 on 2, and one each of
|
|
56
|
+
(judge 1, expert 2), (2, 3), (3, 1). Each rater's shares are 0.3 / 0.4 / 0.3.
|
|
57
|
+
Quadratic: D_o = (1 + 1 + 4) / 10 = 0.6; D_e = 2 × (0.3·0.4·1 + 0.3·0.3·4 + 0.4·0.3·1) = 1.2;
|
|
58
|
+
kappa = 1 − 0.6 / 1.2 = **0.50**. Linear: D_o = 0.4, D_e = 0.84, kappa = 11/21 = **0.52**.
|
|
59
|
+
Unweighted on the same table: p_o = 0.7, p_e = 0.34, kappa = 6/11 = **0.55**. On pass/fail data
|
|
60
|
+
all three coincide. `judge_stats.py --self-test` checks the script against these values.
|
|
61
|
+
|
|
62
|
+
**Mean bias** = mean of (judge − expert) on the items both scored, with a bootstrap interval.
|
|
63
|
+
Per group, compare it across the variants: a difference in bias between arms is a difference the
|
|
64
|
+
judge adds to the comparison by itself.
|
|
65
|
+
|
|
66
|
+
**Fleiss' kappa** for m raters on N items, n_ij = raters who gave item i label j:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
P_i = (sum_j n_ij² - m) / (m(m - 1))
|
|
70
|
+
Pbar = mean of P_i
|
|
71
|
+
p_j = sum_i n_ij / (N m)
|
|
72
|
+
P_e = sum_j p_j²
|
|
73
|
+
kappa = (Pbar - P_e) / (1 - P_e)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Wilson 95% interval** for k successes in n:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
centre = (p + z²/2n) / (1 + z²/n)
|
|
80
|
+
half = z × sqrt(p(1-p)/n + z²/4n²) / (1 + z²/n), z = 1.96
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Bootstrap** for kappa or a correlation: resample items with replacement, recompute, take the
|
|
84
|
+
2.5th and 97.5th percentiles of 2,000 resamples. Resample items, not judgements, so repeated
|
|
85
|
+
trials of one item move together.
|
|
86
|
+
|
|
87
|
+
**False-pass rate** = items the expert failed that the judge passed ÷ items the expert failed.
|
|
88
|
+
**False-fail rate** = items the expert passed that the judge failed ÷ items the expert passed.
|
|
89
|
+
|
|
90
|
+
**Order-balanced win rate** for variant X = (X's win rate when shown first + X's win rate when
|
|
91
|
+
shown second) / 2. An unbiased judge gives the same two rates.
|
|
92
|
+
|
|
93
|
+
## Why kappa drops when one label dominates
|
|
94
|
+
|
|
95
|
+
When 90% of items pass, two raters agree 82% by chance, so a high raw agreement leaves kappa
|
|
96
|
+
little room. That is the point, not a flaw: most of the agreement is free. When the skew is 85%
|
|
97
|
+
or more, report the confusion counts, precision and recall on the rare class beside kappa, and
|
|
98
|
+
how many rare-class items the sample holds: 6 positives give a recall interval of roughly 30% to
|
|
99
|
+
90% even at 4 of 6. Accuracy against an always-majority baseline of 95% says almost nothing.
|
|
100
|
+
|
|
101
|
+
## Both-orders protocol for pairwise judges
|
|
102
|
+
|
|
103
|
+
1. Judge every pair twice, once in each order, at the same settings.
|
|
104
|
+
2. Count a win only when the same output wins in both orders; a split is a tie.
|
|
105
|
+
3. Report the share of pairs that split: that is the position effect, measured directly.
|
|
106
|
+
4. With one order per pair, randomise it and check that each variant is shown first close to
|
|
107
|
+
half the time; if not, use the order-balanced rate.
|
|
108
|
+
|
|
109
|
+
## Separating criteria
|
|
110
|
+
|
|
111
|
+
A holistic score ("is this a good reply?") lets fluency stand in for correctness. When the
|
|
112
|
+
judge's score tracks length more than the expert's does, split the rubric into criteria a judge
|
|
113
|
+
can check one at a time, and gate on the ones that matter:
|
|
114
|
+
|
|
115
|
+
- ✅ *"Policy-correct (yes/no) · answers the question asked (yes/no) · tone (1–5)."* Gate on the
|
|
116
|
+
two yes/no criteria; report tone.
|
|
117
|
+
- ❌ *"Rate the reply 1–10 for quality."*
|
|
118
|
+
|
|
119
|
+
Re-run the audit on each criterion separately: a judge can be reliable on tone and useless on
|
|
120
|
+
correctness.
|
|
121
|
+
|
|
122
|
+
## Input columns the script reads
|
|
123
|
+
|
|
124
|
+
One row per judgement, CSV or JSONL. Column names are case-insensitive.
|
|
125
|
+
|
|
126
|
+
| Column | Required | Meaning |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| `item` | yes | the thing judged (aliases: `item_id`, `id`, `case`, `ticket_id`, `question_id`, `passage_id`, `post_id`) |
|
|
129
|
+
| `label` | one of label/score | the verdict; in pairwise data, the variant chosen or `tie` (aliases: `verdict`, `winner`, `choice`, `flagged`, `decision`, `prediction`) |
|
|
130
|
+
| `score` | one of label/score | numeric score (aliases: `judge_score`, `grader_score`); `--threshold T` makes score ≥ T a pass, only when the user stated T |
|
|
131
|
+
| `judge` | no | absent means every row is one judge (aliases: `model`, `grader`, `rater`) |
|
|
132
|
+
| `trial` | no | repeat number; default 1 (aliases: `run`, `repeat`) |
|
|
133
|
+
| `expert` | no | the expert's label or score for the item, on any of its rows (aliases: `human`, `gold`, `gold_label`, `expert_label`, `human_score`) |
|
|
134
|
+
| `position` | no | pairwise: where the **chosen** output was shown (`A`/`B`, `1`/`2`, `first`/`second`) |
|
|
135
|
+
| `first_shown` | no | pairwise: which **variant** was shown first (aliases: `shown_first`, `first_variant`) |
|
|
136
|
+
| `length` | no | pointwise: length of the judged output; pairwise: length of the chosen output (aliases: `words`, `reply_words`, `word_count`) |
|
|
137
|
+
| `other_length` | no | pairwise: length of the output not chosen |
|
|
138
|
+
|
|
139
|
+
Shapes the script also reads:
|
|
140
|
+
|
|
141
|
+
- **One file per run.** `judge_stats.py run_1.jsonl run_2.jsonl` makes each file a run, in the
|
|
142
|
+
order given, and resolves columns per file, so `item_id`/`flagged` in one and `id`/`verdict`
|
|
143
|
+
in the other both work. Runs are joined to each other and to the expert **on the item id**;
|
|
144
|
+
the output says when the files list items in different orders. A line-by-line comparison of
|
|
145
|
+
two files in different orders measures nothing.
|
|
146
|
+
- **Expert labels in their own file:** `--gold gold.csv` (an item column plus an expert, label or
|
|
147
|
+
score column).
|
|
148
|
+
- **One column per judge:** `--judges col_a,col_b,col_c` reads a wide file where each named
|
|
149
|
+
column holds that judge's label for the row's item.
|
|
150
|
+
- **Different words for the same label:** `--map true=violation,false=ok` renames before
|
|
151
|
+
anything is compared. Labels that differ only in case (`VIOLATION`, `violation`) merge on their
|
|
152
|
+
own. The output flags a run whose labels share no value with the expert's.
|
|
153
|
+
|
|
154
|
+
Any other name maps with `--col NAME=COLUMN` (for example `--col score=grader_points`).
|
|
155
|
+
`--group-by COL` repeats every statistic per value of COL; `--group-by "COL>=N"` splits a numeric
|
|
156
|
+
column in two (`passage_tokens>=400`). It leads with a comparison table and the between-group
|
|
157
|
+
differences (judge mean or rate, expert mean or rate, bias), each with an interval that resamples
|
|
158
|
+
items within each group; for two-label data the differences are in percentage points of the
|
|
159
|
+
`--positive` class's rate.
|
|
160
|
+
|
|
161
|
+
On two-label data `--positive` names the class the decision acts on or counts (`violation`,
|
|
162
|
+
`relevant`, `pass`); without it, `pass`/`yes`/`good` when present, else the expert's minority
|
|
163
|
+
class. Every run then gets its own row: judge and expert counts of that class, TP/FP/FN/TN,
|
|
164
|
+
precision, recall and false-positive rate with Wilson intervals, and accuracy beside the
|
|
165
|
+
always-majority baseline. False-pass rate on pass/fail data is that false-positive rate.
|
|
166
|
+
|
|
167
|
+
`--gate SPEC` (repeatable) checks the user's criterion per judge and run. Metrics: `accuracy`,
|
|
168
|
+
`kappa`, `quadratic`, `precision`, `recall`, `fpr`, `false_positives`, `false_negatives`,
|
|
169
|
+
`flip_rate`, `bias` (score points, or percentage points of the positive rate), `bias_diff`
|
|
170
|
+
(needs `--group-by`). Rates take `0.9` or `90%`.
|
|
171
|
+
|
|
172
|
+
Between judges, repeats add a trial-matched kappa (pooled and per trial) and Fleiss' kappa
|
|
173
|
+
across every judge × trial rating; with expert labels, the accuracy difference between two
|
|
174
|
+
judges on the same items, with its interval. Pairwise rates count ties as judgements no variant
|
|
175
|
+
won, and their intervals resample questions, not judgements. Exit code 2 means the input could
|
|
176
|
+
not be read, with the reason on stderr.
|