Datasets & Ground Truth
The most common reason an eval lies to you is a bad dataset. Metrics get all the attention, but the dataset is where credibility is quietly won or lost.
What makes an eval set trustworthy
- Representative — mirrors the real input distribution (queries, formats, languages). An eval of clean, easy inputs gives a flattering, useless number.
- Sufficiently sized — big enough that the aggregate is stable run-to-run (Chapter 1's lesson).
- Sliced — tagged by segment so you see where quality lives, not just an average that hides failures.
- Hard where it matters — deliberately includes the failure-prone, high-stakes cases. The point is to catch problems, not feel good.
Goldens rot; contamination inflates; synthetic helps with care
A golden dataset is a curated, human-blessed yardstick — and it decays as the product and users change. Treat it as a maintained, versioned, owned asset. Watch for data contamination: if your eval cases were in the model's training data (common with public benchmarks), the score is inflated and meaningless for your use case — prefer private, recent, or custom sets. Synthetic data (an LLM generating plausible cases) is great for bootstrapping breadth, but skews toward what the model finds natural; use it to scale coverage, and real human-curated data to anchor truth.
An eval set of only easy queries reported one team a reassuring 92%. The same system on real, representative traffic: 64%. Nothing changed but the dataset. Your dataset is your measurement.
Make slicing reveal the hidden failure
You're handed per-case scores tagged by slice (no model call needed). Compute the overall, then each slice, and surface the weak ones. The point: the blended average looks fine; the slice view is where the truth lives.
Lab code — runs free
from statistics import mean
# Per-case scores, already tagged by slice
SCORED = [
{"slice": "en", "score": 0.95}, {"slice": "en", "score": 0.92},
{"slice": "en", "score": 0.97}, {"slice": "en", "score": 0.90},
{"slice": "es", "score": 0.61}, {"slice": "es", "score": 0.55},
{"slice": "code", "score": 0.40}, {"slice": "code", "score": 0.48},
]
overall = mean(r["score"] for r in SCORED)
by_slice = {s: mean(r["score"] for r in SCORED if r["slice"] == s)
for s in {r["slice"] for r in SCORED}}
print(f"overall: {overall:.2f}")
for s, v in sorted(by_slice.items(), key=lambda kv: kv[1]):
flag = " <-- WEAK" if v < 0.70 else ""
print(f" {s:5} {v:.2f}{flag}")
overall: 0.72
code 0.44 <-- WEAK
es 0.58 <-- WEAK
en 0.94
A "0.72 overall" sounds shippable. Sliced, it's an excellent English system bolted to a broken code-handling path and a shaky Spanish one. If your eval set were 90% English (unrepresentative), the blended number would climb toward 0.90 and you'd ship the breakage. Representativeness + slicing is the whole game; the metric is downstream.
Cortex: the 92% that was really 64%
Cortex reported 92% accuracy on their support assistant and planned to expand aggressively. The number came from an eval set built by the team writing "typical" questions — clean, well-phrased, and unrepresentative of the messy, terse, edge-case-laden things real customers actually ask. When they rebuilt the eval set by sampling real traffic, the same system scored 64%. Nothing about the model changed; only the dataset did.
The 28-point gap was pure dataset flattery, and it had nearly driven a bad scaling decision. They fixed it by building the set from real usage, tagging by segment, sizing each important slice to stay stable, and assigning an owner to refresh it as the product changed. The principle their team internalized: an eval is only as honest as the cases it runs on — a beautiful number on an unrepresentative set tells you about the set, not the system.
This chapter: Meridian builds Remi's eval set from real support tickets, tagged by intent — balance queries, refund requests, disputes. They notice the refund slice is small (about 12% of traffic) but high-stakes, so they deliberately over-sample it to a few hundred cases: a blended average would drown out the exact slice where a mistake costs money. A named support lead owns the set and refreshes it monthly. (Ch 6: they get human labels for that refund slice.)
Quiz · Chapter 3
- The most common reason an eval gives misleading results is:
- "Slicing" an eval set means:
- Data contamination refers to:
- The right role for synthetic eval data is to:
- A golden dataset should be treated as: