Skip to content
AI Product Engineer Wiki

    ↑ ↓ to move between results, Enter to open, Esc to close

    Menu

    LLM-as-judge: design and calibration

    Use a model to grade AI output at scale, with judge prompts, rubrics, calibration against human grades, and the biases to guard against.

    Level: Advanced 9 min read Updated
    On this page

    Why this matters

    Human grading is the reference standard for qualities like correctness, tone and faithfulness to sources, but it doesn’t scale to every prompt change, every model comparison and every night’s regression run. A model can apply the same rubric in minutes, for a fraction of the cost.

    The catch is that a model judge is itself an AI system: it can be wrong, inconsistent and biased in predictable ways. Used carefully, with one criterion at a time, structured verdicts and regular calibration against human grades, it’s one of the most useful tools in the eval stack. Used carelessly, it gives you confident numbers that don’t mean anything. This article shows the careful version.

    When to use a model as judge

    A model judge sits in the middle of the eval pyramid: above code checks, below human grading. Use it when:

    • Code can’t check the quality. Faithfulness to sources, whether a question was actually answered, tone, completeness.
    • Humans can’t grade the volume. Hundreds of outputs per change, or nightly runs.
    • You have human grades to calibrate against. Without them, you can’t know whether the judge is right.

    Don’t use a judge for things code can check exactly, such as format, length, required phrases or valid JSON. Code is faster, free and never wrong about those.

    Writing a judge prompt

    Judges work best with a narrow, well-defined job. The principles:

    • One criterion per judgment. “Is it grounded?” and “is the tone right?” are separate calls. A judge asked to score five things at once does all of them worse.
    • Use your human rubric. The same definition, pass example, fail example and borderline rule that your human graders use. If humans can’t agree on a criterion, a model won’t either.
    • Ask for a pass/fail verdict, not a score. Binary verdicts are more consistent than 1 to 10 scales.
    • Ask for a short justification first. Having the judge quote the part of the output that decides the verdict, before giving it, tends to make verdicts more careful and makes disagreements easier to diagnose.
    • Give the judge what it needs and nothing else. For groundedness, the sources and the answer. Not the prompt version, not which model produced it.
    • Return structured output, so verdicts are parsed reliably.

    A judge in TypeScript

    This judge grades one criterion, groundedness, and returns a structured verdict. A calibration function then compares its verdicts with human labels on the same outputs.

    evals/judge.ts
    import Anthropic from '@anthropic-ai/sdk';
    import { zodOutputFormat } from '@anthropic-ai/sdk/helpers/zod';
    import { z } from 'zod';
    
    const client = new Anthropic();
    
    // The reasoning field comes first, so the judge explains before it decides.
    const VerdictSchema = z.object({
      reasoning: z.string().describe('One or two sentences quoting the part of the answer that decides the verdict'),
      verdict: z.enum(['pass', 'fail']),
    });
    
    type Verdict = z.infer<typeof VerdictSchema>['verdict'];
    
    // The same definition, examples and borderline rule human graders use.
    const GROUNDED = [
      'Criterion: grounded. Every factual claim in the answer is supported by the sources.',
      'Pass: all claims appear in the sources, possibly reworded.',
      'Fail: any claim (a date, amount, policy or step) that the sources do not support.',
      'Borderline: courtesy phrases such as apologies are not factual claims; ignore them.',
    ].join('\n');
    
    /** Grades one answer on one criterion. Returns null when the judge didn't finish, so it's never counted as a pass. */
    export async function judgeGrounded(sources: string, answer: string): Promise<Verdict | null> {
      const response = await client.messages.parse({
        model: 'claude-sonnet-5-5',
        max_tokens: 2048,
        // No fallback on purpose: switching judges mid-run would make scores incomparable.
        output_config: { effort: 'low', format: zodOutputFormat(VerdictSchema) },
        system: `You grade one criterion for an evaluation. Apply it strictly.\n\n${GROUNDED}`,
        messages: [{ role: 'user', content: `<sources>\n${sources}\n</sources>\n\n<answer>\n${answer}\n</answer>` }],
      });
      if (response.stop_reason !== 'end_turn' || !response.parsed_output) return null;
      return response.parsed_output.verdict;
    }
    
    interface LabeledExample {
      sources: string;
      answer: string;
      /** The verdict agreed by human graders. */
      human: Verdict;
    }
    
    /** Compares judge verdicts with human labels. False passes are the dangerous disagreements. */
    export async function calibrate(examples: LabeledExample[]) {
      let agree = 0;
      let falsePass = 0;
      let falseFail = 0;
      let unfinished = 0;
      for (const example of examples) {
        const verdict = await judgeGrounded(example.sources, example.answer);
        if (verdict === null) unfinished++;
        else if (verdict === example.human) agree++;
        else if (verdict === 'pass') falsePass++;
        else falseFail++;
      }
      const graded = examples.length - unfinished;
      return {
        agreement: graded === 0 ? 0 : agree / graded,
        falsePass,
        falseFail,
        unfinished,
      };
    }

    Two design choices to notice:

    • Unfinished judgments aren’t passes. If the judge is cut off or declines, the result is null, and calibration reports it separately. A silent default to “pass” would inflate every score.
    • Disagreements are split by direction. A judge that passes outputs humans failed (a false pass) hides real problems; one that fails outputs humans passed (a false fail) wastes your time. You usually care much more about the first.

    This example uses Claude Sonnet 5.5 as the judge, a common choice for grading at volume because it’s cheaper than the model being evaluated. Using the same model works too. Either way, the judge earns trust only through calibration.

    Calibration and bias

    Calibration means checking the judge against human grades on the same outputs, and improving it until they agree well enough:

    Calibrating a model judge. Repeat whenever the rubric, the judge model or the feature changes significantly.
    Show text descriptionHide text description

    A sequence of 4 steps that loops back to the start.

    1. Human-grade a sample : 30 to 100 outputs, with good agreement between graders
    2. Run the judge : Same outputs, same rubric, verdicts hidden from it
    3. Compare : Agreement, false passes and false fails
    4. Fix the judge : Read the disagreements; tighten the rubric or the judge prompt

    After the last step, the process starts again at step 1.

    Set a target before calibrating: for example, at least 90% agreement with humans and no false passes on must-never-fail criteria. Until the judge meets it, treat its scores as rough signals, not decisions.

    Model judges also have known biases. Research on LLM judges has documented several (see Zheng et al., 2023 (opens in a new tab)):

    • Position bias: when comparing two outputs side by side, judges can favor whichever comes first (or second). Mitigation: run comparisons in both orders, or grade each output on its own against the rubric.
    • Length bias: longer, more detailed-looking answers can be favored even when they’re not better. Mitigation: criteria that don’t reward length, and a separate length check in code.
    • Self-preference: a judge may favor outputs that resemble its own style. Mitigation: calibrate against human grades, which reveals the bias if it affects your criteria.

    The common thread: grade against a rubric, one criterion at a time, and verify against humans. Biases mostly show up in open-ended comparisons (“which is better?”), and much less in narrow, well-defined pass/fail criteria.

    Common mistakes

    • One judge call for many criteria. Judges do each criterion worse when asked several at once. One criterion per judgment.
    • Scores instead of verdicts. “Rate 1 to 10” is inconsistent. Use pass/fail against a clear definition.
    • Never calibrating. Without comparison against human grades, you don’t know whether the judge’s numbers mean anything.
    • Counting unfinished judgments as passes. Handle truncation and refusals explicitly, and report them.
    • Using a judge for what code can check. Format, length and required phrases belong in code checks.

    Try it

    Exercise

    About 90 min

    Calibrate a judge against your human grades

    1. Take a criterion you graded with a colleague in rubrics and human grading, with at least 30 agreed labels.
    2. Adapt the judge above to that criterion, using the same rubric text.
    3. Run the calibration and record agreement, false passes, false fails and unfinished judgments.
    4. Read every disagreement, change one thing in the rubric or judge prompt, and run it again.
    Show a hint

    When the judge and humans disagree, check the humans too. Sometimes the judge is right and the human label was a mistake. Fix those labels before tuning the judge.

    Show a worked solution

    An example calibration log (illustrative):

    • Round 1: 83% agreement, 3 false passes, 2 false fails. False passes were answers that added a plausible “usually within 5 days” not in the sources.
    • Round 2: added to the fail definition: “including hedged claims such as ‘usually’ or ‘typically’”. Result: 93% agreement, 0 false passes, 2 false fails.
    • Round 3: the two remaining false fails were courtesy phrases the judge treated as claims; tightened the borderline rule. Result: 97% agreement, 0 false passes.
    • Decision: the judge can gate merges for groundedness; re-calibrate when the judge model changes.

    Check your understanding

    Question 1 of 4: Why grade one criterion per judge call?

    Show answer

    B. Judges asked to assess several criteria at once do each one worse

    A narrow, well-defined job produces more consistent verdicts and clearer disagreements to diagnose.

    Question 2 of 4: Which disagreement with human grades is usually the most dangerous?

    Show answer

    B. The judge passes an output humans failed

    False passes hide real problems behind a good score.

    Question 3 of 4: What should happen when the judge is cut off before giving a verdict?

    Show answer

    C. Treat it as unknown and report it separately

    Silent defaults distort scores. Unfinished judgments are reported on their own.

    Question 4 of 4: How can you reduce position bias in side-by-side comparisons?

    Show answer

    B. Run each comparison in both orders, or grade each output alone against a rubric

    Swapping the order, or avoiding pairwise comparison, removes the advantage of position.

    Key takeaways

    • Use a model judge for qualities code can’t check, at volumes humans can’t grade.
    • Give it one criterion, your human rubric, a pass/fail verdict and a short justification first, with structured output.
    • Calibrate against human grades: track agreement, false passes, false fails and unfinished judgments.
    • Guard against position, length and self-preference bias by grading against rubrics and verifying with humans.

    Progress is saved in this browser and lights up the roadmap.