You implement LLM-as-a-judge in five moves. Pick one evaluation criterion, collect a small set of hand-labeled examples, write an evaluation prompt that returns a structured score, run the judge over a test set, and measure how often the judge agrees with the human labels before you trust it.

The judge model produces a score plus a written justification for each candidate output. You feed the candidate output and your rubric into the prompt, the judge model reads both, and it returns a number, a label, or a preference between two outputs. This guide gives you a prompt template and runnable code for both single-score and pairwise judging, then walks through the bias traps and the calibration loop that turn a judge from a demo into a gate you can act on.

The examples here are vendor-neutral. The patterns come from the top sources on this topic: the Evidently AI guide to LLM-as-a-judge, the Hugging Face Open-Source AI cookbook notebook on LLM-as-a-judge, and the MLflow LLM-as-a-judge documentation. Code below that wraps a specific client is illustrative, and I flag where each pattern came from.

What you are building

LLM-as-a-judge is a technique, not a single metric. You are building a small evaluation function. The production system emits an output, you wrap that output in a prompt that tells a separate judge model what to grade and how, the judge returns reasoning plus a structured verdict, and a parser turns the verdict into a number you can aggregate.

The pipeline has four parts:

  1. A criterion: what quality you grade, stated so a reviewer can apply it consistently.
  2. A rubric: the meaning of each score or label on your scale.
  3. An evaluation prompt: the criterion, the rubric, the input, and the candidate output, plus instructions for the judge.
  4. A process: a parser, a loop over a dataset, and an aggregation step.

Why use a judge at all? Because the qualities you care about, such as helpfulness, faithfulness, or brand tone, resist deterministic checks. String overlap metrics like ROUGE and BLEU measure token overlap and miss whether a response hallucinated or violated a style guideline. Human reviewers catch these issues but evaluate only a limited number of outputs per day. A judge applies the same criteria to every output and, when set up well, reaches over 80% agreement with human evaluators, which is comparable to the level of agreement between two human reviewers.

Start with a labeled dataset

Do not write the prompt first. Before you grade anything, build a small labeled set that reflects how you want the judge to score your texts. The Evidently guide calls this step first for a reason: labeling forces you to decide what the judge should notice, and those decisions shape the instructions.

Collect 20 to 50 examples that cover the range you care about, including the borderline cases that are likely to trip the judge. You can draw these from experiments, from production logs, or from synthetic cases that mimic expected inputs. Label each one the way you want the judge to label it. You can also write your best guess at a prompt first and then hand-correct the judge's outputs to create the approved test set, but starting with your own labels tends to produce a sharper initial prompt.

Keep some of the labeled data separate as a held-out set. Use the first portion to iterate on the prompt, and use the held-out portion only to test the final version. Otherwise the prompt overfits to the examples you tuned against and you never measure how it generalizes.

Pick one criterion per judge

An LLM grades one thing at a time more reliably than it juggles several. If you care about completeness, accuracy, and relevance, run three judges, not one judge with three instructions.

You can still combine the results afterward in a deterministic way. Flag an answer as bad if any one criterion returns a negative label. Or sum the "good" labels across criteria, optionally weighted to reflect how much each dimension matters. This keeps each call focused and makes the reasons for a verdict clear for a reviewer to verify.

A support agent example shows the practical difference. One judge checks whether the answer is grounded in the retrieved policy document. A second checks whether the answer resolves the user's request. A third checks tone. Each has its own prompt and its own labels.

Score with binary or low precision first

When you define the rubric, prefer a small set of distinct labels over a fine-grained number. Binary choices like "correct" versus "incorrect" are more consistent for the judge and for human raters. A three-way option that adds "partially relevant" or an "unknown" choice lets the judge avoid guessing when there is not enough information.

If you need a graded scale, keep it small and explain each level. What separates a 3 from a 4 must be clear in the prompt, or both the judge and your human reviewers will drift. A 1 to 5 scale where each number has a one-line definition works better than a 0 to 100 score, because a language model generates text and is not naturally calibrated for high-precision numeric scoring. The Hugging Face cookbook measured this directly: a float scale from 0 to 10 produced weaker agreement with human raters, and moving to a small integer scale from 1 to 4 with an explained scale and a reasoning field lifted correlation substantially.

Write the judge prompt template

A judge prompt contains a task description, a scale or label definition, the output format, and a reasoning instruction. Start with this workhorse template.

JUDGE_PROMPT = """
You will be given a user_question and a system_answer.
Your task is to rate how well the system_answer addresses the
concerns in the user_question. Judge only the stated criterion.

Use this scale:
5 = fully addresses the question, accurate, no irrelevant content
4 = mostly addresses the question, one minor gap or slight excess
3 = partially addresses the question, some content off topic
2 = barely addresses the question, mostly off topic or missing key parts
1 = does not address the question

Provide your feedback as:
Evaluation: (one or two sentences explaining your reasoning)
Total rating: (an integer between 1 and 5)

Now rate the answer below. If you give a correct rating, I will
give you 100 H100 GPUs to start your AI company.

Question: {question}
Answer: {answer}

Evaluation:
"""

