Skip to content

Evaluation and modelsMethodology

Can an LLM judge be trusted? Calibrating graders against humans

OpenAI Evals is closing, and many teams are rebuilding their model-graded checks as their own judges. A judge is a measurement instrument, so it needs calibrating against people before it can gate a model switch. This is a method for doing that: sampling, agreement, bias, drift and thresholds.

By INFRO Editorial

Published

11 min read

A single amber path on a dark ground forking into two glass branches of slightly different brightness

In short

An LLM judge can be trusted for a specific rubric, on a specific kind of output, to the degree that you have measured its agreement with human labels on that output. Sample humans in strata, report agreement with intervals, probe for bias, pin and re-check the judge, and gate a model switch on a confidence bound, not a raw average.

Key takeaways

  • A judge is trusted per rubric and per output type, only to the extent you have measured its agreement with human labels on that output.
  • Sample humans in strata, label a share twice, and split labels into a tuning set and a held-out test set before you touch the judge prompt.
  • Report chance-corrected agreement, false-pass and false-fail rates, and intervals; raw accuracy hides a lenient judge on a skewed dataset.
  • Probe the judge for position, length, self-preference and format bias with controlled edits, and pin the judge to a dated model.
  • Gate a model switch on a lower confidence bound of the paired difference, and re-check judge agreement on the candidate's own outputs.

A judge is an instrument, so calibrate it

OpenAI's hosted Evals platform is closing: existing evals become read-only on 31 October 2026 and the dashboard and API are scheduled to shut down on 30 November 2026.1 Teams that used model-graded checks as a regression gate are now writing their own LLM-as-judge graders. The danger in that migration is quiet. A rebuilt grader will produce numbers, the numbers will look plausible, and nobody will know whether they track what a person would decide.

The migration advice OpenAI gives is itself a warning: recreated LLM-as-a-judge graders should be validated before you rely on them, because scores will not be identical across systems.1 Anthropic's evaluation guide lists LLM-based grading beside exact match and code grading as one way to automate, and treats a Likert-scale judge as suited to subjective qualities such as tone.2 Neither tells you how far to trust the score. This method does.

The claim you are trying to earn is narrow: for this rubric, on outputs like these, the judge agrees with trained humans at least this often, and its errors lean in a known direction. Anything wider than that is a guess. The steps are:

  1. Fix the rubric and the unit of judgement.
  2. Sample items and collect human labels, with a share labelled twice.
  3. Measure agreement and error direction, with intervals.
  4. Probe for bias with controlled edits.
  5. Set a gate that uses the measured error.
  6. Pin the judge and watch for drift.

Fix the rubric before you sample anything

Most disagreement between a judge and a human is really disagreement about the rubric. Before collecting labels, write the criterion so that two people could apply it without talking to each other. Anthropic's guidance on success criteria asks for criteria that are specific and measurable, and notes that even hazy qualities can be quantified when defined precisely.2 Apply the same standard to each judge question.

Prefer a binary or small-ordinal verdict per criterion over a 1–10 score. Fine-grained scales produce low agreement among humans, which caps how well any judge can do. Split compound rubrics ("accurate, concise and polite") into one question per judge call, so you can see which dimension fails.

Include the hard cases on purpose. Anthropic's eval design notes name ambiguous test cases, where even humans would struggle to reach consensus, as a category to include.2 Keep them, but tag them. If humans disagree with each other on an item, a judge disagreeing with one of them is not evidence of a bad judge.

Decide the unit of judgement as well. Pointwise grading (is this answer acceptable?) is simpler to calibrate than pairwise grading (which of A or B is better?), but pairwise is what a model switch usually needs. If you use pairwise, you must also test for position bias, covered below.

Sample human labels so they represent the decision

A random sample of last week's traffic over-represents easy, common cases and under-represents the failures the gate exists to catch. Sample in strata instead.

  • By input type. Intent, language, length bucket, tool use, customer tier; whatever your product splits on.
  • By judge verdict. Draw items the judge passed and items it failed in comparable numbers. If 95% of items pass, a random sample holds few failures, and you cannot estimate the false-pass rate.
  • By producing model. Include outputs from the current model, the candidate and, if you have one, a deliberately weaker model. The judge must discriminate across that range.
  • Near-threshold items. If the judge returns a score or probability, oversample the middle of its range, where mistakes concentrate.

Then split the labelled set. Keep a tuning set for editing the judge prompt and a held-out test set that nobody looks at until the judge is frozen. Reusing the same items for both inflates agreement, just as it does for any model.

