Traditional software testing compares deterministic behaviour with a known expected result: the same input should produce the same output. Generative systems fail that test — but not because they are random. At a fixed temperature a model is deterministic too. They fail it because correctness is one-to-many: a good answer can take countless forms, two very different responses may both be right, and there is no single expected value to assert against.
What an eval measures
We use evaluations — evals — to grade the qualities a compiler cannot see: factual accuracy, relevance, completeness, tone, citation quality, adherence to instructions.
These are not one kind of measurement. Some are graded against evidence: is this claim supported by the retrieved source? Some are graded against the prompt: did the model do what it was told? Some are graded against a rubric somebody had to write: is this the right register for this reader? Each needs a different judge setup and each fails differently. Collapsing them into a single score is the fastest way to produce a number that moves without meaning anything.
The judge
In an LLM-as-a-Judge evaluation, one model performs the task while another independently reviews its output against explicit criteria. The judge sees the question, the answer, the rubric — and, for a RAG system, the retrieved evidence.
Evidence, and what it can and cannot tell you
Access to the retrieved evidence is essential. Without it, the judge can assess whether an answer sounds convincing, but not whether it is actually supported by the source material.
With it, the judge can measure groundedness: each claim traced to material that supports it. What groundedness cannot tell you is whether the right material was retrieved in the first place.
An answer can be faithfully grounded in three irrelevant passages and still score clean.
Retrieval has to be scored separately — the relevance of the retrieved context to the question, against a gold set where one exists. Kept apart, the two scores become a diagnostic: faithful answers over poor context point at retrieval and chunking, unfaithful answers over good context point at the generator and the prompt. Collapsed into one, they tell you only that something is wrong.
Where we use it
Throughout development and before production: to compare models and prompts, expose retrieval and chunking failures, test agent behaviour, and detect regressions as the system evolves. Results are calibrated against human-reviewed examples and combined with conventional tests for the deterministic code around the model.
How the judge fails
A judge is a model, and it carries a model's biases. It rewards length. It favours output from its own family. In pairwise comparison it is sensitive to which candidate it reads first. Reword the rubric and the scores move. None of this disqualifies the method, but it sets the conditions for using it: fixed rubrics, randomised order, a panel rather than a single reviewer where the decision matters, and a labelled set that measures how well the judge agrees with human reviewers.
It also makes the judge a versioned component. Change the judge model or edit the rubric and the scale shifts underneath you — scores from before the change stop being comparable with scores from after it. Version the judge as strictly as the system it grades, and re-calibrate whenever either one moves.
The judge is a scalable quality-control mechanism — not an automatic source of truth.