Medical AI · Retrieval-augmented generation (RAG) · Lesson 7 of 7
End-to-end RAG evaluation
Reviewed by Dr. Ram Kumar G, MBBS, MD (Internal Medicine), MPH (USA), on · Last updated
- Intermediate
- Technical focus
- About 30 minutes
- Includes exercise
Before this lesson: Build a guideline Q&A assistant
In short
End-to-end evaluation runs the whole assistant on a labelled test set and checks three things: did it retrieve the right source, did its answer contain the key facts, and did it decline questions its documents do not cover? Comparing settings on the same set shows what actually helps. Here, quoting whole sections raised correct answers from 6 of 8 to 8 of 8 with no loss of retrieval, and looking at retrieval scores showed a clear margin for setting the decline threshold, on a test set still far too small for real use.
You will learn to
- Design a labelled test set with key facts and out-of-scope questions
- Score a RAG assistant on retrieval, correctness and appropriate declining
- Compare configurations and attribute failures to retrieval or answering
- Choose a decline threshold from score distributions, and know what further evaluation is needed
What to measure
Frameworks such as RAGAS and ARES automate some of these measures with language-model judges. They are useful at scale but need checking against human labels, especially in clinical domains.
| Metric | Question | Failure it catches |
|---|---|---|
| Retrieval accuracy | Was the cited source the right one? | Wrong section retrieved |
| Answer correctness | Does the answer contain the key facts? | Right section, incomplete or wrong answer |
| Faithfulness | Is every statement supported by the retrieved text? | Added or altered content (mainly for generated answers) |
| Appropriate declining | Did it decline questions the documents do not cover? | Confident answers to out-of-scope questions |
| Safety | Are urgent situations handled correctly? | Missed red flags (see the red-teaming lesson) |
Scoring the assistant
The test set has eight answerable questions, each with the section that answers it and the key facts a correct answer must contain, and two questions the protocol does not cover. Run the protocol block and the assistant block from the previous lessons first.
TESTS = [ # (question, section that answers it or None, key facts a correct answer must contain)
("When should metformin be stopped?", "s2", ["below 30"]),
("Can metformin be started with an eGFR of 40?", "s2", ["below 45"]),
("What should I do about a hypo?", "s4", ["15 g", "15 minutes"]),
("How is a low glucose treated?", "s4", ["15 g"]),
("How often should HbA1c be checked after a change in treatment?", "s1", ["3 months"]),
("How often is foot sensation tested?", "s3", ["once a year"]),
("When should an ulcer be referred urgently?", "s3", ["spreading redness"]),
("When does eye screening start?", "s5", ["at diagnosis"]),
("What dose of semaglutide should I start?", None, []),
("Is it safe to fast during Ramadan with diabetes?", None, []),
]
def evaluate(**settings):
retrieved = correct = refused_right = answerable = unanswerable = 0
for q, gold, facts in TESTS:
r = answer(q, **settings)
cited = r["citations"][0].split(":")[0] if r["citations"] else None
if gold is None:
unanswerable += 1
refused_right += cited is None
continue
answerable += 1
retrieved += cited == gold
correct += cited == gold and all(f in r["answer"] for f in facts)
print(f"{str(settings):<42} retrieval {retrieved}/{answerable} correct {correct}/{answerable} "
f"declined unanswerable {refused_right}/{unanswerable}")
evaluate(max_sentences=2)
evaluate(max_sentences=None)
evaluate(max_sentences=None, min_score=0.45)
# {'max_sentences': 2} retrieval 8/8 correct 6/8 declined unanswerable 2/2
# {'max_sentences': None} retrieval 8/8 correct 8/8 declined unanswerable 2/2
# {'max_sentences': None, 'min_score': 0.45} retrieval 8/8 correct 8/8 declined unanswerable 2/2- With two-sentence answers, retrieval was perfect but two answers missed key facts: a generation (answering) failure, not a retrieval failure. Separating the two tells you where to fix.
- Quoting whole sections fixed both without affecting retrieval or declining.
- Raising the threshold to 0.45 changed nothing here, which needs explaining before trusting either value.
Setting the decline threshold from data
scores = [(answer(q, min_score=0.0)["retrieval_score"], gold is not None, q) for q, gold, _ in TESTS]
for s, answerable, q in sorted(scores):
print(f"{s:.2f} {'answerable ' if answerable else 'out of scope'} {q}")
lowest_answerable = min(s for s, a, _ in scores if a)
highest_unanswerable = max(s for s, a, _ in scores if not a)
print(f"\nMargin: lowest answerable {lowest_answerable:.2f}, highest out-of-scope {highest_unanswerable:.2f}")
# 0.31 out of scope Is it safe to fast during Ramadan with diabetes?
# 0.32 out of scope What dose of semaglutide should I start?
# 0.49 answerable When does eye screening start?
# 0.51 answerable When should an ulcer be referred urgently?
# 0.53 answerable When should metformin be stopped?
# 0.55 answerable Can metformin be started with an eGFR of 40?
# 0.63 answerable What should I do about a hypo?
# 0.66 answerable How often is foot sensation tested?
# 0.67 answerable How is a low glucose treated?
# 0.77 answerable How often should HbA1c be checked after a change in treatment?
#
# Margin: lowest answerable 0.49, highest out-of-scope 0.32- Any threshold between 0.32 and 0.49 separates these questions, which is why 0.35 and 0.45 behaved the same.
- Real users ask borderline questions: related topics the documents only partly cover, or covered topics in unusual words. A real test set needs many of them to place the threshold sensibly, and should weigh the cost of a wrong answer against the cost of an unnecessary 'I don't know'.
From a small demo to a real evaluation
- Hundreds of questions, written with clinicians and including patients' wording, abbreviations, misspellings and borderline topics.
- Key facts and acceptable answers agreed by more than one clinician, with severity for each possible error.
- Separate scores for retrieval, correctness, faithfulness, declining and safety, with confidence intervals.
- Repeated runs if the system uses a language model, since answers vary.
- A regression suite re-run after every change to documents, chunking, models, prompts or thresholds.
- After deployment, monitoring of real questions, declines and user feedback, feeding new test cases.
About the teaching document
- The protocol used in this track was written for teaching. Its statements are broadly in line with common practice, but it is not clinical guidance and must not be used for patient care.
- In a real system, the documents would be your organisation's approved guidelines, with version control and an owner responsible for keeping them current.
Exercise
Evaluate and improve the guideline assistant end to end, and design a realistic evaluation plan.
Data: Synthetic protocol and labelled questions in the notebook (Created for this course; not clinical guidance)
- Reproduce the three configurations and the score distribution.
- Add ten borderline questions (partly covered topics, unusual wording) and re-examine the threshold.
- Add a faithfulness check that every sentence of the answer appears in the cited section, and confirm it passes for extractive answers.
- Optional, with an approved model: add a generation step and measure faithfulness and correctness again; which errors appear?
- Write a one-page evaluation plan for deploying a guideline assistant in a clinic.
Open the notebook in ColabView on GitHubWorked solution coming soon
Key takeaways
- Score retrieval, answer correctness, faithfulness, declining and safety separately.
- Separating retrieval from answering failures shows where to fix the system.
- Set the decline threshold from score distributions, using many borderline questions.
- Small demos show the method; real evaluation needs large, clinician-labelled test sets.
Terms used: Grounding, RAG (retrieval-augmented generation), Recall@k
Related: Build a guideline Q&A assistant, Evaluating retrieval, Red-teaming LLM applications
FAQ
How do you evaluate a RAG system?
By running it on labelled questions and measuring whether it retrieved the right source, whether its answers contain the key facts and are supported by the source, and whether it declines questions it cannot answer.
What is faithfulness in RAG evaluation?
Whether every statement in an answer is supported by the retrieved text. Extractive answers are faithful by construction; generated answers need to be checked.
How do I choose the threshold for declining?
Look at retrieval scores for questions the documents can and cannot answer, including borderline ones, and choose a threshold that balances wrong answers against unnecessary declines.
Are automated RAG evaluation tools reliable?
They are useful for scale, but they rely on language-model judges that can be wrong. Validate them against clinician labels for your domain.
How large should a RAG test set be?
Large enough to cover every important topic, phrasing style and edge case, typically hundreds of questions for a clinical system, with more for safety-critical topics.
Sources
- Es S, et al. RAGAS: automated evaluation of retrieval augmented generation. EACL 2024 (system demonstrations). arXiv:2309.15217
- Saad-Falcon J, et al. ARES: an automated evaluation framework for retrieval-augmented generation systems. NAACL 2024. arXiv:2311.09476
- Xiong G, et al. Benchmarking retrieval-augmented generation for medicine. Findings of ACL 2024. arXiv:2402.13178
- Asgari E, et al. A framework to assess clinical safety and hallucination rates of LLMs for medical text summarisation. npj Digital Medicine 2025;8:274. doi:10.1038/s41746-025-01670-7
Educational content only. This material teaches methods; it is not clinical advice. Code, models and examples here are not validated medical devices and must not be used to make decisions about real patients without proper clinical validation, governance and any required regulatory approval. Examples use synthetic or openly licensed de-identified data only. Never paste identifiable patient information into public AI tools. Mentions of models, tools or vendors are for identification, not endorsement.