Skip to main content

Writing Judge Prompts & Rubrics

Introduction

You have the idea (L166 (The Idea: Models Grading Models)) and the protocol (L167 (Pointwise vs Pairwise / Comparative Judging)). Now the part that actually decides whether your judge is trustworthy or theater: the rubric.

A judge is only as good as the rubric you hand it. Ask “is this answer good?” and the model has no choice but to fill in the blank with its own idea of good — uncalibrated, invisible, and different every run. The discipline of this lesson is turning a fuzzy quality (“be helpful,” “be faithful”) into a precise, operational rubric the judge applies the same way every time. The one-line warning that should haunt you: vague rubrics produce vague verdicts at scale. A bad rubric doesn't fail loudly — it quietly hands you thousands of confident, wrong numbers.

An infographic titled 'Writing Judge Prompts & Rubrics' about how to turn a vague notion of quality into a precise rubric an LLM judge can apply consistently, because a judge is only as good as its rubric and vague rubrics produce vague verdicts at scale. The core contrast shows the same answer, which invents priority phone support that the source says is email-only, graded two ways: a vague rubric that just asks is this answer good rubber-stamps the hallucination at four out of five because the judge fills in its own priors, while a precise rubric catches the invented claim and returns fail. A good judge prompt follows an RCAF structure: a Role such as you are a strict grader, the rubric as Context, a scoring Action, and a strict output Format, with the input and output to grade and a low temperature. Writing good criteria means operationalizing fuzzy words: helpful is a feeling, not a rubric, whereas every factual claim in the answer is directly supported by the source is a rubric, written in the domain's own language rather than generic machine-learning vocabulary. The strongest criteria are specific, measurable, criterion-independent so they avoid double-counting, and exhaustive enough to cover the decision the team cares about, and you decompose quality into separate criteria such as faithfulness, which checks the answer stays inside the retrieved evidence, relevance, which checks it answers what was asked, and completeness, scoring one criterion per call in separate prompts and aggregating at the application layer, because a single prompt that scores everything at once produces correlated unreliable scores. The scale should be a categorical integer such as binary pass-fail or zero to five, which has the highest human alignment, never a float, with an anchored descriptor for every level saying what a one, a three, and a five mean, plus ideally one calibration example, since one well-chosen example beats many. The judge should reason first by listing the claims and marking each supported or not before scoring, the G-Eval technique, though the reasoning should be structured and concise rather than an unbounded post-hoc rationale; the rubric must build in length-neutrality explicitly, stating a concise answer scores at least as high as a verbose one at equal correctness, or it silently rewards verbosity; and for grounded criteria like faithfulness you pass the source into the judge so it can check each claim. Finally you cannot fully determine the criteria before judging real outputs, a phenomenon called criteria drift, so you discover the rubric through an alignment loop: grade a small sample, compare the judge to human labels, read the disagreements which each reveal an under-specified criterion, refine the rubric, and repeat until agreement is high. The takeaway banner reads: a judge is only as good as its rubric; operationalize the criterion, anchor the scale, reason first, pass in the source, and align to humans, because vague rubrics produce vague verdicts at scale.

The Rubric Is the Eval

Hold one case in mind for the whole lesson. The source says: “Pro includes priority email support (4-hour SLA); phone is Enterprise-only.” The answer to grade says: “Yes — Pro includes priority phone support, 4-hour SLA.” It invented a channel. Now watch the rubric decide the verdict:

  • Vague rubric“Is this answer good?” → the judge shrugs, sees a confident on-topic reply, and returns “👍 4/5.” It rubber-stamped the hallucination, because “good” is a placeholder it filled with its priors.
  • Precise rubric“Faithfulness: every claim must be supported by the source; reason through each claim, then score” → the judge lists the claims, finds “phone support” isn't in the source, and returns FAIL.

Same judge, same answer, opposite verdict — decided entirely by the rubric. As one practitioner put it: “The response is high quality” is not a definition; it's a placeholder the judge fills with whatever its priors happen to be. The rubric isn't documentation around your eval — the rubric is your eval.

Anatomy of a Judge Prompt: RCAF

A reliable judge prompt has four parts — RCAF: a Role, the rubric as Context, a scoring Action, and a strict output Format — wrapped around the input/output to grade, run at temperature 0 so grading is deterministic.

from anthropic import Anthropic
import json

client = Anthropic()

# RCAF: Role · rubric as Context · scoring Action · strict Format. ONE criterion, anchored.
FAITHFULNESS = """You are a strict grader.                                   # ROLE
CRITERION - Faithfulness: every factual claim in the ANSWER must be directly  # CONTEXT
supported by the SOURCE. Score an integer 0-5, anchored:                      #   (anchored
  5 = every claim supported    3 = one unsupported claim    1 = mostly unsupported  #   levels)
A concise answer scores >= a verbose one at equal correctness.                # length-neutral
First list each claim and mark supported / not — THEN score.                  # ACTION (reason 1st)
Reply as JSON only: {"claims":[...], "score":0-5, "label":"pass|fail"}"""      # FORMAT

