AI Engineer Dojo Contents
Chapter 6

Human Evaluation & Annotation

Automated scorers and judges are scaffolding on top of human judgment. Humans remain the ground truth for subjective quality — and the eval engineer usually designs, runs, and quality-controls that human process.

When to spend humans, and the skill that decides it

Humans are slow and expensive — spend them where they're irreplaceable: creating golden sets, validating judges, high-stakes or subjective calls, and preference data. Everything else is automated and spot-checked. The real skill is rubric design: "rate quality 1–5" yields noise; a good rubric defines each criterion concretely and reduces judgment to the smallest reliable decision — often a binary per dimension (grounded? yes/no). The same rubric discipline works for humans and LLM judges.

Key metric

Inter-annotator agreement (e.g., Cohen's kappa) measures whether your humans agree with each other. Crucially, kappa corrects for chance: raw agreement can look great while kappa is mediocre. Low kappa means the rubric is ambiguous, not that the annotators are bad — and you can't expect a model judge to hit a target humans can't agree on.

Preference data closes the loop to training

Pairwise human preferences ("A is better than B") do double duty: they validate systems and they're the raw material for post-training (RLHF/DPO). Knowing that evaluation quietly becomes the data engine for model improvement signals seniority.

Try it · ~10 minFree · no API key

Compute Cohen's kappa by hand — and see why raw agreement lies

Two annotators label 10 answers (grounded? 1/0). You'll compute raw agreement and chance-corrected kappa (pure stdlib, free). The point: watch a reassuring raw-agreement number deflate once you remove what chance alone would have produced.

Lab code — runs free

A = [1, 1, 0, 1, 0, 0, 1, 1, 0, 1]   # annotator A: grounded? 1/0
B = [1, 0, 0, 1, 0, 1, 1, 1, 0, 1]   # annotator B
n = len(A)

po = sum(a == b for a, b in zip(A, B)) / n      # observed (raw) agreement
pa1, pb1 = sum(A) / n, sum(B) / n               # each rater's rate of "1"
pe = pa1 * pb1 + (1 - pa1) * (1 - pb1)           # agreement expected by chance
kappa = (po - pe) / (1 - pe)

print(f"raw agreement = {po:.2f}")
print(f"chance        = {pe:.2f}")
print(f"kappa         = {kappa:.2f}")
Worked solution
raw agreement = 0.80
chance        = 0.52
kappa         = 0.58

Raw agreement of 0.80 looks like a solid rubric. But because both annotators say "grounded" most of the time, chance alone would produce 0.52 agreement — so the chance-corrected kappa is only 0.58 ("moderate"). If kappa dropped toward 0.3, that's your signal the rubric is ambiguous: rewrite it (sharper criteria, examples per label) before you trust either the humans or an LLM judge calibrated against them. Reporting raw agreement without kappa is how teams convince themselves a fuzzy rubric is fine.

Case study

Ravel: ground truth that wasn't

Ravel validated their LLM judge against human labels — good practice — but the judge kept "disagreeing" with the humans in ways that made no sense. The real problem was upstream: the human labels themselves were noisy. Three annotators using a vague one-line guideline agreed with each other only 64% of the time. Their "ground truth" was closer to three people's differing opinions than a truth, so measuring the judge against it was measuring against static.

They fixed the humans before the model: a written rubric with examples of each label, a calibration round on shared cases, and adjudication of disagreements by a senior reviewer. Inter-annotator agreement rose to 89%, and only then did the judge's numbers become interpretable. The lesson: human evaluation is a measurement instrument too, and an instrument you haven't calibrated can't be the yardstick for anything — garbage ground truth makes every downstream number meaningless.

Running case · Meridian × Remi

This chapter: two Meridian support leads independently label 120 of Remi's refund replies as acceptable / not, against a written rubric. Initial agreement is 0.72; they adjudicate the conflicts and tighten the guideline, reaching 0.9. This human-labeled refund set is exactly what they measured the Chapter-5 judge against — which is how they caught that it was only 56% right on the slice that matters. (Ch 7: Remi's answers come from billing docs — is retrieval the problem?)

Quiz · Chapter 6

  1. Low inter-annotator agreement (kappa) usually means:
  2. Why does kappa deflate a reassuring raw-agreement number?
  3. Humans should be spent primarily on:
  4. A good rubric reduces judgment to:
  5. Human pairwise preference data is also used to:
← Back Continue →

The AI Evaluation Engineer · AI Engineer Dojo · aiengineerdojo.com