Anleitungen
RAG-Evaluation
Die englische Fassung dieser Seite hat sich seit der Übersetzung geändert. Die englische Seite ist die aktuelle. Auf Englisch lesen
Eine durch Retrieval gestützte Antwort kann aus vier verschiedenen Gründen falsch sein: Die richtige Passage wurde nie abgerufen, sie wurde abgerufen und zu niedrig eingestuft, sie wurde hoch genug eingestuft und dann aus dem Kontext entfernt, oder sie hat das Modell erreicht, und das Modell hat trotzdem falsch geantwortet. Eine einzelne Accuracy-Zahl kann diese Fälle nicht auseinanderhalten. Oloproof führt ein RAG-System als zwei Stufen aus, die es einsehen kann, misst jede davon und führt fehlgeschlagene Fälle unter kontrollierten Änderungen erneut aus, um herauszufinden, welcher Grund zutrifft.
examples/support_rag/ ist das Projekt, das diese Seite ausführt. Es benötigt keine Provider-Zugangsdaten.
Ein gestuftes System
Das System ist eine Klasse mit einer Retrieval-Stufe und einer Generierungsstufe, dekoriert mit @rag_system:
from oloproof import Passage, Retrieval, rag_system
@rag_system(
name="support-rag",
version="slice-b-example",
depth=6,
top_k=2,
token_budget=40,
index_version="kb-2026-09-16",
)
class SupportRag:
def retrieve(self, input, depth):
...
return Retrieval(query=input["question"], depth=depth, candidates=tuple(passages))
def generate(self, input, context):
...
return {"answer": answer, "citations": [best.doc_id]}
def count_tokens(self, passage):
return len((passage.text or "").split())retrieve(input, depth) liefert bis zu depth Kandidaten als Passage(doc_id=..., score=..., text=...), in der Reihenfolge, in der Ihr Retriever sie erzeugt hat. Oloproof zeichnet die Positionen auf und ordnet niemals neu. Anschließend behält es die ersten top_k, entfernt Passagen jenseits von token_budget und übergibt den Rest an generate(input, context). count_tokens(passage) wird nur mit einem token_budget benötigt; Oloproof schätzt niemals Tokens.
oloproof.yaml verweist auf die Klasse und kann jede ihrer Einstellungen überschreiben:
system:
name: support-rag
version: slice-b-example
rag:
object: app:SupportRag
depth: 6
top_k: 2
token_budget: 40
index_version: kb-2026-09-16index_version ist Teil der Identität des Retrievals. Ändern Sie den Wert, wenn sich der Index ändert, sonst werden gecachte Retrievals gegen einen Index wiederverwendet, der sie nicht mehr liefert.
Was ein Fall deklariert
Ein RAG-Fall trägt unter expected zwei Felder, die keine andere Art von Fall benötigt:
{"id":"refund_annual","input":{"question":"How long do refunds take for annual plans?"},"expected":{"answer":"14 days","relevant":[{"doc_id":"kb-01"}],"gold_context":[{"doc_id":"kb-01","text":"Refunds for annual plans are issued within 14 days of an approved request. Support reviews each request on the same business day."}]},"metadata":{"topic":"billing"}}- expected.relevant listet die Dokumente auf, die die Frage beantworten. Die Retrieval-Metriken lesen
es, und ein Fall ohne dieses Feld wird mit no_relevance_labels von ihnen ausgeschlossen.
- expected.gold_context ist der Passagentext selbst. Die Diagnose setzt ihn anstelle des abgerufenen
Kontexts ein, und ein fehlgeschlagener Fall ohne dieses Feld kann nicht diagnostiziert werden.
Die Evaluatoren
evaluators:
- {type: contains, criterion: answer_correct, field: answer, expected_field: answer}
- {type: hit_rate, k: 2}
- {type: recall, k: 2}
- {type: ndcg, k: 6}
- {type: citation_validity}
slices: [metadata.topic, relevant_position, context_truncated]
min_slice_support: 4hit_rate, recall, mrr und ndcg nehmen k und benennen daraus ihr eigenes Kriterium: hit_rate_at_2. Ein Eintrag in expected.relevant kann außerdem eine chunk_id und einen grade tragen, der standardmäßig 1 ist; relevance_unit: chunk zählt dann jeden Chunk als eigene Einheit statt ganzer Dokumente. citation_validity prüft, dass jede ID, die eine Antwort zitiert, eine Passage in dem Kontext benennt, den sie erhalten hat, und mit require_citations: true scheitert eine Antwort, die nichts zitiert. groundedness_judge und citation_support_judge sind LLM-Judges, die den zusammengestellten Kontext lesen, und nehmen wie jeder andere Judge einen provider und ein model.
oloproof runDrei Zeilen der Metriktabelle:
│ answer_correct │ 69.2% │ [38.5%, 91.0%] │ 9 / 13 observed · 0 missing · 0 excluded │
│ ndcg_at_6 │ 0.866 │ [0.506, 0.990] │ mean of 13 observed · 0 missing · 0 excluded │
│ citations_valid │ 100.0% │ [75.2%, 100.0%] │ 13 / 13 observed · 0 missing · 0 excluded │Dazwischen stehen hit_rate_at_2 und recall_at_2 beide bei 92,3 %, 12 von 13 beobachtet, mit einer unteren Schranke von 63,9 %: Die relevante Passage einer Frage wurde nie abgerufen.
Cache: execution 0 hit/13 miss; judgment 0 hit/65 miss
Stages: retrieve 0 hit/13 miss; generate 0 hit/13 missDie Zeile Stages ist der eigene Cache des gestuften Systems. Retrieval und Generierung werden getrennt gecacht, sodass eine Änderung an der Generierung niemals das Retrieval erneut ausführt.
Herausfinden, warum
Vier Fragen sind gescheitert. diagnose führt sie mit der Gold-Passage anstelle des abgerufenen Kontexts erneut aus, neben einer Kontrolle, die sie unverändert erneut ausführt:
oloproof diagnose RUN_ID --intervention gold-context --criterion answer_correctSelected: 4 failed cases with gold context (observed; no population claim)
Control: 0 of 4 passed when re-executed without the intervention
Recovered under gold context: 3 of 4
RETRIEVAL_MISS: 1 of 4, recovered; no relevant evidence was retrieved
CONTEXT_ASSEMBLY_LOSS: 2 of 4, recovered; relevant evidence within top-k was left out of the context
GENERATION_FAILURE: 1 of 4, still failed with the gold context
Implicated: context budget, in 2 of the 3 recovered failures.
Candidate experiment: a larger token budget. This is a hypothesis to test, not an established cause.
Candidate experiment: smaller chunks. This is a hypothesis to test, not an established cause.
Diagnosis sha256:b2846cbe04099225bda4bf21beb1738f54d6cc0e9a7ce210bb3eb467619cbd69
Child runs: gold context run_01M3C3REAAZDF9FD8N2C8BG17P, control run_01M3C3REAFVXK2VM4MYAQYH6KE
Cases: oloproof inspect sha256:b2846cbe04099225bda4bf21beb1738f54d6cc0e9a7ce210bb3eb467619cbd69Ein Fall, der mit der Gold-Passage besteht und ohne sie scheitert, ist vor dem Modell gescheitert. Ein Fall, der mit der Gold-Passage in der Hand scheitert, geht auf das Modell zurück. Die Kontrolle macht diese Lesart sicher: Ein Fall, der sich bei einer einfachen Wiederholung erholt, war instabil, nicht diagnostiziert.
Die Diagnose-ID listet den Fall hinter jeder Zählung auf:
oloproof inspect DIAGNOSIS_IDmoney_back: RETRIEVAL_MISS, relevant_not_retrieved, strength intervention_recovery, best relevant position none
refund_review: CONTEXT_ASSEMBLY_LOSS, relevant_dropped_from_context, strength intervention_recovery, best relevant position 2
seat_count: GENERATION_FAILURE, fails_with_gold_context, strength intervention_non_recovery, best relevant position 1
security_review: CONTEXT_ASSEMBLY_LOSS, relevant_dropped_from_context, strength intervention_recovery, best relevant position 2Sie benennt einen Faktor, niemals eine Ursache. „Implicated“ und „candidate experiment“ sind die stärksten Worte, die sie verwendet, denn vier Fälle, die sich unter einer Intervention erholen, belegen nicht, warum sie gescheitert sind.
Eine Korrektur testen, bevor man sie vornimmt
Zwei weitere Interventionen spielen das aufgezeichnete Retrieval mit einer anderen Einstellung erneut ab, sodass kein Aufruf des Retrievers erfolgt. top-k erweitert den Schnitt:
oloproof diagnose RUN_ID --intervention top-k --top-k 4 --criterion answer_correctSelected: 4 failed cases with gold context (observed; no population claim)
Control: 0 of 4 passed when re-executed without the intervention
Recovered under top-k 4: 0 of 4
Confirmed under top-k 4: 0 of 0 RANKED_OUT cases also recovered
Labels from gold context (diagnosis sha256:b2846cbe04099225bda4bf21beb1738f54d6cc0e9a7ce210bb3eb467619cbd69): 3 of 4 recovered
RETRIEVAL_MISS: 1 of 4, recovered; no relevant evidence was retrieved
CONTEXT_ASSEMBLY_LOSS: 2 of 4, recovered; relevant evidence within top-k was left out of the context
GENERATION_FAILURE: 1 of 4, still failed with the gold context
Diagnosis sha256:668084c3e99df84f7b63f138792aa96f48e5cb8251fee3acae8e1cc0500ba085
Child runs: gold context run_01M3C3REAAZDF9FD8N2C8BG17P, control run_01M3C3REAFVXK2VM4MYAQYH6KE, top-k 4 run_01M3C3RKHTGGV37079V11JJ78M, replay control run_01M3C3RKJ076K7MSVQ94J4ZE2P
Cases: oloproof inspect sha256:668084c3e99df84f7b63f138792aa96f48e5cb8251fee3acae8e1cc0500ba085Nichts hat sich erholt, und genau das haben die Labels vorhergesagt: Kein Fehlschlag hier war eine Passage, die knapp unterhalb des Schnitts eingestuft war. Die Wiederholung übernimmt die Gold-Context-Labels, sodass sich die beiden Diagnosen zusammen lesen lassen. reranker nimmt --reranker mit einer module:function und spielt das Retrieval stattdessen über Ihren Reranker erneut ab.
Das Experiment ausführen
Die Diagnose nannte ein größeres Token-Budget. Erhöhen Sie token_budget auf 120 und führen Sie erneut aus:
Cache: execution 0 hit/13 miss; judgment 0 hit/65 miss
Stages: retrieve 13 hit/0 miss; generate 7 hit/6 missJedes Retrieval wurde wiederverwendet, weil top_k und das Token-Budget außerhalb der Identität des Retrievals liegen; nur die sechs Fälle, deren Kontext sich geändert hat, wurden neu generiert. Vergleichen Sie dann mit der Vergleichs-Policy des Beispiels:
oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy compare.yamlComparison sha256:d801ed897f1fa1b196ca1e3f73a1ef4ffe6845d6ee8bddaea8a44da94d27a75b of run_01M3C3RYJZ4PAJ8P4P9NT71360 against run_01M3C3R5Y9D18WGSZQFA7N4XRT · 13 paired cases
answer_correct: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excluded
hit_rate_at_2: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excluded
recall_at_2: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excluded
ndcg_at_6: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excluded
citations_valid: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excludedFür jeden Slice und jede Metrik folgt eine explorative Zeile, danach die Entscheidungen:
Decisions
answers-not-worse answer_correct non-inferiority, margin 5.0 points INSUFFICIENT_EVIDENCE interval_overlaps_margin
citations-not-worse citations_valid non-inferiority, margin 2.0 points INSUFFICIENT_EVIDENCE interval_overlaps_margin
Gate: BLOCK (exit 3)Das Experiment hat nicht geholfen: Keiner der dreizehn hat sein Urteil geändert. Und dreizehn gepaarte Fälle hätten keine Änderung einer Größe belegen können, die für ein Release relevant ist, was das andere ist, was das Intervall aussagt.
Wie es weitergeht
- Slices behandelt relevant_position und context_truncated.
- Vergleichsregeln behandelt die Regeln, nach denen der letzte Schritt entschieden wurde.
- Judges behandelt, was ein Groundedness-Judge erfüllen muss, bevor er gaten darf.