Here's the trap most teams fall into: they build an LLM app, realize human evaluation is too slow, point GPT-4 or Claude at their outputs with a prompt like "rate this response 1-10," and ship whatever scores well.
Then they discover their "judge" prefers longer answers regardless of quality, favors whichever response it read first, and confidently rates hallucinated facts as accurate.
LLM-as-a-judge is genuinely useful. It's also easy to do badly. Let's walk through how to do it properly.
What LLM-as-a-Judge Actually Is
The idea is simple: instead of humans grading model outputs, you use a strong LLM as the evaluator. You feed it the task, the output, and grading criteria, and it returns a score or a verdict.
There are three common setups:
| Setup | How it works | Best for |
|---|---|---|
| Pointwise | Judge scores one output against a rubric | Monitoring quality over time |
| Pairwise | Judge picks the better of two outputs | Comparing models or prompts |
| Reference-based | Judge compares output to a known-good answer | Tasks with ground truth |
Pairwise comparison tends to be the most reliable because relative judgments are easier than absolute ones. Asking "which of these is better?" gets more consistent answers than "how good is this on a scale of 1 to 10?"
The catch: every one of these setups inherits the judge model's biases. If you don't design around them, you're not measuring quality. You're measuring what the judge happens to like.
The Biases You Will Actually Hit
These aren't hypothetical. They show up in published research and in my experience they show up in every real evaluation pipeline.
Position bias
In pairwise comparisons, judges systematically favor one position, usually the first response shown. The Judging LLM-as-a-Judge paper (Zheng et al., 2023) found that GPT-4 flipped its verdict for a meaningful share of pairs just from swapping the order.
The fix is mechanical: run every comparison twice with positions swapped. If the judge picks A both times, A wins. If the verdicts disagree, record a tie. Never run a pairwise eval once and trust it.
Verbosity bias
Judges reward length. A padded, repetitive answer will often outscore a tight, correct one. This is especially dangerous because it creates a feedback loop: if you optimize your prompts against a length-biased judge, your product gets wordier and worse.
Mitigations: put "conciseness" explicitly in the rubric, tell the judge that length is not a signal of quality, and spot-check cases where the longer response won.
Self-preference bias
Models rate their own outputs higher than outputs from other models. If you're comparing Claude against GPT-4, don't use either one as the sole judge. Use a third model, or use both and require agreement.
Style over substance
Confident tone, nice formatting, and bullet points all inflate scores independent of correctness. A judge will happily give high marks to a beautifully structured answer built on a fabricated statistic. Which brings us to the biggest problem.
Rubric Design: Where Most Evals Are Won or Lost
"Rate this 1-10" is not a rubric. It forces the judge to invent its own criteria, and it will invent different criteria on different runs.
A working rubric has three properties:
- Separate dimensions. Score correctness, completeness, and conciseness as separate items, not one blended number. Blended scores hide failures: an 8/10 could be flawless-but-incomplete or thorough-but-wrong.
- Anchored scale points. Define what each score means. "3 = factually correct but misses a key constraint from the question" beats an unanchored number every time. Binary or three-point scales are more reproducible than ten-point scales.
- Reasoning before verdict. Require the judge to explain its assessment first, then output the score in a structured format. You get more consistent scores and an audit trail you can read when a score looks wrong.
Here's a skeleton that holds up in practice:
You are evaluating an answer to a user question.
Score each dimension independently:
FAITHFULNESS (0-2):
0 = contains claims contradicted by or absent from the provided sources
1 = mostly supported, minor unsupported details
2 = every factual claim is supported by the provided sources
COMPLETENESS (0-2): ...
CONCISENESS (0-2): ...
Length is not a signal of quality. Do not reward
formatting or confident tone.
First write 2-3 sentences of reasoning per dimension,
then output JSON: {"faithfulness": n, "completeness": n, "conciseness": n}
Notice the faithfulness dimension says "the provided sources." That's deliberate, and it's the part most pipelines skip.
Grounding the Judge: The Step Everyone Skips
An ungrounded judge evaluates factual accuracy from its own parametric memory. That means it shares the same knowledge cutoff and the same misconceptions as the model it's grading. When your app answers questions about current events, pricing, documentation, or anything post-cutoff, an ungrounded judge is guessing.
The fix is to give the judge the actual source material, the same way you'd ground a RAG pipeline. If your app answered a question using a web page, fetch that page and put it in the judge's context. Now "is this accurate?" becomes "is this supported by this document?", which is a task LLMs are genuinely good at.
In practice that looks like this:
import requests
# Fetch the source the answer cited, as clean markdown
page = requests.get(
"https://api.link.sc/fetch",
params={"url": cited_url},
headers={"Authorization": f"Bearer {API_KEY}"},
).json()["content"]
judge_prompt = f"""SOURCE DOCUMENT:
{page}
ANSWER TO EVALUATE:
{answer}
Score FAITHFULNESS per the rubric. A claim not present
in the source document counts as unsupported, even if
you believe it is true."""
That last instruction matters. Without it, judges "helpfully" fill gaps with their own knowledge, and you're back to ungrounded evaluation. We use link.sc for the fetch step because the judge needs clean markdown, not raw HTML full of nav links, but any pipeline that gets real page content into the judge's context works.
This is the same principle behind grounding generation models, which I've covered in what LLM grounding is. It applies doubly to judges: an evaluator you can't trust is worse than no evaluator, because it launders bad outputs with a quality score. If your app cites its sources, grounded judging gets even easier, because every answer arrives with the URLs you need to verify it.
A Checklist Before You Trust Your Judge
Run through this before you let judge scores drive decisions:
- Swap positions in every pairwise comparison and count disagreements as ties
- Calibrate against humans. Grade 50-100 examples yourself and measure agreement. Below roughly 80 percent agreement, fix the rubric before scaling
- Use a third-party judge when comparing models, never one of the contestants
- Ground factuality checks with fetched source documents, not the judge's memory
- Read the reasoning on a random sample every run. Scores drift; explanations show you why
- Keep a frozen eval set so scores are comparable across time
LLM-as-a-judge won't replace human evaluation. It replaces the 95 percent of grading that's repetitive, so your human review time goes where it matters: the disagreements, the edge cases, and the answers that scored suspiciously well.
Need clean, LLM-ready source documents to ground your judges? Get a free link.sc API key and start fetching pages as markdown in minutes.