Report harm scorer accuracy split by inter-rater agreement (a third of violence gold labels are single-vote)
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- python
- Domain
- ai, security, testing-qa
Research direction
Start with HarmScorerEvaluator and the multi-rater datasets under pyrit/datasets/scorer_evals/harm. Read pyrit.score.scorer_evaluation.krippendorff.krippendorff_alpha and the existing *_metrics.jsonl output to understand agreement handling. Done means preserving current aggregate metrics while reporting accuracy and MAE separately for unanimous and contested rows, with any single-rater metadata clearly marked if included.
Written by the indexing model from the issue text.
Description
Is your feature request related to a problem?
A harm scorer is evaluated against one gold label per response. Where that label is the mean of several human raters, the mean hides how much the raters disagreed, and the eval reports a single MAE/accuracy as if the label were certain. On the multi-rater gold sets in pyrit/datasets/scorer_evals/harm, a large fraction of the binary harmful/not labels come down to a single rater's vote.
Measured on the current files (Krippendorff alpha computed with PyRIT's own pyrit.score.scorer_evaluation.krippendorff.krippendorff_alpha, ordinal, so it matches the *_metrics.jsonl values):
| file | n | raters | ordinal alpha | exact 3-way agreement | binary label is a single-vote (2-1) split |
|---|---|---|---|---|---|
| violence_multi_score.csv | 187 | 3 | 0.766 | 32.1% | 31.0% |
| hate_speech_multi_score.csv | 199 | 3 | 0.861 | 42.2% | 17.6% |
| mini_hate_speech.csv | 15 | 3 | 0.659 | 20.0% | 26.7% |
On violence, nearly a third of the binary gold labels are 2-1 splits, so a scorer marked wrong on those rows was outvoted by one human rather than overruled by a consensus. A point metric spends the scorer's error budget partly on rows the humans themselves split on, and a scorer that is well calibrated to that ambiguity (for example one that abstains where humans divide) is penalised for it rather than credited.
The other eight harm gold sets (exploits, hate_speech, info_integrity, privacy, representational, self_harm, sexual, violence) ship a single rating, so their disagreement cannot be observed at all and their labels are treated as ground truth with no uncertainty signal.
Describe the solution you'd like
- In
HarmScorerEvaluator, when a gold set has more than one rater, additionally report accuracy/MAE split by agreement level: unanimous rows vs contested (non-unanimous) rows, from the same eval run. A scorer at 0.87 overall that is 0.95 on agreed rows and near chance on contested ones is behaving correctly, and the split makes that visible where the aggregate hides it. -
- Optionally mark the single-rater gold sets as provisional in the harm-definition metadata, so a low scorer number on them is read as possible label uncertainty rather than a scorer defect.
Describe alternatives you've considered
Down-weighting contested rows in the aggregate metric, or dropping them. Reporting the split is less opinionated: it changes nothing about the existing numbers and adds a second view, so no current metric moves.
Additional context
I have a small standalone audit script (numpy plus PyRIT's Krippendorff) that produces the table above and emits the contested row indices per file, which is what recommendation 1 would filter on. Happy to attach it or open a PR for the reporting change if this direction is wanted. Flagging @romanlutz since this feeds directly into the dataset-curation work.
- Dominant language
- Python
- Stars
- 4.5k
- Forks
- 896
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 155
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from microsoft/PyRIT
-
Bug: triage help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Bug: triage
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
BUG: ScorerMetrics.to_json() raises TypeError on the trial_scores array ScorerEvaluator attaches Open
Difficulty 3/5 1-2 days Newbie friendliness 78/100
-
Bug: triage help wanted
Difficulty 3/5 1-2 days Newbie friendliness 75/100
-
Difficulty 4/5 3-5 days Newbie friendliness 68/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100