Repository navigation
FIX: Add a trial-invariant gold-vs-model Krippendorff alpha - #4181
Roman Lutz (romanlutz) merged 5 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Floating-point noise in median scores can produce a negative ordinal alpha for tolerance-equivalent labels, reporting disagreement even when normalized MAE is zero.
1 open issue
What changed in this PR
Adds gold-vs-model agreement to harm scorer evaluation without inflating agreement when identical scorer trials are repeated, addressing #4129 while preserving the existing combined metric.
Changes:
- Computes ordinal alpha between median human labels and median model scores.
- Adds the optional metric to stored results and displays it in pretty output.
- Adds regression coverage for repeated trials and perfect agreement.
| File | Description |
|---|---|
tests/unit/score/test_scorer_evaluator.py |
Tests trial invariance and perfect agreement. |
pyrit/score/scorer_evaluation/scorer_metrics.py |
Defines and documents the optional metric. |
pyrit/score/scorer_evaluation/scorer_evaluator.py |
Computes gold-vs-model alpha from two median-score rows. |
pyrit/output/scorer/pretty.py |
Displays the new metric with quality coloring. |
Review effort: Balanced
|
Fixed in |
|
Thanks for the thorough review and repros Roman Lutz (@romanlutz)! Addressed in
Validation: 157 passed in |
|
I filed #4129, so I checked this against it on 4523853:
Not covered here, and I'm happy to do these as a follow-up once this merges, if you'd like:
I had offered to take #4129 when I filed it; since this is already well into review, I'm happy for it to |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ly noisy trials Per Allan-dq's observation on microsoft#4181: with independent per-trial noise the per-response median converges to the gold label, so the alpha rises with trials while MAE falls - unlike the microsoft#4129 artifact where MAE stayed flat. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Roman Lutz (romanlutz)
left a comment
There was a problem hiding this comment.
Re-reviewed at 4523853 and against latest main. All review points are addressed, and the one-ULP category merge is a better solution than the decimal rounding I suggested: it fixes both repros (verified: 0.8713 and 0.3832) while preserving genuinely distinct values as close as 1e-10. Trial-invariance holds (0.0857 at 1/3/5/10 trials on the #4129 scenario), and median roundoff never exceeded one ULP across scans of all midpoint pairs on 0.01/0.05/0.1/0.25 grids plus 20k random 4- and 6-rater medians, so the tolerance is sufficient in practice. One known residual: a level with median noise in both directions only partially merges (constructed case: 0.910 vs ideal 1.0) — contrived inputs, small and conservative error, fine to ship.
Qin Dai (@Allan-dq) thanks for the independent verification. I reproduced the direction of your violence_multi_score.csv experiment (MAE 0.076 -> 0.004 while alpha 0.917 -> 0.996 with independent per-trial noise) and agree it's correct behavior: the median of more independent trials genuinely converges to gold, unlike the old artifact where MAE stayed flat. I pushed your suggested docstring note directly (4a90b99) along with a merge of latest main (50e0155); 188 tests pass on the combined state. Your follow-up offer for the docs page, the GUI "Agreement" column/tooltip, and the krippendorff_alpha_combined docstring works for me — please go ahead after this merges.
LGTM, thanks Chen Yufeiyang (@feiiiiii5)!

Description
HarmScorerMetrics.krippendorff_alpha_combinedconcatenates human and model scores, so each scorer trial acts as an extra rater. A scorer that ignores the response rises from 0.086 at 1 trial to 0.828 at 10 trials while MAE stays 0.381.krippendorff_alpha_gold_model: a two-row alpha between the gold (median human) label and the per-response median model score, so it is invariant tonum_scorer_trials.krippendorff_alpha_combinedunchanged for existing registry data and show the new value inpretty.py.tests/unit/score/test_scorer_evaluator.py121 passed; relatedscoreandoutputtests 854 passed; Ruff check/format clean.Closes #4129.