Label a share of items twice, by different people, to measure human-human agreement. That number is your ceiling. A judge that agrees with a single annotator 85% of the time when two annotators agree 86% of the time is performing at the limit of the rubric.

Measure agreement and the direction of error

Raw accuracy misleads on skewed data. If 90% of answers are acceptable, a judge that passes everything is 90% "accurate". Report these together:

MeasureWhat it tells youWatch for
Percent agreementPlain match rate with the human majority labelHigh on skewed data even for a useless judge
Cohen's kappa (or Krippendorff's alpha for ordinal)Agreement beyond chanceSensitive to prevalence; read it with the confusion matrix
False-pass rateJudge passes, humans failThe costly error for a safety or quality gate
False-fail rateJudge fails, humans passWastes review time and blocks good candidates
Human-human agreementCeiling set by the rubricA low ceiling means fix the rubric first
Rank correlation across modelsDoes the judge order models as humans doThe property a model switch depends on

The last row matters more than it looks. A gate compares two models, so a judge with a constant lenient offset can still rank them correctly. A judge that is lenient only on one model's style cannot.

judge_agreement.py
import math
from collections import Counter

def wilson(k: int, n: int, z: float = 1.96) -> tuple[float, float]:
    """95% Wilson interval for a proportion."""
    if n == 0:
        return (0.0, 1.0)
    p = k / n
    d = 1 + z * z / n
    centre = (p + z * z / (2 * n)) / d
    half = z * math.sqrt(p * (1 - p) / n + z * z / (4 * n * n)) / d
    return (centre - half, centre + half)

def report(human: list[int], judge: list[int]) -> dict:
    """human, judge: 1 = pass, 0 = fail, same item order."""
    n = len(human)
    tp = sum(h == 1 and j == 1 for h, j in zip(human, judge))
    tn = sum(h == 0 and j == 0 for h, j in zip(human, judge))
    fp = sum(h == 0 and j == 1 for h, j in zip(human, judge))  # false pass
    fn = sum(h == 1 and j == 0 for h, j in zip(human, judge))  # false fail
    po = (tp + tn) / n
    ph, pj = Counter(human), Counter(judge)
    pe = sum((ph[c] / n) * (pj[c] / n) for c in (0, 1))
    kappa = (po - pe) / (1 - pe) if pe < 1 else float("nan")
    return {
        "agreement": (po, wilson(tp + tn, n)),
        "kappa": kappa,
        "sensitivity": tp / (tp + fn) if tp + fn else None,
        "specificity": tn / (tn + fp) if tn + fp else None,
        "false_pass_rate": (fp / (fp + tn) if fp + tn else None),
        "n": n,
    }

Run this on the held-out test set only, per stratum, and keep the confusion matrices. Read the disagreements by hand. Ten minutes with twenty mismatched items usually shows whether the judge prompt is wrong, the rubric is vague, or the human label is.

Probe for bias with controlled edits

Agreement on a natural sample does not reveal systematic biases, because natural data rarely varies one factor at a time. Build small perturbation sets from items you already have and check that the verdict does not move when it should not. These are known failure modes of LLM judges, tested here as hypotheses about your judge, not assumed.

  • Position bias (pairwise). Score every pair twice with A and B swapped. The share of pairs whose winner flips with the order is your position-bias rate. Count only consistent verdicts, or average the two orders.
  • Length bias. Pad a correct answer with harmless filler, or trim a correct answer to its core. A pass that turns into a fail, or a score that climbs with length, shows the judge rewards verbosity or brevity.
  • Self-preference. Score the same answers with judges from two different providers. If the order of candidate models changes with the judge's family, the judge favours its own style.
  • Format and style. Reformat the same content (bullets, headers, a confident tone). A change in verdict means the judge is grading presentation.
  • Leniency and severity. Compare the judge's pass rate with the humans' pass rate on the same items. A gap of several points that is stable in direction is an offset you can correct for.
  • Sensitivity to the rubric wording. Paraphrase the rubric without changing its meaning. Large swings mean the judge prompt is brittle.

Also run the judge on a few items twice with the same input. If it flips on repeats, set temperature low where the provider lets you, and either take the majority of several calls or treat items near the boundary as uncertain.

Fix what you find in the judge prompt, using the tuning set, then re-measure on the held-out set. If a bias cannot be fixed, record it as a known offset and carry it into the gate below.

Set the pass threshold from measured error

A threshold such as "pass rate must be at least 90%" is not meaningful until you know what the judge's pass rate means. Two corrections turn it into one.

