Skip to content
PHP2Shell: The PHP Bug
Akshay Thakare

Evaluating a RAG System: Retrieval and Answers

Measure retrieval and generation separately: recall@k, MRR, groundedness and answer correctness, with an evaluation set you build from real questions.

RAGAdvanced2 min readUpdated 11 Oct 2026

Two systems, two sets of metrics

If the right passage is never retrieved, no prompt can fix the answer. Evaluate retrieval first, then generation.

Build the evaluation set

For 50–200 real or realistic questions, record:

  • the question
  • the document chunk(s) that contain the answer
  • a reference answer, or the key facts it must contain
  • some questions whose answer is not in the corpus

Retrieval metrics

MetricMeaning
Recall@kShare of questions where a correct chunk is in the top k
MRRAverage of 1 / rank of the first correct chunk
Precision@kShare of the top k that are relevant
Python.py
def recall_at_k(results, gold, k=5):
    hits = sum(any(doc in gold[q] for doc in docs[:k]) for q, docs in results.items())
    return hits / len(results)

Answer metrics

MetricChecks
Groundedness / faithfulnessEvery claim is supported by the retrieved context
CorrectnessMatches the reference answer's key facts
Refusal accuracySays "not found" when the answer is not in the corpus

Model-based grading can score these at scale, but spot-check its judgements by hand and keep the grading rubric specific.

Use it like a test suite

Run the evals on every change: chunk size, embedding model, retriever, reranker or prompt. Keep the change only if the metrics improve without breaking refusals.

Finished this note?

Share