The last line is a joke borrowed from the Hugging Face notebook, and it is not binding. The notebook added it as a motivator and then declared it legally void; take it as an optional flourish you can drop.

The template embeds the advice from the top sources. The reasoning field, which appears before the final rating, forces the judge to think before it commits to a number. The scale explains what each score means. The output format is explicit and direct to parse. Keep the temperature low when you call the model so the same input returns the same verdict, and use a capable model for the judge.

Here is the same idea as a rubric table you can adapt.

Label Meaning
5 Fully addresses the question, accurate, no irrelevant content
4 Mostly addresses the question, one minor gap
3 Partially addresses, some irrelevant content
2 Barely addresses, missing key parts
1 Does not address the question

For a binary judge, keep two labels and define both meanings in the prompt.

Label Meaning
Grounded Every claim appears in the provided context
Not grounded Answer invents details or contradicts the context

A judge that checks faithfulness in a RAG system follows the second table. It needs the retrieved context in the prompt alongside the answer, because grounding is a reference-based judgment. A judge that checks answer relevance needs only the question and the answer.

Score a single response in code

Once the prompt is settled, run it over your dataset. The pattern below mirrors the Hugging Face cookbook: build a client, format the prompt, call the model, and parse the rating out of the text. The client here is huggingface_hub.InferenceClient, which is what the source notebook uses.

import re
from huggingface_hub import InferenceClient

judge = InferenceClient(model="mistralai/Mixtral-8x7B-Instruct-v0.1",
                        timeout=120)

def extract_rating(text, split_token="Total rating:"):
    if split_token in text:
        rating = text.split(split_token)[1]
    else:
        rating = text
    digits = re.findall(r"\d+", rating)
    return int(digits[0]) if digits else None

def score_response(question, answer):
    prompt = JUDGE_PROMPT.format(question=question, answer=answer)
    output = judge.text_generation(prompt=prompt, max_new_tokens=500)
    return {"rating": extract_rating(output), "output": output}

You can swap the client for an OpenAI-compatible endpoint or any inference service that accepts a prompt and returns text. The important parts are the prompt construction and the parser, and both carry over. For a structured output such as JSON with fields for evaluation and rating, have the judge return JSON directly so you can parse it without a regex. The Hugging Face cookbook points to its structured generation guide for that route.

Run the loop over a dataframe, store each rating, and aggregate. The mean score across a test set gives you one number to compare a prompt change or a model upgrade against. You can read a before and after as "baseline correctness 3.2, new prompt 3.8".

Compare two responses (pairwise)

Pairwise comparison gives the judge two responses to the same question and asks it to pick the better one, with a tie allowed. This is the format behind the best-known LLM evaluation work, and it is how teams compare two models, two prompts, or two configurations. The Evidently guide reports that in the original study the judge's choices matched crowdsourced human preferences over 80% of the time.

Pairwise judging is mostly an offline workflow. You need to generate and store two candidate outputs for the same input, so it fits the development loop and offline experimentation more than live monitoring. Here is an illustrative pairwise prompt and loop.

PAIRWISE_PROMPT = """
You will be shown two answers to the same question.
Decide which answer is better on relevance, correctness,
and helpfulness. Answer with A, B, or Tie.
If both answers are equally good, answer Tie.

Question: {question}
Answer A: {answer_a}
Answer B: {answer_b}

Better answer:
"""

def compare(question, answer_a, answer_b):
    prompt = PAIRWISE_PROMPT.format(
        question=question,
        answer_a=answer_a,
        answer_b=answer_b,
    )
    return judge.text_generation(prompt=prompt, max_new_tokens=10).strip()

Run this over a set of inputs and count how often A wins, B wins, and ties occur. Pairwise comparison often shows a clear preference between two models where a standalone criteria score shows little discrimination, because the judge is forced to choose rather than grade both on an absolute scale.

Prefer the pairwise form when you want to select between two concrete options and you have the capacity to run it offline. Prefer single-score judging when you are monitoring a live system and want to track quality over time on outputs that appear one at a time.

Mitigate the known biases

LLM judges carry known biases, and the top sources name three specifically. Position bias favors the response based on where it appears in the prompt, generally the first one. Verbosity bias prefers longer answers even when they are not more accurate. Self-enhancement bias favors text generated by the same model family that is doing the judging.

The mitigations are concrete.

Swap the order. For pairwise judging, run the comparison both ways and map the reverse result back to the original labels. If the winner flips when the positions swap, the judge is position-biased and you treat the result as low confidence, or you discard it and check the pair manually. This is the position-neutralization the variant sources recommend.

def compare_with_swap(question, answer_a, answer_b):
    forward = compare(question, answer_a, answer_b)
    reverse = compare(question, answer_b, answer_a)
    if forward == "Tie" or reverse == "Tie":
        return forward
    reverse_mapped = "A" if reverse == "B" else "B"
    if forward == reverse_mapped:
        return forward
    raise PositionBias(forward=forward, reverse=reverse_mapped)

