n4nAI

Building a rubric-based LLM judge prompt

Step-by-step guide to building a rubric-based LLM judge prompt for LLM-as-a-judge, with code examples and calibration against human labels.

n4n Team3 min read630 words

Audio narration

Coming soon — every post will get a voice note here.

A rubric-based LLM judge prompt turns subjective quality assessments into reproducible scores by giving the model explicit criteria and a fixed scale. This guide walks through building one that survives contact with production traffic, from dimension selection to calibration against human labels.

Step 1: Define evaluation dimensions and scoring scale

Pick 3–5 dimensions that map to your product’s failure modes. For a support bot, correctness, tone, and instruction-following cover most regressions. Avoid vague traits like “quality” — they correlate with nothing.

Set a fixed scale. A 1–5 integer scale with verbal anchors at each point beats a 1–10 scale because models calibrate better on fewer, distinct buckets. Never let the judge emit floats; round to integers in post-processing if it does.

Step 2: Write the rubric as machine-readable criteria

The rubric must be unambiguous. Store it as JSON so you can render it into the rubric-based LLM judge prompt and parse results consistently.

{
  "dimensions": [
    {
      "name": "correctness",
      "scale": [1, 2, 3, 4, 5],
      "anchors": {
        "1": "Contains factual errors or contradicts the user request",
        "3": "Mostly accurate with one minor omission",
        "5": "Fully accurate, complete, no hallucinations"
      }
    },
    {
      "name": "tone",
      "scale": [1, 2, 3, 4, 5],
      "anchors": {
        "1": "Hostile, dismissive, or off-brand",
        "3": "Neutral but generic",
        "5": "Warm, concise, on-brand for enterprise support"
      }
    }
  ]
}

Attach this rubric to every judge call. If you change an anchor, version the rubric file.

Step 3: Construct the judge prompt

The system message sets the role; the user message packs the rubric, the candidate output, and any reference answer. Keep the ordering fixed: rubric first, then candidate, then reference. Models attend to recent tokens, but a stable layout reduces variance.

If you point the OpenAI client at n4n.ai’s OpenAI-compatible endpoint, you get access to 240+ models and automatic fallback when a provider is rate-limited, which keeps judge runs from failing mid-evaluation.

from openai import OpenAI

client = OpenAI(
    base_url="https://api.n4n.ai/v1",
    api_key="YOUR_KEY"
)

rubric_json = """
{
  "dimensions": [
    {"name": "correctness", "scale": [1,2,3,4,5],
     "anchors": {"1":"errors","3":"minor omission","5":"perfect"}}
  ]
}
"""

system_prompt = (
    "You are a strict LLM judge. Score the candidate output against the "
    "provided rubric. Output only JSON matching the schema."
)

user_content = f"""RUBRIC:
{rubric_json}

CANDIDATE:
{candidate_text}

REFERENCE:
{reference_text}

Return JSON: {{"correctness": int, "tone": int, "reasoning": str}}"""

resp = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=[
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_content}
    ],
    response_format={"type": "json_object"}
)

Step 4: Enforce structured output with a schema

JSON mode prevents free-text rambling, but it does not guarantee your keys. Validate after the call. Use a tiny parser:

import json

def parse_judge(raw):
    data = json.loads(raw.choices[0].message.content)
    assert set(data.keys()) >= {"correctness", "tone", "reasoning"}
    data["correctness"] = int(data["correctness"])
    data["tone"] = int(data["tone"])
    return data

If you need stricter contracts, use function calling with a JSON schema. The extra round-trip is worth it when the judge feeds a dashboard.

Step 5: Calibrate on a labeled sample set

A rubric-based LLM judge prompt is useless until you measure its agreement with humans. Label 50–100 real outputs yourself or pull from historical tickets with CSAT scores.

Run the judge on each sample, then compute rank correlation:

from scipy.stats import spearmanr

human = [sample["human_score"] for sample in eval_set]
judge = [parse_judge(run_judge(sample))["correctness"] for sample in eval_set]

rho, p = spearmanr(human, judge)
print(f"Spearman ρ={rho:.2f}, p={p:.3f}")

A ρ above 0.7 on correctness means the judge can flag regressions. Below that, the rubric anchors are too soft.

Step 6: Tighten ambiguous anchors

Typical failure: the judge gives 4s to everything. That signals anchor compression. Split the middle. Change “3: mostly accurate” to “3: accurate but misses one step the user explicitly asked for”. Concrete behaviors beat adjectives.

Another failure: reasoning says “good answer” but score is 1. Add a constraint in the system prompt: “The reasoning field must cite the rubric anchor that justifies the score.” This forces the model to map output to criteria.

Step 7: Automate in your pipeline

Wire the judge into a nightly eval or CI step. Load a golden set, score, and fail the build if mean correctness drops more than 0.2 from baseline.

baseline = 4.1
scores = [parse_judge(run_judge(s))["correctness"] for s in golden]
mean = sum(scores)/len(scores)
if baseline - mean > 0.2:
    raise SystemExit("Judge detected regression in correctness")

Store per-token usage if your gateway exposes it; you’ll need it to track cost as the golden set grows.

Step 8: Verify success against human labels

Verification is not “the judge runs.” Success means the rubric-based LLM judge prompt agrees with held-out human ratings and surfaces real defects.

Create a fresh set of 30 outputs the judge has never seen, labeled by a second human. Compute both Spearman ρ and raw accuracy within one point. You have a working judge when:

  • ρ ≥ 0.7 on each dimension
  • < 10% of items differ from human by more than 1 point
  • Reasoning fields reference specific rubric anchors

If those hold, promote the rubric version and freeze the prompt. Re-calibrate monthly; model updates shift judge behavior even if your code doesn’t change.

The work is iterative. A rubric-based LLM judge prompt is a living artifact—treat it like a unit test suite, not a one-shot prompt.

Tagsllm-as-a-judgerubricprompt-engineeringevaluation

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All llm-as-a-judge techniques posts →