learn-ai-evals-with-phoebe / Builder session 3 of 10
Learn Evals with Phoebe · Builder track · Session 3 of 10

Retrieval metrics: the full family, and which to gate on

In b1 you met Hit Rate and MRR. They are the front door, not the whole house. This session opens the rest: Precision@k, Recall@k, and NDCG, plus the distinction between measuring whether the ranking is good (precision, MRR, NDCG) and whether it is complete (recall). You will read the same live scorecard as a set of formulas, run LlamaIndex's evaluator with the whole metric suite, and - the point of the session - decide which single metric to gate Recall's retriever on and why.

🟡 Builder track · medium Practitioners · some Python Live scorecard included Session 3 of 10
0-3 · Welcome 3-20 · Metrics 20-40 · Build + choose 40-45 · Q&A
Part 0

Two metrics is not enough

Hit Rate says "did the right doc show up at all". MRR says "how high did the first right doc rank". Real questions need more: how much of the top k is actually relevant (precision), did we find all the relevant docs (recall), and how good is the whole ranking when relevance is graded rather than yes/no (NDCG). This session gives you the family, the formulas, and a rule for picking the one metric you will actually hold your retriever to.

Live - presented in session Self-study - full depth after class ★ Try it now Sources covered at the end
★ What you build today A working grasp of Precision@k, Recall@k, and NDCG alongside Hit Rate and MRR, the precision-versus-recall lens (ranking quality vs completeness), hands-on time reading the live scorecard as formulas, the LlamaIndex evaluator running the full suite, and a defended choice of the one metric to gate Recall on.
Part 1 · covers precision, recall, and ranking

Precision, recall, and where the metrics read from 9 min live

Every retrieval metric reads from the same object: a ranked list of results, each either relevant or not for this query. Once you can see that list, every metric is just a different question asked of it. Here is one ranked list, and the four metrics pointing at what they measure.

Ranked results for one query (2 of 3 relevant docs found in top 5) rank 1 relevant ✓ rank 2 not relevant rank 3 relevant ✓ rank 4 not relevant rank 5 not relevant Hit Rate + MRR first hit at rank 1: hit; MRR = 1/1 = 1.0 Precision@5 2 relevant in top 5 = 2/5 = 0.40 Recall@5 2 of 3 relevant docs found = 2/3 ≈ 0.67 (needs total relevant) Precision asks "of what I returned, how much was good?" Recall asks "of all the good, how much did I return?" Same ranked list, different questions. Precision guards against noise; recall guards against gaps. Every metric reads from one ranked, relevance-marked list. Learn to see the list first.
🔍 Click to zoom - one ranked list, and where each metric reads from it
LiveThe formula table3 min

Four metrics, four formulas, four different failures they catch. Keep this table next to the ranked list above.

MetricFormulaWhat it catches
Hit Rate@kfraction of queries with a relevant doc in top kDid we find it at all, anywhere in top k
MRRmean of 1/rank of the first relevant doc (0 if none)How high the first right answer ranks
Precision@krelevant in top k / kNoise: how much of what we returned was junk
Recall@krelevant in top k / total relevantGaps: how much relevant material we missed
LiveContext precision vs context recall3 min

RAGAS frames these two as the retriever's twin responsibilities, and names them in a way worth borrowing.

  • Context precision = ranking quality. It measures whether the relevant chunks are ranked high among what was retrieved. A retriever can return the right chunk buried at rank 8 and still have poor context precision - the good stuff has to be near the top.
  • Context recall = completeness. It measures whether all the chunks needed to answer were retrieved. Crucially, context recall requires a reference (a ground-truth answer or the set of relevant chunks) to know what "all" means - you cannot compute recall without knowing the full set of relevant docs.
  • They trade off. Widen k and recall rises while precision usually falls (more relevant found, but more junk too). The right balance depends on the product, which is Part 2's whole subject.