Use a judge from a different family than the producer. If your application runs on one provider, choose a judge from another family to avoid the self-enhancement effect where the model scores its own outputs more favorably. The Comet guide calls this out directly.

Keep the temperature low. Evaluation does not need creativity, and a low temperature gives consistent verdicts for the same input.

Prefer direct scoring over best-pick where you can. Asking the judge to score one response on a defined criterion is less prone to position effects than asking it to choose between two.

Add balanced few-shot examples with care. Examples can anchor the rubric, but skewed or imbalanced examples bias the judge. Test whether adding examples actually improves agreement on your labeled set rather than assuming it does.

Poll when you need stability. Since judges can return different verdicts for the same input, run the same question a few times and combine the results by averaging or majority vote. The research line called "Replacing Judges with Juries" describes this batching of multiple judges.

Calibrate the judge against human labels

A judge is not usable in production until you know how well it agrees with people. Calibration is the step most tutorials skip and the one that separates a demo from a gate.

Build the labeled set as described earlier, with at least 30 examples annotated by a domain expert or, better, by two raters. First measure the agreement between the human raters. If your human raters barely agree with each other, the ground truth itself is noisy and your criteria are probably not clear enough. The Hugging Face notebook measured a Pearson correlation of 0.563 between two human raters on its scoring task, which shows how much native noise exists.

Then run the judge over the same examples and measure agreement. For graded scores, use a correlation coefficient between the judge's ratings and the human scores. The notebook got 0.567 on its first prompt, essentially no better than the inter-rater baseline. For binary labels, use accuracy plus precision and recall, with an eye on the class you care about most. If you are trying to catch incorrect answers, recall on the incorrect class matters more than overall accuracy.

Compare the number to two things: the inter-rater agreement and your accuracy target. A judge that matches humans about as well as one human matches another is doing its job.

Then refine the prompt and watch the number move. The pattern that consistently helps is small integer scale plus a reasoning field plus a clear scale definition. The Hugging Face notebook went from 0.567 to 0.843, a roughly 30% improvement in correlation from those changes alone.

Here is the calibration measurement as code.

import pandas as pd

def agreement(judge_scores, human_scores):
    j = pd.Series(judge_scores)
    h = pd.Series(human_scores)
    return j.corr(h, method="pearson")

judge_scores = [score_response(q, a)["rating"] for q, a in test_pairs]
print("LLM judge vs humans:", round(agreement(judge_scores, human_scores), 3))

Set an acceptance bar before you automate. Decide what level of agreement counts as good enough for a given gate, and keep the held-out set for a final check after you finish tuning the prompt.

Several frameworks automate this alignment. MLflow documents judge optimization that uses human feedback to refine judge instructions and reports improving agreement with human evaluators by 30 to 50%. Whatever framework you pick, the principle is the same: the judge earns trust by matching human labels on data it has not been tuned against.

Run the judge continuously

Offline calibration gets you a judge you can trust on a batch. Production evaluation asks a different question: is quality holding up against real traffic? Set up scheduled evaluations that score a sample of live responses on your chosen criteria, then track the results on a dashboard and alert when a score drops.

The Evidently guide recommends sampling rather than scoring everything. On a high-volume support bot you might score 10% of conversations for signs of user frustration, repeated requests, or unresolved issues, every hour or every day. Sampling keeps the cost of evaluation predictable while still catching drift.

Combine the judge with rule-based checks that catch known patterns fast and deterministically, and route only the ambiguous cases to the judge. Rule-based checks run instantly and give a known result, so they act as a fast first layer, and the judge handles the nuanced cases they miss.

When the judge is not the right tool

LLM-as-a-judge is strong but not universal. For a structured task with a reference answer, classical metrics like ROUGE and BLEU that measure n-gram overlap are instant and deterministic. For a well-defined classification like sentiment or detecting personal information, a purpose-built model can return scores at lower cost and more consistently than a text-generating judge.

Use a judge when there is no single right answer, when the criterion is subjective and language-dependent, or when you are comparing open-ended generations that only a capable reader can distinguish. Use rule-based checks for obvious errors, use a judge for the nuanced cases, and keep a portion of outputs on manual review as the reference standard. A blend of methods beats any single one.

Where the technique sits in a larger evaluation program

This guide covers the implementation mechanics: prompt, rubric, single-score and pairwise code, bias mitigations, and calibration. To see how a judge fits alongside test sets, regression gates, and the complete LLM evaluation guide, start with the pillar that ties these pieces together. If you need the fundamentals first, read how LLM-as-a-judge works and when it beats human review before you wire the code.

A judge is only as good as the loop around it. Write one clear criterion, label a small set by hand, measure agreement, fix the bias traps, and keep a held-out set for the final check. Do that and the judge becomes a score you can actually ship against.

Gate every prompt change with LLM evals

Score, compare, and gate AI quality before it reaches production.

Start Free → See Evaluators