def judge_faithfulness(source, answer):
    msg = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        temperature=0,                          # deterministic grading
        system=FAITHFULNESS,
        messages=[{"role": "user",
                   "content": f"SOURCE:\n{source}\n\nANSWER:\n{answer}"}],   # pass the SOURCE in
    )
    return json.loads(msg.content[-1].text)
# Score ONE criterion per call. For relevance/completeness, write SEPARATE rubrics &
# separate calls, then aggregate — one prompt scoring everything at once gives mushy scores.

Read the four roles in that prompt. Role sets the stance (“strict grader”). Context is the rubric itself — the criterion plus anchored levels. Action tells it how to decide (reason first, then score). Format pins the output to parseable JSON. And notice two non-obvious moves: the SOURCE is passed in so the judge can actually check each claim (you can't grade faithfulness without the evidence), and the comment's rule — score one criterion per call. A single prompt asked to rate faithfulness and relevance and fluency at once produces correlated, mushy scores; separate rubrics in separate calls, aggregated at the app layer, stay sharp.

Write Criteria That Are Operational & Separable

The hardest, highest-leverage work is operationalizing the fuzzy word. “Helpful” is a feeling; “the response directly addresses every constraint in the user's query, including the negative ones” is a rubric. Write the criterion in your domain's language, not generic ML vocabulary — “every factual claim is explicitly supported by the retrieved context” tells the judge exactly what to look for; “high quality” tells it nothing.

The strongest criteria share four properties: specific (one clear thing), measurable (you could check it), criterion-independent (doesn't double-count what another criterion already scored), and exhaustive (together they cover the decision you actually care about). That last pair is why you decompose quality instead of asking for one global score:

  • Faithfulness — does it stay inside the retrieved evidence (no inventions)?
  • Relevance — does it answer what the user actually asked?
  • Completeness — did it cover everything it needed to?

Score each criterion in its own call and aggregate at the application layer. The instinct to save tokens with one do-everything prompt is exactly what makes judge scores untrustworthy.

Anchor the Scale

Even a perfect criterion needs a scale the judge can apply consistently — and the defaults people reach for are usually wrong.

  • Use a categorical integer scale, not a float. Judges are far more consistent on “0–5” or “pass/fail” than on “0.0–1.0.” Research puts human alignment highest on a 0–5 scale, and binary pass/fail is the most robust of all — a yes/no verdict is hard to game with verbosity. Pick the coarsest scale that still captures the distinction you need.
  • Anchor every level. Don't just say “score 1–5” — say what each number means: “5 = every claim supported · 3 = one unsupported claim · 1 = mostly unsupported.” Anchored descriptors are the difference between a stable ruler and a judge guessing what a “4” feels like today.
  • Add one calibration example. A single worked example (“…24/7 phone line” → 2, invents a channel) stabilizes scoring like rater-training does for humans. Counterintuitively, one example beats many — models often get worse as you pile on few-shot examples, so choose one good one.

See It: Build the Rubric

Here's the whole lesson as something you can do with your hands. The answer below hides the phone-support hallucination. Start with nothing and toggle rubric ingredients on — watch the judge prompt assemble line by line, the human-alignment meter climb, and the verdict flip from rubber-stamping the lie to catching it.

Interactive: one answer that invents 'priority phone support' is graded against a SOURCE that says email-only. The reader toggles rubric ingredients on/off — name an explicit criterion, pass the SOURCE in (reference-guided), categorical 0–5 scale, anchored levels, a calibration example, reason-first, and a length-neutrality clause. As they toggle, the actual judge prompt assembles line-by-line (arrow workflow), a human-alignment meter climbs from ~52% to ~92%, and the sample verdict sharpens through three states: with no source the judge rubber-stamps the hallucination at 4/5; with a criterion but no anchors/reason it half-notices at a soft 3/5; with an explicit criterion + source + anchors + reason-first it returns FAIL (2/5), catching that 'phone support' isn't in the source. Makes 'vague rubrics produce vague verdicts at scale' tangible.

Toggle them in any order and the pattern is unmistakable. Drop the source and the judge can't check anything — it guesses “4/5.” Add a criterion but no anchors or reasoning and it gets a soft, drifting “3/5.” Add anchored levels + reason-first + the source and it does what you actually wanted: lists the claims, catches “phone support,” and returns FAIL. You didn't change the model or the answer — only the rubric — and that alone moved the verdict from wrong to right.

Defend the Rubric From Bias

A few clauses in the rubric are really bias armor — leave them out and the judge quietly optimizes for the wrong thing:

  • Reason first — but keep it structured. Asking the judge to “list each claim and mark supported / not, then score” (the G-Eval pattern) consistently improves agreement with humans over jumping straight to a number. The nuance: keep the reasoning a short, defined set of steps, not an open-ended essay. An unbounded rationale before a forced verdict can become post-hoc justification — the model commits early and rationalizes. Structured steps, then score.
  • State length-neutrality explicitly. Judges score longer answers higher (verbosity bias). If your rubric doesn't say “a concise answer scores ≥ a verbose one at equal correctness,” it implicitly rewards length. One sentence closes the loophole.
  • Pass the evidence in (reference-guided). For grounded criteria — faithfulness, correctness — give the judge the source or a gold answer in the prompt so it checks against fact, not vibes. A faithfulness rubric with no source is just the judge's imagination. (These biases — position, verbosity, self-preference — get their full calibration treatment in L169 (Judge Biases & How to Calibrate).)

You Discover the Rubric — The Alignment Loop

Here's the humbling part, and the most important: you cannot fully write the rubric up front. Researchers studying how people build judges found a “criteria drift” phenomenon — “it is impossible to completely determine evaluation criteria prior to human judging of LLM outputs.” As you grade real data, your own understanding of “good” evolves, and you reinterpret the rubric. The rubric is discovered, not specified.

So the workflow isn't write rubric → done. It's a loop (the “who validates the validators?” problem): label a small sample by hand, run your judge on it, and read every disagreement — each one is a criterion you under-specified or a level you anchored wrong. Refine, re-run, and stop when judge↔human agreement is high.

# You can't fully write the rubric up front — you DISCOVER it. Align it to a small set
# of HUMAN labels, then refine the criterion wherever the judge disagrees. Repeat.
def align(judge, labeled):                  # labeled: [(source, answer, human_label), ...]
    rows = [(ans, human, judge(src, ans)["label"]) for src, ans, human in labeled]
    agree = sum(v == h for _, h, v in rows)
    disagreements = [(a, h, v) for a, h, v in rows if v != h]   # <- READ these
    print(f"judge↔human agreement: {agree/len(rows):.0%}")
    return disagreements                     # each gap is a criterion you under-specified
# "It is impossible to completely determine evaluation criteria before judging real outputs."
# Refine the rubric on the disagreements, re-run, and stop when agreement is high (~>90%).

Two cautions live in this loop. Rubric drift / Rubric-Induced Preference Drift: tiny natural-language edits to a rubric can silently shift the judge's preferences in a whole domain, so version your rubric like code and re-check agreement after every change. And the loop never fully ends — keep a path from judge disagreement → human adjudication (L170 (Human-in-the-Loop Spot Checks)). The rubric you ship is the one that provably tracks your humans (L158 (Building Your First Eval Set) is where those human labels come from), not the one that sounded right in a doc.

🧪 Try It Yourself

Take a vague rubric you (or a tutorial) already use and operationalize one criterion — 15 minutes, and the skill clicks:

  1. Pick the fuzzy word. “Helpful,” “accurate,” “good tone” — whatever you're secretly asking a judge for.
  2. Write the procedural definition. Turn it into something two people would grade the same way: not “is it accurate?” but “every factual claim is supported by the provided source.” In your domain's words.
  3. Anchor a 0–5 (or pass/fail) scale. Say what a 5, a 3, and a 1 look like — one line each. Add one example answer with its score.
  4. Grade 10 real outputs yourself, then run claude-opus-4-8 with your rubric on the same 10 (reason first, then score). Read the disagreements. Nine times out of ten the rubric was ambiguous, not the judge — fix that line and re-run.

When your judge agrees with you on those 10, you've done the actual job: you didn't write a prompt, you designed a measurement.

Mental-Model Corrections

  • “Just ask the judge if it's good.” “Good” is a placeholder the judge fills with its own priors. Write an operational criterion in your domain's words, or you're measuring the model's vibes, not your standard.
  • “One prompt can score everything at once.” A do-everything prompt yields correlated, mushy scores. Score one criterion per call (faithfulness, then relevance, then completeness) and aggregate.
  • “Use a 0.0–1.0 float for precision.” Judges are inconsistent on floats. Use a categorical scale — 0–5 (best human alignment) or binary (most robust, hard to game) — with anchored levels.
  • “Score first, explain after.” Backwards for accuracy: reason first (list the evidence), then score (G-Eval) — but keep the reasoning structured and short, not an essay that becomes post-hoc justification.
  • “My rubric is neutral.” Not unless you said so. Without an explicit length-neutrality clause it rewards verbosity; without the source passed in it can't check faithfulness at all.
  • “Write the rubric once, then run it.” You discover the rubric (criteria drift). Align it to human labels, read the disagreements, and refine until it provably tracks your people.

Key Takeaways

  • A judge is only as good as its rubricvague rubrics produce vague verdicts at scale. “Is it good?” makes the judge grade by its own priors; an operational criterion makes it grade by yours.
  • Structure the prompt as RCAF: Role · rubric as Context · scoring Action · strict (JSON) Format, at temperature 0, with the input/output to grade.
  • Operationalize + separate the criteria: specific, measurable, criterion-independent, exhaustive; decompose into faithfulness / relevance / completeness and score one per call.
  • Anchor the scale: categorical integers (0–5 best human alignment, or binary most robust), a descriptor for every level, plus one calibration example (one beats many).
  • Build in the defenses: reason first but structured (G-Eval), an explicit length-neutrality clause, and pass the source in for grounded criteria. Full bias treatment in L169 (Judge Biases & How to Calibrate).
  • You discover the rubric: criteria drift means you can't fully specify it up front — align to human labels, read the disagreements, refine, and version it like code. Those labels come from L158 (Building Your First Eval Set); escalation lives in L170 (Human-in-the-Loop Spot Checks).