Recall needs a reference; precision does not Precision only needs the returned list labeled relevant/not. Recall needs the denominator - the total count of relevant docs - which only a reference gives you. This is why recall is the more expensive metric to measure honestly, and why some teams approximate it.
Part 2 · covers the live scorecard as formulas

Read the scorecard as formulas ★ 8 min live

This is the required build-along. Below is Recall's golden set scored live - the same numbers as b1, but this time you connect each on-screen number to the formula behind it. Move k and watch Hit Rate and Precision@1 diverge: they answer different questions and respond to k differently.

Live★ Build-along: numbers to formulas6 min

For the current k, take one row of the table and compute the metric by hand from the formula table above, then confirm it matches the on-screen number. Then change k: watch Hit Rate climb (a wider net finds more) while Precision@1 stays fixed (position 1 does not care about k). That divergence is the whole point.

Honesty note - what this scorecard really does Retrieval here uses the same simplified lexical embedder as the RAG course playground, so it runs with zero network. But the evaluation math - Hit Rate@k, MRR, Precision@1 over a golden set - is exactly what you compute in production. You are watching the real metric mechanic with a toy retriever.

Tie it back to the formulas: Hit Rate@k is hits anywhere in top k / number of queries, so raising k can only hold or raise it. Precision@1 is relevant in top 1 / 1, so it is decided entirely by what sits at rank 1 - untouched by k. MRR reads only the first hit's rank, so it too ignores k past that first hit.

Part 3 · covers NDCG + choosing a metric

NDCG, and choosing the one metric to gate on 9 min live

Hit Rate, MRR, and Precision treat relevance as yes/no. But some results are more relevant than others, and their position matters. NDCG handles both: graded relevance, discounted by rank. It is the metric of choice when the whole ordering matters, not just the first hit.

Graded relevance rank 1: rel 3 rank 2: rel 2 rank 3: rel 1 Rank discount divide each rel by log2(rank + 1): lower ranks count less DCG@k sum of the discounted rels NDCG DCG / IDCG DCG@k = sum over i of rel_i / log2(i + 1). IDCG@k is the DCG of the perfect ordering. NDCG@k = DCG@k / IDCG@k, so it always lands in 0 to 1 and is comparable across queries. NDCG rewards putting the most-relevant results highest. It judges the whole ranking, not one hit.
🔍 Click to zoom - graded relevance plus a rank discount, normalized, gives NDCG
Self-studyThe full suite from LlamaIndex3 min read

You do not implement these one by one in production. LlamaIndex's evaluator takes the metric names and reports the whole family over your golden set.

Python · LlamaIndex RetrieverEvaluator, full suitefrom llama_index.core.evaluation import RetrieverEvaluator # valid metric names: hit_rate, mrr, precision, recall, ap, ndcg evaluator = RetrieverEvaluator.from_metric_names( ["hit_rate", "mrr", "precision", "recall", "ndcg"], retriever=retriever, ) # run over the whole golden set (built in b2) at once results = await evaluator.aevaluate_dataset(golden_dataset) # average each metric across all queries import pandas as pd df = pd.DataFrame([r.metric_vals_dict for r in results]) print(df.mean().round(3)) # hit_rate 0.917 # mrr 0.806 # precision 0.306 # recall 0.917 # ndcg 0.842

One call, the whole family. Now the question is not how to compute them - it is which one you actually hold the retriever to.

Self-studyMRR vs NDCG, and which metric for which product3 min read

The last thing that matters is fit: the right metric depends on what your product does with the results.

  • MRR vs NDCG. MRR cares only about the rank of the first relevant result and treats relevance as yes/no. NDCG grades relevance and scores the whole ranking. Use MRR when one good hit is enough; use NDCG when the ordering of several results matters.
  • One-answer bot → Precision@1 or MRR. If the product shows a single answer (a support bot, a "top result" assistant), you only care about position 1. Gate on Precision@1 or MRR and ignore how the tail is ordered.
  • Research tool → Recall or NDCG. If the product surfaces many results for a human to scan (a search tool, a research assistant), completeness and whole-ranking quality matter. Gate on Recall (did we surface everything relevant) or NDCG (is the whole ordering good).
