Evaluating Generative-AI Systems
An end-to-end score hides failure causes. Record the exact task set, prompt and index versions, model and decoding configuration, environment, and raw outcomes. Then separate retrieval quality, context construction, answer faithfulness, task usefulness, safety, latency, and cost.
Prerequisites
Know relevance labels, citations, validation, and basic summary statistics.
Learning goals
- keep component metrics separate from end-to-end outcomes.
- compute metrics over a fixed, versioned evaluation set.
- combine deterministic checks with blinded human review where judgment is required.
Worked example
The four rows are fixed observations, not model outputs. Units for cost must be declared by an adapter—tokens, CPU time, or currency at a dated price—not mixed silently.
runs = [
{"retrieved": True, "citation_valid": True, "faithful": True, "useful": True, "latency_ms": 120, "cost": 3},
{"retrieved": True, "citation_valid": True, "faithful": False, "useful": False, "latency_ms": 180, "cost": 4},
{"retrieved": False, "citation_valid": False, "faithful": False, "useful": False, "latency_ms": 90, "cost": 2},
{"retrieved": True, "citation_valid": True, "faithful": True, "useful": True, "latency_ms": 240, "cost": 5},
]
retrieval_recall = sum(row["retrieved"] for row in runs) / len(runs)
cited = [row for row in runs if row["citation_valid"]]
citation_precision = sum(row["faithful"] for row in cited) / len(cited)
faithfulness = sum(row["faithful"] for row in runs) / len(runs)
usefulness = sum(row["useful"] for row in runs) / len(runs)
latencies = sorted(row["latency_ms"] for row in runs)
p95 = latencies[-1] # nearest-rank p95 for four teaching observations
print(f"retrieval_recall={retrieval_recall:.3f} citation_precision={citation_precision:.3f} faithfulness={faithfulness:.3f}")
print(f"task_success={usefulness:.3f} p95_latency_ms={p95} cost_units={sum(row['cost'] for row in runs)}")
Output:
retrieval_recall=0.750 citation_precision=0.667 faithfulness=0.500
task_success=0.500 p95_latency_ms=240 cost_units=14
This toy “citation precision” asks whether a cited run is faithful, not whether every sentence has adequate support. Define metric denominators precisely. Include ordinary, difficult, refusal, multilingual, long-context, access-control, and adversarial cases that match the deployment risk.
Common mistakes
- Reporting one aggregate score or provider leaderboard as universal quality.
- Using a model judge without validating it against independent human labels and slices.
- Changing the test set after reading failures while keeping the old claim.
- Ignoring confidence intervals, repeated samples for stochastic systems, and missing outcomes.
Practice
Write a rubric for policy-question answers with separate support, completeness, harmlessness, and usefulness ratings. Specify which disagreements require human adjudication.
Next steps
Hallucination, Grounding, and Uncertainty turns missing support into a safe answer or fallback decision.
Primary sources
Checked 2026-10-16: Holistic Evaluation of Language Models, NIST AI RMF Generative AI Profile, and Model Cards for Model Reporting.