Chapter 5 — Evaluating LLM Applications
Fifth post of the chapter-by-chapter walkthrough of LLM Primer V: Building Real-World LLM Applications. The chapter that admits assertEqual is dead for LLM outputs and rebuilds the testing discipline around anchored judges, the RAG Triad, and trajectory tests.
Why this chapter exists
Classical software testing rests on the assumption that a correct output is a specific output — the function returns 42, the string equals "Hello, world," the JSON matches the fixture. LLM systems produce paraphrases that are meaning-equivalent but character-different, and the exact-match assertion that has anchored software testing for fifty years collapses on the first regeneration. Teams then reach for BLEU, ROUGE, or embedding cosine similarity and discover that these metrics correlate weakly with human judgment on the things that matter — is the answer right, is it grounded, is it addressing the question. Chapter 5 rebuilds the testing discipline around what actually works: anchored LLM-as-a-judge rubrics, the RAG Triad, agent trajectory tests, and a continuous loop where production traces feed the evaluation set that gates the next release.
5.1 The evaluation gap and LLM-as-a-judge
The evaluation gap is the distance between what a classical test can measure and what an LLM output actually needs measured. Exact-match and reference-string metrics catch none of the interesting failures on paraphrase-heavy tasks. LLM-as-a-judge is the workhorse that closes the gap, with two disciplines that separate it from a party trick. First, the judge's rubric is anchored: each score value has a written definition, ideally with an example, so the judge is not free-associating a number. Second, the judge produces reasoning before the score, because a judge that has to write out its reasoning is a judge that scores more consistently. Programmatic checks complement the judge for what is deterministically verifiable — JSON parses, required fields present, no forbidden strings, response length within bounds. The judge is not universal; it is what covers the ground the deterministic checks cannot.
5.2 The RAG Triad — context, groundedness, answer relevance
For retrieval systems, the pattern that has crystallized is scoring three vertices independently. Context relevance asks whether the retrieved chunks are actually relevant to the query, and it isolates retrieval failures from generation failures. Groundedness asks whether the generated answer follows from the retrieved context, and it catches hallucinations that pass shape validation. Answer relevance asks whether the answer addresses the question the user actually asked. Scored independently, the three vertices localize failures: a low context-relevance score points at retrieval, a low groundedness score points at the generator, a low answer-relevance score points at either the router or a system that is answering an adjacent question. RAGAS operationalizes the triad as a batch pipeline; the quality of the judge model dominates the quality of the scores, so the judge itself is a component the team evaluates.
5.3 Framework niches and agent regression
Three frameworks occupy distinct niches. RAGAS runs the RAG Triad in batch against a dataset of question-answer pairs and is the right tool for periodic dataset evaluation. TruLens attaches feedback functions to live production traffic and computes the triad on the traces themselves, closing the loop between production and evaluation. DeepEval runs LLM tests as CI gates the way pytest runs unit tests, with per-metric thresholds. Agents extend all of this in three directions: trajectory snapshot tests assert the shape of the tool-call sequence for a fixed input, catching structural drift; invariant assertions verify that the agent did not call a forbidden tool or skip a required approval; rubric tests score the trajectory itself for whether the path was reasonable. An agent that gives the right answer the wrong way is one prompt change away from giving the wrong answer the same way, and the trajectory test is the discipline that catches that.
What Chapter 5 sets up
Evaluations need production traces to sample from. CI gates need real regressions to guard against. The continuous-improvement loop only works if there is an observability layer capturing every step of every invocation — the model calls, the tool calls, the retrieval results, the sub-agent hops, the cost, the latency, the user feedback. Chapter 6 is that layer. It walks OpenTelemetry with GenAI semantic conventions, the metrics that actually matter for LLM systems, the platform choices, and — most importantly — the export pipeline that routes low-scoring traces back into the evaluation set that gates the next release.
Next — Chapter 6: AI Observability and Tracing. The substrate that makes both evaluation and debugging possible — one nested trace per invocation, with cost and quality attached as first-class attributes.