Note 01 / RAG · Evaluation
RAG bewerten: Retrieval und Antworten getrennt
Recall, Trefferquote und Antwortrichtigkeit messen unterschiedliche Dinge. Ein kleines Beispiel und ein nachvollziehbarer Prüfplan.
Eine plausible Antwort ist noch kein Beleg
Wenn ein RAG-System falsch antwortet, können zwei unterschiedliche Stufen die Ursache sein: Der Retriever findet den relevanten Text nicht, oder der Generator verwendet vorhandenen Text falsch. Ein einziger Gesamtscore verdeckt diesen Unterschied. Prüfen Sie zuerst die gefundenen Quellen und danach die Antwort.
Ein Eval-Fall enthält eine Frage, eine Menge relevanter Dokument- oder Passage-IDs und Kriterien für eine zulässige Antwort. Granularität und ID-Version müssen stabil sein. Ein geändertes Chunking kann sonst wie eine Regression aussehen, obwohl sich nur die Bewertungsreferenz geändert hat.
Recall und Trefferquote nicht verwechseln
Recall@k ist der Anteil relevanter Elemente, die unter den ersten k eindeutigen Treffern erscheinen. Hit rate@k sagt nur, ob mindestens ein relevantes Element dabei ist. Der Reciprocal Rank betrachtet die Position des ersten relevanten Treffers. Bei mehreren relevanten Dokumenten kann die Trefferquote gut aussehen und der Recall dennoch niedrig sein.
def retrieval_metrics(expected, ranked, k):
if not expected or k < 1:
raise ValueError("non-empty expected set and positive k required")
# Dokument-IDs vor der Auswertung deduplizieren.
top = list(dict.fromkeys(ranked))[:k]
hits = len(set(top) & expected)
first = next((rank for rank, doc in enumerate(top, 1)
if doc in expected), None)
return {
"recall": hits / len(expected),
"hit_rate": float(hits > 0),
"reciprocal_rank": 1 / first if first else 0.0,
}
# Synthetischer Funktionstest, kein Produktionsbenchmark.
expected = {"doc-a", "doc-b"}
ranked = ["doc-x", "doc-a", "doc-a", "doc-b"]
result = retrieval_metrics(expected, ranked, k=2)
assert result == {"recall": 0.5, "hit_rate": 1.0,
"reciprocal_rank": 0.5}
Die Zahlen im assert sind erwartete Ergebnisse einer synthetischen Fixture. Sie beschreiben keine Qualität eines ausgelieferten RAG-Systems. Für einen Datensatz werden die Werte pro beantwortbarer Frage berechnet und anschließend gemittelt; so entstehen unter anderem der mittlere Recall und der Mean Reciprocal Rank.
Antwortprüfung und Regression
Fragen ohne belegbare Antwort gehören in ein separates Set. Ein leerer Relevanzsatz ist kein Recall von null, sondern ein anderer Testfall: Erkennt das System die fehlende Grundlage? Prüfen Sie bei beantwortbaren Fragen zusätzlich, ob jede wesentliche Aussage durch die zitierte Passage gestützt wird und ob die Frage tatsächlich beantwortet ist.
Versionieren Sie Fragen, Korpusstand, Embedding-Modell, Chunking und Generator-Konfiguration zusammen mit den Ergebnissen. Definieren Sie die Freigabekriterien vor dem Vergleich. Der lokale Python-Test dieser Note prüft Mehrfachtreffer, fehlende Treffer und ungültige Eingaben; er startet kein LLM und liefert keinen Produktionsbenchmark.
Grenzen des Testsets
Ein kleines Set kann seltene Fehler nicht zuverlässig abdecken. Ergänzen Sie fehlgeschlagene Fälle, halten Sie einen separaten Prüfbestand zurück und lesen Sie auch unveränderte Antworten stichprobenartig. Ein LLM als Bewertungsinstanz braucht Kalibrierung und menschliche Gegenprüfung. Für Latenzwerte dokumentieren Sie Hardware, Last, Eingabelängen, Messgrenzen und Wiederholungen; diese Note veröffentlicht keine solchen Messwerte.