Retrieval-Metriken: Hit Rate, MRR und NDCG
Sie erstellen einen Goldstandard-Datensatz aus Anfragen und relevanten Dokumenten und berechnen anschließend Hit Rate, Mean Reciprocal Rank und NDCG, um zu messen, wie oft Ihr Retriever die richtigen Chunks findet.
Retrieval-Metriken: Hit Rate, MRR und NDCG ist eine kostenlose AI Engineering Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Engineering Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Engineering Academy-Kurs umfasst insgesamt 4 Lektionen.
Warum gibt es verschiedene Retrieval-Metriken?
Die Hit Rate zeigt, ob irgendwo in den Top-K-Ergebnissen ein relevanter Chunk auftaucht, sagt aber nicht, an welcher Stelle der Rangliste er steht. Ein System, das den besten Chunk immer auf Rang 5 platziert, ist schlechter als eines, das ihn konsequent auf Rang 1 platziert, selbst wenn beide dieselbe Hit Rate haben. Genauere Metriken wie MRR und NDCG erfassen die Ranking-Qualität und belohnen Systeme, die die relevantesten Chunks ganz oben platzieren, wo das LLM und die Benutzer sie am wahrscheinlichsten verwenden.
Hit Rate @K: Wiederholung und Implementierung
Hit Rate@K ist die einfachste Metrik: Bei welchem Anteil der Abfragen erscheint mindestens ein relevanter Chunk in den Top-K-Ergebnissen? Sie liefert pro Abfrage ein binäres Signal und ist leicht zu interpretieren. Berechnen Sie sie, indem Sie die Schnittmenge der abgerufenen IDs und der bekannten relevanten IDs prüfen. Verwenden Sie standardmäßig K=5, da die meisten RAG-Systeme fünf Chunks abrufen. Vergleichen Sie Hit Rate@1, @3 und @5, um zu verstehen, wie sich die Trefferquote verändert, wenn Sie das Retrieval-Fenster vergrößern.
def hit_rate_at_k(golden_dataset, retriever, k=5):
hits = 0
for item in golden_dataset:
retrieved = retriever.retrieve(item['question'], top_k=k)
retrieved_ids = [r['id'] for r in retrieved[:k]]
relevant_ids = set(item['relevant_chunk_ids'])
if any(rid in relevant_ids for rid in retrieved_ids):
hits += 1
return hits / len(golden_dataset)
for k in [1, 3, 5, 10]:
hr = hit_rate_at_k(golden_dataset, retriever, k=k)
print(f'Hit rate@{k}: {hr:.1%}')Mean Reciprocal Rank (MRR)
MRR (Mean Reciprocal Rank) misst den durchschnittlichen Kehrwert des Rangs, auf dem der erste relevante Chunk erscheint. Befindet sich der relevante Chunk auf Rang 1, beträgt der reziproke Rang 1/1 = 1,0. Auf Rang 2 beträgt er 0,5, auf Rang 5 0,2. Der MRR wird über alle Abfragen gemittelt. Ein höherer MRR bedeutet, dass der Retriever relevante Chunks konsequent weit oben platziert. Das ist wichtig, weil das LLM Kontext, der früh im Prompt steht, stärker berücksichtigt.
def mean_reciprocal_rank(golden_dataset, retriever, top_k=10):
reciprocal_ranks = []
for item in golden_dataset:
retrieved = retriever.retrieve(item['question'], top_k=top_k)
retrieved_ids = [r['id'] for r in retrieved]
relevant_ids = set(item['relevant_chunk_ids'])
rr = 0.0
for rank, rid in enumerate(retrieved_ids, start=1):
if rid in relevant_ids:
rr = 1.0 / rank
break # only the first relevant result counts
reciprocal_ranks.append(rr)
mrr = sum(reciprocal_ranks) / len(reciprocal_ranks)
print(f'MRR@{top_k}: {mrr:.3f}')
return mrrMRR-Werte interpretieren
MRR-Werte lassen sich intuitiv interpretieren: MRR = 1,0 bedeutet, dass der erste relevante Chunk immer auf Rang 1 steht (perfekt). MRR = 0,5 bedeutet, dass er sich typischerweise auf Rang 2 befindet. MRR = 0,25 bedeutet, dass er sich typischerweise auf Rang 4 befindet – die relevanten Informationen stehen so weit unten, dass sie möglicherweise aus dem Kontext abgeschnitten werden. Für RAG sollten Sie einen MRR > 0,7 anstreben, damit Ihr relevantester Chunk konsequent an einer der ersten beiden Positionen steht.
# MRR interpretation table
mrr_interpretations = {
1.0: 'Perfect — relevant chunk always at rank 1',
0.5: 'Good — typically at rank 2',
0.33: 'Acceptable — typically at rank 3',
0.25: 'Weak — typically at rank 4',
0.1: 'Poor — relevant chunk rarely near the top'
}
for score, description in mrr_interpretations.items():
print(f'MRR {score:.2f}: {description}')Precision @K
Precision@K misst, welcher Anteil der K abgerufenen Chunks tatsächlich relevant ist. Anders als die Hit Rate, die binär ist, misst Precision@K das Signal-Rausch-Verhältnis Ihrer Retrieval-Ergebnisse. Eine niedrige Precision bedeutet, dass das LLM neben relevanten Chunks irrelevanten Kontext erhält, wodurch das Risiko von Verwirrung oder Prompt Injection steigt. Für RAG ist eine Precision@5 > 0,6 ein guter Zielwert.
def precision_at_k(golden_dataset, retriever, k=5):
precisions = []
for item in golden_dataset:
retrieved = retriever.retrieve(item['question'], top_k=k)
retrieved_ids = [r['id'] for r in retrieved[:k]]
relevant_ids = set(item['relevant_chunk_ids'])
relevant_retrieved = sum(
1 for rid in retrieved_ids if rid in relevant_ids
)
precision = relevant_retrieved / k
precisions.append(precision)
mean_precision = sum(precisions) / len(precisions)
print(f'Precision@{k}: {mean_precision:.3f}')
return mean_precisionDiscounted Cumulative Gain (DCG)
DCG ist eine Metrik zur Bewertung von Ranglisten, die belohnt, wenn mehr relevante Chunks weiter oben stehen. Sie summiert die Relevanzwerte der abgerufenen Chunks und gewichtet sie abhängig von ihrer Position logarithmisch ab: Rang 1 erhält die volle Gewichtung, Rang 2 wird mit log(2) abgewertet und so weiter. Je relevanter die Chunks an den oberen Positionen sind, desto höher ist der DCG. Die normalisierte Variante (NDCG) teilt durch den idealen DCG (das bestmögliche Ranking) und erzeugt so einen Wert zwischen 0 und 1.
import math
def dcg_at_k(relevances, k):
'''relevances[i] = 1 if chunk at rank i+1 is relevant, else 0'''
dcg = 0.0
for i, rel in enumerate(relevances[:k]):
# rank is i+1, discount is log2(rank + 1)
dcg += rel / math.log2(i + 2)
return dcg
def ndcg_at_k(retrieved_ids, relevant_ids, k):
relevances = [1 if rid in relevant_ids else 0
for rid in retrieved_ids[:k]]
actual_dcg = dcg_at_k(relevances, k)
ideal_dcg = dcg_at_k([1] * min(len(relevant_ids), k), k)
return actual_dcg / ideal_dcg if ideal_dcg > 0 else 0.0NDCG für das gesamte Dataset berechnen
NDCG@K ist die Standardmetrik für Retrieval in Suchsystemen. Sie erfasst gleichzeitig Relevanz und Ranking-Position. Ein NDCG@5 von 0,85 bedeutet, dass Ihr Retriever im Durchschnitt 85 % des theoretisch bestmöglichen Rankings erreicht. NDCG unterstützt Fälle mit mehreren relevanten Chunks pro Abfrage, wobei jeder einen Relevanzwert erhält, und bestraft Systeme, die relevante Chunks zwar finden, sie aber zu weit unten platzieren.
def mean_ndcg_at_k(golden_dataset, retriever, k=5):
ndcg_scores = []
for item in golden_dataset:
retrieved = retriever.retrieve(item['question'], top_k=k)
retrieved_ids = [r['id'] for r in retrieved[:k]]
relevant_ids = set(item['relevant_chunk_ids'])
score = ndcg_at_k(retrieved_ids, relevant_ids, k)
ndcg_scores.append(score)
mean = sum(ndcg_scores) / len(ndcg_scores)
print(f'NDCG@{k}: {mean:.4f}')
return mean
# Compute all retrieval metrics together
hit_rate = hit_rate_at_k(golden_dataset, retriever, k=5)
mrr = mean_reciprocal_rank(golden_dataset, retriever, top_k=5)
ndcg = mean_ndcg_at_k(golden_dataset, retriever, k=5)RAGAS für automatisierte Metriken verwenden
Die Bibliothek RAGAS stellt ein produktionsreifes Evaluierungs-Framework für RAG-Systeme bereit. Sie implementiert die Metriken Context Precision, Context Recall, Faithfulness und Antwortrelevanz mithilfe eines LLM-as-Judge-Ansatzes. Übergeben Sie RAGAS Ihre Fragen, Antworten, abgerufenen Kontexte und Ground-Truth-Antworten, und Sie erhalten einen vollständigen Evaluierungsbericht mit Werten für jede Metrik. Dies ist der schnellste Weg, eine umfassende RAG-Evaluierungspipeline einzurichten.
from ragas import evaluate
from ragas.metrics import (
context_precision,
context_recall,
faithfulness,
answer_relevancy
)
from datasets import Dataset
eval_data = Dataset.from_list([
{
'question': item['question'],
'answer': item['generated_answer'],
'contexts': item['retrieved_texts'],
'ground_truth': item['expected_answer']
}
for item in golden_dataset_with_answers
])
results = evaluate(
eval_data,
metrics=[context_precision, context_recall, faithfulness, answer_relevancy]
)
print(results)Metriken nach Abfragekategorie aufschlüsseln
Gesamtdurchschnittswerte verbergen wichtige Muster. Teilen Sie Ihr Golden Dataset in Kategorien auf – das Nachschlagen von Fakten, Vergleiche, prozedurale Anleitungen und Fragen außerhalb des vorgesehenen Anwendungsbereichs – und berechnen Sie die Metriken für jede Kategorie separat. Möglicherweise stellen Sie fest, dass die Hit Rate bei Faktenabfragen 95 %, bei Multi-Hop-Vergleichen jedoch nur 60 % beträgt. Metriken auf Kategorieebene machen die spezifischen Fehlerarten sichtbar, die aggregierte Werte verbergen.
from collections import defaultdict
def evaluate_by_category(golden_dataset, retriever):
by_category = defaultdict(list)
for item in golden_dataset:
category = item.get('category', 'unknown')
retrieved = retriever.retrieve(item['question'], top_k=5)
retrieved_ids = {r['id'] for r in retrieved}
hit = bool(retrieved_ids & set(item['relevant_chunk_ids']))
by_category[category].append(hit)
print('Hit rate by category:')
for cat, hits in sorted(by_category.items()):
hr = sum(hits) / len(hits)
print(f' {cat}: {hr:.1%} ({sum(hits)}/{len(hits)})')Wenn Metriken widersprüchliche Signale liefern
Manchmal liefern Metriken widersprüchliche Signale. Sie verbessern möglicherweise den NDCG (besseres Ranking), während die Hit Rate unverändert bleibt (gleich viele verfehlte Abfragen). Das geschieht, wenn eine Optimierung relevante Chunks von Rang 6 auf Rang 2 verschiebt, ohne zuvor verfehlte Abfragen in die Top 5 zu bringen. Prüfen Sie in solchen Fällen, ob Ihre Optimierung bei den bereits erfolgreichen Abfragen geholfen und die fehlerhaften vernachlässigt hat. Untersuchen Sie neben aggregierten Metriken immer auch einzelne Fehlerbeispiele.
def analyze_failures(golden_dataset, retriever, top_k=5):
failures = []
for item in golden_dataset:
retrieved = retriever.retrieve(item['question'], top_k=top_k)
retrieved_ids = {r['id'] for r in retrieved}
relevant_ids = set(item['relevant_chunk_ids'])
if not (retrieved_ids & relevant_ids):
failures.append({
'question': item['question'],
'expected_chunks': list(relevant_ids),
'retrieved_chunks': [r['id'] for r in retrieved],
'top_score': retrieved[0]['score'] if retrieved else None
})
print(f'Failures: {len(failures)}/{len(golden_dataset)}')
return failuresRecall @K: Vollständigkeit des Retrievals
Recall@K misst, welcher Anteil aller relevanten Chunks in den Top-K-Ergebnissen abgerufen wurde. Wenn eine Frage im Index drei relevante Chunks hat und Ihr Retriever zwei davon in den Top 5 zurückgibt, beträgt Recall@5 2/3 = 0,67. Ein hoher Recall ist wichtig, wenn das LLM mehrere Belegstücke benötigt, um eine vollständige Antwort zu formulieren – schon das Fehlen eines einzigen wichtigen Chunks kann die Antwort unvollständig machen. Stimmen Sie Precision und Recall durch die Wahl von K aufeinander ab: Ein höheres K verbessert den Recall, senkt aber die Precision.
def recall_at_k(golden_dataset, retriever, k=5):
recalls = []
for item in golden_dataset:
retrieved = retriever.retrieve(item['question'], top_k=k)
retrieved_ids = set(r['id'] for r in retrieved[:k])
relevant_ids = set(item['relevant_chunk_ids'])
if not relevant_ids:
continue # skip items with no annotated relevant chunks
retrieved_relevant = retrieved_ids & relevant_ids
recall = len(retrieved_relevant) / len(relevant_ids)
recalls.append(recall)
mean_recall = sum(recalls) / len(recalls)
print(f'Recall@{k}: {mean_recall:.3f}')
return mean_recallSchnelltest
Testen Sie Ihr Verständnis der Konzepte des AI Engineering aus dieser Lektion.
Zusammenfassung der Lektion
In dieser Lektion haben Sie gelernt: Hit Rate@K als Metrik für das binäre Vorhandensein, MRR zur Messung der durchschnittlichen Rangposition des ersten relevanten Chunks, Precision@K für das Signal-Rausch-Verhältnis des Retrievals, NDCG@K als Standardmetrik für Ranglisten und die RAGAS-Bibliothek zur Automatisierung der RAG-Evaluierung mit Context Precision, Recall, Faithfulness und Antwortrelevanz. Als Nächstes gehen wir ausführlicher auf Generierungsmetriken und die Messung von Faithfulness ein.
Lerne Python mit einem KI-Tutor — kostenlos
Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.
- Kurse
- 30
- Lektionen
- 120
Häufig gestellte Fragen
Ist die Lektion „Retrieval-Metriken: Hit Rate, MRR und NDCG“ kostenlos?
Ja — der vollständige Text von „Retrieval-Metriken: Hit Rate, MRR und NDCG“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Engineering Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Engineering Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Retrieval-Metriken: Hit Rate, MRR und NDCG“?
Sie erstellen einen Goldstandard-Datensatz aus Anfragen und relevanten Dokumenten und berechnen anschließend Hit Rate, Mean Reciprocal Rank und NDCG, um zu messen, wie oft Ihr Retriever die richtigen… Du übst AI Engineering Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um AI Engineering Academy zu starten?
Keine Vorkenntnisse erforderlich. AI Engineering Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Retrieval-Metriken: Hit Rate, MRR und NDCG“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser AI Engineering Academy-Lektion Code schreiben und ausführen?
Ja. Jede AI Engineering Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Warum Evaluation bei RAG wichtig ist
- Retrieval-Metriken: Hit Rate, MRR und NDCG
- Generierungsmetriken: Faithfulness und Antwortrelevanz
- Eine automatisierte Evaluationsumgebung erstellen