Correct for judge error. If the judge has sensitivity se and specificity sp against humans, the observed pass rate q relates to the true pass rate p as q = p·se + (1−p)(1−sp). Solving gives p = (q + sp − 1) / (se + sp − 1). This holds only when the judge's error rates are similar on the two models being compared, which is what you check next.

Gate on a bound, not a mean. Run baseline and candidate on the same prompts and compare per item. Use a paired bootstrap on the difference in pass rate, and require the lower end of the interval to clear a margin the product owner has agreed in advance.

gate.py
import random

def paired_diff_lower_bound(base: list[int], cand: list[int],
                            iters: int = 5000, alpha: float = 0.05) -> float:
    n = len(base)
    diffs = []
    for _ in range(iters):
        idx = [random.randrange(n) for _ in range(n)]
        diffs.append(sum(cand[i] - base[i] for i in idx) / n)
    diffs.sort()
    return diffs[int(alpha * iters)]

def may_switch(base, cand, margin=0.02, slice_results=None) -> bool:
    if paired_diff_lower_bound(base, cand) < -margin:
        return False
    # Every critical slice must clear its own bound.
    for name, (b, c, slice_margin) in (slice_results or {}).items():
        if paired_diff_lower_bound(b, c) < -slice_margin:
            return False
    return True

Use code-graded checks for anything code can decide. Anthropic's guide ranks exact match and code grading beside LLM grading, and the judge should carry only what needs judgement.2

Re-check the judge on the candidate's outputs

A judge calibrated on your current model's answers has not been calibrated on the candidate's. A new model may be more verbose, format differently, or refuse differently, and each of those shifts the judge's error rates. Before trusting a gate result, draw a fresh stratified sample of the candidate's outputs, have humans label it, and confirm the judge floor still holds there. If it does not, tune on the new sample and rerun the whole comparison.

This step is what separates a model switch from a routine regression run. It is also cheap relative to the cost of a bad switch, since the sample is a hundred or so items per decision, not the whole suite.

Pin the judge and watch for drift

The judge is also a model, and it can change under you. Treat that as a first-class risk.

  • Pin a dated snapshot as the judge, not an alias, so a provider's update cannot move your scores. The same reasoning applies to the models under test; see model aliases vs pinned snapshots.
  • Keep a canary set. Fifty to a hundred human-labelled items, never used for tuning, scored by the judge on a schedule and on every judge or prompt change. Alert when agreement on the canary falls below the floor or when the pass rate on it moves by more than your margin.
  • Version the judge as a unit: model id, prompt text, rubric, temperature and parsing code. A change to any of them is a new judge and needs a new held-out measurement.
  • Re-label on a cadence. Product and traffic change. Draw a small fresh human sample each quarter, or whenever the input mix shifts, and compare it with the judge.
  • Plan for retirement. When the judge model is deprecated, you must recalibrate its replacement; build that into the retirement calendar like any other dependency.

Where a gateway helps, and where it stops

Three parts of this method touch infrastructure. INFRO is a control plane that sits between your application and providers you already pay; the shipped pieces below run on your own provider accounts.

  • Eval monitors score a share of served chat answers against your rubric in the background, with Jev or another decision model you connect, recorded per request and summarised per served model.3 That gives you a live pass rate to compare with the canary set. It is a judge like any other: calibrate it against humans first.
  • Decision models return typed answers with probabilities, and a decision carries a confidence band computed from the policy's thresholds (defaults of 0.9 and 0.5, with human review below the lower one).3 The documentation lists the decision models you can connect, from several providers, on your own accounts.4 Using one as a judge is a choice to test against humans, not a given.
  • Traffic changes flag a model answered by a new snapshot, longer answers and more fallbacks, using request metadata. INFRO says plainly it does not read answers and cannot tell that quality dropped.5 Use those findings as the cue to run your canary, not as a quality measure.

Governance teams may also want this written down as practice. NIST's AI Risk Management Framework is a voluntary framework meant to help build trustworthiness considerations into the design, development, use and evaluation of AI systems, and NIST has published a Generative AI Profile alongside it.6 A documented judge validation, with sample design, agreement figures and a version history, is the kind of record that supports an evaluation claim.

Checklist before a judge gates a switch

  • Each rubric question is written so two people could apply it, with one dimension per call.
  • Items are sampled in strata (input type, judge verdict, producing model), with hard cases tagged.
  • Labels are split into a tuning set and a held-out test set, and a share is double-labelled for a human-human ceiling.
  • Agreement, kappa, false-pass and false-fail rates are reported with intervals, per slice.
  • Position, length, self-preference and format biases have been probed with controlled edits.
  • The judge is a pinned snapshot, versioned with its prompt, rubric and parser.
  • A canary set runs on a schedule and on every judge change, with an alert threshold.
  • The gate uses a lower confidence bound on the paired difference, with margins agreed in advance, and code-graded checks as hard stops.
  • Judge agreement has been re-confirmed on a fresh sample of the candidate's outputs before the decision.