Real world Recall answers support-style questions with one grounded answer per query. That profile points at Precision@1 or MRR as the gating metric - the tail ordering barely matters when the user reads the top result. If Recall later grows a "show me everything about incident X" mode over corpus B, that mode would want Recall@k or NDCG instead. The metric follows the product.
Build-along · take it further

Choose Recall's gating metric ★ 10 min · the scorecard above

A retriever with five metrics and no chosen gate has no gate at all. Decide the one number Recall lives or dies by.

State the product. Write one line: what does Recall do with retrieved results? One grounded answer per query, or a list a human scans? Be honest about today, not the roadmap.

Map product to metric. One-answer → Precision@1 or MRR. Many-results → Recall@k or NDCG. Pick the single metric your product profile points at.

Read it off the scorecard. Find your chosen metric's current value in the live scorecard above. That number, at your chosen k, is the candidate gate.

Set and justify a threshold. Write the gate: "ship only if [metric] ≥ [value] at k=[k]" and one sentence on why that bar fits the product. That line is what b8's CI gate will enforce.

★ Recall's retriever after b3 Recall's retriever is no longer described by a single borrowed number - it has a full profile (Hit Rate, MRR, Precision, Recall, NDCG) and, more importantly, one chosen gating metric tied to what the product actually does. You can now say not just how good the retriever is, but which "good" you are holding it to. In b4 we turn from retrieval to generation metrics: faithfulness, relevance, and correctness of the answer itself.
Homework

Before session b4 ◐ 45 min total

Source material

Official sources covered

Taught from official docs. This page covers ~80% of their working content on retrieval metrics - the rest (custom metrics, hosted runners) lands in later sessions.

RAGAS · context precision + context recallPart 1 · ranking quality vs completeness · recall requires a reference
LlamaIndex · retrieval evaluation (full metric suite)Part 3 · hit_rate, mrr, precision, recall, ap, ndcg via from_metric_names
DCG / NDCG (definition + formula)Part 3 · rel_i / log2(i+1), normalized by IDCG, range 0-1
Check yourself

Three questions before you go 🎯 ◐ 90 seconds

1 · Precision@k and Recall@k differ because...

Precision divides by k and catches noise; recall divides by the total number of relevant docs and catches gaps - which is why recall needs a reference to know that denominator.

2 · NDCG differs from MRR mainly because...

MRR reads only the first relevant result's rank with binary relevance. NDCG grades relevance and discounts by rank across the whole list, then normalizes to 0-1 by the ideal ordering.

3 · For a support bot that shows the user one answer, the best gating metric is...

When the product shows a single answer, only position 1 matters. Precision@1 or MRR captures that; recall and wide-k metrics reward a tail the user never sees.

Builder session 3 cheat sheet · pin this

One ranked listEvery metric reads from the same ranked, relevance-marked list. See the list first.
Precision@krelevant in top k / k. Catches noise: how much of what you returned was junk.
Recall@krelevant in top k / total relevant. Catches gaps; needs a reference for the denominator.
Context precision vs recallRAGAS: precision = ranking quality; recall = completeness (requires a reference).
NDCG@kDCG@k / IDCG@k, DCG = sum rel_i / log2(i+1). Graded relevance + rank discount, range 0-1.
MRR vs NDCGMRR = first hit, binary. NDCG = whole ranking, graded. Pick by what the product shows.
LlamaIndex suitefrom_metric_names(["hit_rate","mrr","precision","recall","ndcg"]). One call, whole family.
Metric follows productOne-answer bot → Precision@1 / MRR. Research tool → Recall / NDCG. Gate on one.