Three numbers belong in every calibration report.
Percent agreement
The share of cases where the judge's label equals the human consensus label. It is intuitive and worth report, but it flatters judges whenever one label dominates. The AWS sample on Cohen's kappa for LLM judges gives the standard example: if 80% of responses are correct, a judge that always says "correct" scores 80% accuracy while contributing nothing.
Cohen's kappa
Kappa corrects observed agreement for the agreement expected from each rater's label frequencies. Formally, kappa = (Po - Pe) / (1 - Pe), where Po is observed agreement and Pe is the chance agreement implied by the marginals, as defined in the kappa guide. Use unweighted kappa for nominal labels, and weighted kappa when the labels are genuinely ordered.
from sklearn.metrics import cohen_kappa_score, confusion_matrix
ALLOWED = {"pass", "needs_edit", "fail"}
LABELS = ["pass", "needs_edit", "fail", "judge_error"]
def normalize(value: str) -> str:
label = (value or "").strip().lower()
return label if label in ALLOWED else "judge_error"
human = [normalize(x) for x in human_consensus]
judge = [normalize(x) for x in judge_outputs]
raw_agreement = sum(a == b for a, b in zip(human, judge)) / len(human)
kappa = cohen_kappa_score(human, judge, labels=LABELS)
print(raw_agreement, kappa)
print(confusion_matrix(human, judge, labels=LABELS))
Keep parse failures and refusals in the denominator as their own label. A judge that answers correctly on 90% of cases and errors on the rest has 90% conditional accuracy and 81% end-to-end agreement.
That arithmetic matters more than it looks. At 300 cases, a judge with 81% agreement has a standard error of about 2.3 percentage points, so its 95% interval runs roughly 76.5% to 85.5%. If your release threshold is 85%, the run cannot prove the judge clears it. Budget for 500 or more cases when the threshold sits close to your measured result.
Correlation
When the judge outputs a score rather than a label (1 to 5, or 0 to 100), report Pearson correlation if you care about the linear relationship and Spearman if you care that the rank order matches. Correlation catches a judge that ranks outputs sensibly while sitting systematically high or low, which kappa on a binarized score can hide. Report both the correlation and the mean offset.
Read the confusion matrix, not just the headline
For every calibration run, inspect four cells: human-pass and judge-fail, human-fail and judge-pass, and the two agreement cells. In practice, judge-pass on a human-fail case is the costly cell, because it lets defects through. If that cell is populated, tighten the failing definitions and add the cases to the few-shot examples before re-running. MLflow's LLM-as-a-judge documentation notes that its evaluation tooling supports aligning judges with human feedback so automated scores stay tied to the team's quality standards, which is the same inspect-and-repair loop.