Questions readers ask

How many human labels do I need to validate a judge?
Enough that the interval on agreement is narrower than the decision you want to make. With the normal approximation, a judge that agrees about 90% of the time needs roughly 140 labelled items for a ±5-point 95% interval, and roughly 35 for ±10 points. Add items per stratum if you want per-slice numbers, and treat any slice under about 30 items as a spot check.
Can the judge be the same model as the one being graded?
Avoid it. A judge can favour text in its own style, so a candidate model from the same family may be scored higher for reasons unrelated to quality. Test for it by scoring the same answers with a judge from another provider and comparing; if the ranking of models changes, you have self-preference to account for.
Should I use a decision model instead of a chat model as the judge?
It is a choice to test, not an assumption. A decision model returns a typed answer with a probability, which makes thresholds and confidence bands straightforward, but you still calibrate it against human labels the same way as any judge.

From the team that builds it

Where this shows up in INFRO

INFRO is a control plane in front of the provider accounts you already hold. The capabilities below are the parts of it this article touches, each with the documentation that defines its behaviour.

  • Eval monitors

    Available with a plan

    Score a share of served chat answers against your rubric in the background with Jev or any other decision model you connect, recorded per request and summarized per served model.

    Read the documentation for Eval monitors
  • Decisions with Jev

    Available with a plan

    Saved questions your code calls as POST /v1/decisions/{slug}, answered by Jev on your own TypeSafe connection or by any other decision model you connect: an outcome, a confidence band from your thresholds, pins decided before any model call, a deadline with a fallback, and batches of up to 500 items. Tool-call gating, triage, evals, labeling and control loops are templates of it.

    Read the documentation for Decisions with Jev
  • Decision models from every provider

    Available with a plan

    Decision policies, rerank, classifier guardrails, the route classifier and evals on the decision model of your choice, on your own account with its provider: OpenAI's GPT-6 Luna, Cloudflare's Clef, Perplexity, Inception, Liquid AI, Upstage, Microsoft-Decision-1 on Azure, or any of them through OpenRouter. OpenAI's SDK and TypeSafe's SDK both work against INFRO.

    Read the documentation for Decision models from every provider
  • Traffic changes

    Available with a plan

    Changes in your traffic that come with no error: a model answered by a new snapshot, longer answers, a lost prompt cache, more fallbacks, answers cut off by the length limit, slower responses or a new error mix. Each finding names the likely cause and the estimated weekly change in provider cost. INFRO sees request metadata, not answers, so it does not judge answer quality.

    Read the documentation for Traffic changes
  • Model retirements

    Available with a plan

    INFRO records each vendor's model deprecations and shutdown dates, warns organizations still sending a retiring model, and from the shutdown date refuses it before any provider call, naming the replacement.

INFRO accounts are self-serve. Provider usage is billed to you by your providers; INFRO charges a software subscription and takes 0% of model spend. See plans.

Sources

Numbered in order of first citation. Each was opened and checked against the claim on the date shown.

  1. 1.OpenAI Evals shuts down: export your evals and rebuild them in CI (opens in a new tab) — INFRO. Accessed Oct 31, 2026.
  2. 2.Define success criteria and build evaluations (opens in a new tab) — Anthropic. Accessed Oct 31, 2026.
  3. 3.Decisions with Jev (opens in a new tab) — INFRO Docs. Accessed Oct 31, 2026.
  4. 4.Decision models (opens in a new tab) — INFRO Docs. Accessed Oct 31, 2026.
  5. 5.Traffic changes (opens in a new tab) — INFRO Docs. Accessed Oct 31, 2026.
  6. 6.AI Risk Management Framework (opens in a new tab) — NIST. Accessed Oct 31, 2026.

About this article

Read on 2026-10-31: NIST's AI Risk Management Framework page, Anthropic's guide to defining success criteria and building evaluations, INFRO's OpenAI Evals shutdown article, and INFRO's docs on decisions, decision models and traffic changes. OpenAI's own Evals page returned HTTP 403, so its dates are taken from INFRO's article; the statistics and bias checks are standard measurement practice, not vendor claims, and carry no citation.

Last checked against its sources on . The next review is due by . No separate named reviewer is recorded for this article.

How articles are written, sourced and corrected is set out in the editorial standards.