Zum Inhalt springen

Anleitungen

Tutorial: eine RAG-Anwendung evaluieren

Ein ausführbarer Durchgang für eine Retrieval-gestützte Anwendung, auf zwei Wegen: eine bestehende Blackbox-Anwendung, deren Retrieval, Kontext und Zitate Sie von außen erfassen, und eine gestufte Anwendung, die Oloproof Stufe für Stufe ausführt, damit oloproof diagnose fehlgeschlagene Fälle unter kontrollierten Änderungen erneut ausführen kann. Beide laufen lokal ohne Provider-Zugangsdaten.

Die Konzepte hinter jedem Schritt (Stufen, Relevanz-Labels, Gold-Kontext, die vier Fehler-Labels) stehen auf der Seite RAG-Evaluation; die Begriffe Fall, Evaluator, Metrik, Intervall und Gate stehen in Kernkonzepte. Diese Seite ist der praktische Weg durch sie hindurch.

Welcher Weg der Ihre ist

Ihre AnwendungWegWas Sie erhaltenWas Sie nicht erhalten
Ein Aufruf hinein, eine Antwort heraus (ein Dienst, ein HTTP-Endpunkt, eine Framework-Kette, die Sie nicht aufteilen wollen)A, BlackboxRetrieval-Metriken, Zitatprüfungen, Grounding-Judges, Gating, VergleichKontrollierte Interventionen: diagnose führt nichts erneut aus
Retrieval und Generierung, die Sie getrennt aufrufen könnenB, gestuftAlles aus A, Caching pro Stufe und diagnose mit Gold-Kontext, Top-k und einem Reranker neben einer KontrolleAndere Interventionen als diese drei

Beginnen Sie mit A, wenn Sie unsicher sind. Es erfordert keine Änderung an der Anwendung, und ein späterer Wechsel zu B behält Datensatz, Evaluatoren und Policy bei.

Voraussetzungen

  • Python 3.11 oder neuer und installiertes Oloproof (pip install oloproof).
  • Die Beispielprojekte, die mit dem Paket ausgeliefert werden: blackbox_rag für Weg A und support_rag für Weg B. Kopieren Sie eines in ein neues Verzeichnis und arbeiten Sie dort:
oloproof init --example blackbox_rag my-rag
cd my-rag

Jeder Befehl unten läuft im kopierten Verzeichnis. Läufe, Urteile und Diagnosen werden dort in .oloproof/ gespeichert.

Weg A: eine bestehende Anwendung als Blackbox

Die Dateien

DateiWas sie ist
app.pysupport_api(question), stellvertretend für Ihre Anwendung, und run(case), der Adapter
server.pyDieselbe Anwendung über HTTP, für die HTTP-Variante unten
data/corpus.jsonlDie Wissensbasis mit 14 Passagen, die die Anwendung durchsucht
data/support.jsonl15 Fälle: 13 mit Relevanz-Labels und Gold-Passagen, 2 ohne beides
oloproof.yamlDie Suite: Datensatz, System, Evaluatoren, Slices
oloproof.http.yamlDieselbe Suite gegen den HTTP-Server
release.yamlDie Release-Policy für einen einzelnen Lauf
compare.yamlDie Policy für den Vergleich eines Kandidatenlaufs mit einer Baseline

Was die Anwendung zurückgibt

support_api verhält sich wie eine Anwendung, die Sie bereits haben: Sie sucht, baut aus den besten Quellen, die in ein Wortbudget passen, einen Prompt, antwortet und zitiert. Ihre Antwort enthält bereits, was sie getan hat:

{
  "answer": "Team plans include five seats.",
  "cited": ["kb-03"],
  "sources": [{"id": "kb-03", "score": 3.0, "text": "Team plans include five seats. ..."}],
  "prompt_sources": [{"id": "kb-03", "score": 3.0, "text": "...", "rank": 1, "tokens": 17}],
  "skipped": [{"id": "kb-05", "rank": 3, "why": "top_k"}]
}

Die Feldnamen Ihrer Anwendung werden andere sein. Entscheidend ist, dass sie Ihnen pro Frage sagen kann, welche Quellen sie in welcher Rangfolge abgerufen hat, welche das Modell erreicht haben und welche sie zitiert hat. Kann sie das nicht, ergänzen Sie dies zuerst in ihrer Antwort oder ihren Logs: Oloproof misst, was erfasst ist, und leitet Retrieval nie aus einer Antwort ab.

Der Adapter

run ruft die Anwendung unverändert auf und bildet die Antwort auf drei typisierte Artefakte ab, die Datensätze, die die Retrieval- und Zitat-Evaluatoren lesen:

@system(
    name="support-rag-blackbox",
    version="tutorial",
    records=("retrieval/v1", "context/v1", "citations/v1"),
)
def run(case):
    response = support_api(str(case["question"]))
    recorder = current_case()
    recorder.retrieval(
        Retrieval(
            query=case["question"],
            depth=SEARCH_DEPTH,
            candidates=tuple(
                Passage(doc_id=s["id"], score=s["score"], text=s["text"])
                for s in response["sources"]
            ),
        )
    )
    recorder.context(
        Context(
            items=tuple(
                ContextItem(doc_id=i["id"], position=i["rank"], tokens=i["tokens"], text=i["text"])
                for i in response["prompt_sources"]
            ),
            dropped=tuple(
                DroppedItem(doc_id=i["id"], position=i["rank"], reason=i["why"])
                for i in response["skipped"]
            ),
            token_budget=PROMPT_WORD_BUDGET,
        )
    )
    recorder.citations(response["cited"])
    return {"answer": response["answer"], "citations": response["cited"]}
ArtefaktFormGelesen von
retrieval/v1query, depth und candidates in der Reihenfolge, in der Ihr Retriever sie geliefert hat, jeweils ein Passage(doc_id, chunk_id, score, text)hit_rate, recall, mrr, ndcg
context/v1items, die das Modell erreicht haben (doc_id, position, tokens, text), dropped-Einträge mit einem reason von top_k oder token_budget, und token_budgetcitation_validity, groundedness_judge, citation_support_judge
citations/v1ids, jeweils eine doc_id oder doc_id#chunk_idcitation_validity, citation_support_judge

Oloproof erfasst Positionen wie angegeben und sortiert nie neu. Ein fehlerhaftes Artefakt stoppt den Lauf mit Exit-Code 2, statt gespeichert zu werden. case ist das input-Objekt des Falls, also ist case["question"] die Frage aus dem Datensatz.

Um Ihre eigene Anwendung zu verwenden, ersetzen Sie den Rumpf von support_api durch einen Aufruf an sie (einen SDK-Aufruf, eine HTTP-Anfrage) und behalten Sie run. Richten Sie system.callable in oloproof.yaml als module:function darauf.

Die HTTP-Variante

Ein HTTP-System kann den Recorder nicht aufrufen, also trägt seine Antwort die Evidenz, bereits in den drei Formen oben, und die Konfiguration nennt, wo:

system:
  name: support-rag-http
  version: tutorial
  http:
    url: http://127.0.0.1:8766/answer
    output_path: result
    artifacts:
      retrieval/v1: evidence.retrieval
      context/v1: evidence.context
      citations/v1: evidence.citations

server.py liefert genau das. Starten Sie ihn und führen Sie dann dagegen aus:

python server.py 8766
oloproof run --config oloproof.http.yaml

Die Eingabe des Falls wird als JSON-Body gesendet. output_path wählt die Ausgabe aus der Antwort, und jeder artifacts-Eintrag erfasst einen Pfad mit Punkten als diese Art; ein fehlendes oder fehlerhaftes Feld stoppt den Lauf mit Exit-Code 2. Die Ergebnisse sind identisch mit dem Callable-Weg unten. In Ihrem eigenen Dienst ist das Evidenz-Objekt meist ein Debug-Feld, das Sie für Evaluations-Traffic aktivieren.

Was ein Fall deklariert

{"id":"seat_count","input":{"question":"How many seats does a team plan include?"},"expected":{"answer":"5 seats","relevant":[{"doc_id":"kb-03"}],"gold_context":[{"doc_id":"kb-03","text":"Team plans include five seats. ..."}]},"metadata":{"topic":"billing"}}
{"id":"office_hours","input":{"question":"What are the support office hours?"},"expected":{"answer":"09:00"},"metadata":{"topic":"account"}}
  • expected.relevant listet die Passagen, die die Frage beantworten. Retrieval-Metriken lesen es. Ein Fall ohne diese Angabe, wie office_hours, wird mit no_relevance_labels von ihnen ausgeschlossen: Er verlässt den Nenner, statt als Bestehen oder Fehlschlag zu zählen.
  • expected.gold_context ist der Passagentext selbst. Weg A nutzt ihn nie; Weg B setzt ihn während der Diagnose an die Stelle des abgerufenen Kontexts.

Ungelabelte Fälle sind in der Praxis normal, da das Labeln von Relevanz Arbeit kostet. Für die Antwort- und Zitatprüfungen zählen sie trotzdem.

Evaluatoren wählen

evaluators:
  - {type: contains, criterion: answer_correct, field: answer, expected_field: answer}
  - {type: hit_rate, k: 2}
  - {type: recall, k: 2}
  - {type: citation_validity, require_citations: true}
slices: [metadata.topic]
min_slice_support: 4
  • contains prüft, ob die Antwort den erwarteten Text enthält. Das ist die Aufgabenprüfung: Hat der Nutzer die richtige Antwort bekommen. Verwenden Sie stattdessen einen exakten oder Rubrik-Judge, wenn der Wortlaut variiert.
  • hit_rate und recall bei k: 2 messen das Retrieval in der Tiefe, die die Anwendung tatsächlich in den Prompt legt. Eine Retrieval-Metrik in einer Tiefe, die das Modell nie sieht, beschreibt den Index, nicht die Anwendung.
  • citation_validity prüft, ob jede zitierte ID eine Passage nennt, die das Modell erreicht hat; require_citations: true lässt zudem eine Antwort fehlschlagen, die nichts zitiert.
  • groundedness_judge und citation_support_judge (optional) fragen ein Modell, ob die Antwort durch den Kontext gestützt ist. Sie brauchen einen Provider, ein Modell und Zugangsdaten in einer Umgebungsvariable und kosten Geld pro Fall; siehe Judges dazu, was ein Judge erfüllen muss, bevor er gaten darf.

Die Slices relevant_position und context_truncated sind hier nicht verfügbar: Sie vergleichen Positionen mit dem Top-k der Anwendung, das nur ein gestuftes System deklariert. Werden sie angefordert, stoppt der Lauf mit slice 'relevant_position' compares relevant positions with top_k, so it needs a staged system.

Die Release-Policy

version: 1
confidence_level: 0.95
block_on: [FAIL, INSUFFICIENT_EVIDENCE, MANUAL_REVIEW]
rules:
  - id: answer-floor
    metric: answer_correct
    min: 0.70
  - id: retrieval-floor
    metric: hit_rate_at_2
    min: 0.80
  - id: citations-valid
    metric: citations_valid
    kind: observed_count
    max_failures: 0

Eine min-Regel besteht nur, wenn das ganze Intervall die Untergrenze überschreitet, schlägt fehl, wenn das ganze Intervall darunter liegt, und ist sonst INSUFFICIENT_EVIDENCE. Eine observed_count-Regel entscheidet auf den tatsächlich ausgeführten Fällen, ohne Intervall: "kein ungültiges Zitat in dieser Suite". Siehe Gating in der CI.

Ausführen

oloproof run
Run run_01M4FCBPE0G550CKCVGXCNEM2P [DECIDED/COMPLETE]
Gate: BLOCK (exit 1)
│ answer-floor    │ answer_correct  │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold    │
│ retrieval-floor │ hit_rate_at_2   │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold    │
│ citations-valid │ citations_valid │ FAIL                  │ observed_failures_exceed_limit │

│ answer_correct  │ 73.3%    │ [44.8%, 92.3%] │ 11 / 15 observed · 0 missing · 0 excluded │
│ hit_rate_at_2   │ 92.3%    │ [63.9%, 99.9%] │ 12 / 13 observed · 0 missing · 2 excluded │
│ recall_at_2     │ 92.3%    │ [63.9%, 99.9%] │ 12 / 13 observed · 0 missing · 2 excluded │
│ citations_valid │ 93.3%    │ [68.0%, 99.9%] │ 14 / 15 observed · 0 missing · 0 excluded │
Cache: execution 0 hit/15 miss; judgment 0 hit/56 miss

So lesen Sie das:

  • Gate: BLOCK (exit 1): Eine Regel ist mit FAIL ausgegangen. Exit 1 bedeutet ein FAIL; Exit 3 bedeutet, dass das Gate ohne FAIL blockiert hat (hier wäre es INSUFFICIENT_EVIDENCE); Exit 0 bedeutet nichts, worauf die Policy blockiert. [DECIDED/COMPLETE] ist der Ausführungszustand: Jeder Fall lief.
  • citations-valid ist FAIL: Eine Antwort hat nichts zitiert, und require_citations zählt das als ungültig.
  • answer-floor ist INSUFFICIENT_EVIDENCE, nicht PASS, obwohl 73,3% über 70% liegen: Mit 15 Fällen reicht das Intervall bis 44,8% hinunter, also kann die Evidenz nicht zeigen, dass die Untergrenze erfüllt ist.
  • hit_rate_at_2 zeigt 2 excluded: die zwei ungelabelten Fälle. Sein Nenner ist 13, nicht 15.
  • Die darauf folgende Tabelle Slices ist explorativ und wird nie gegatet; ein Slice unter min_slice_support zeigt kein Intervall.

Die Fehlschläge untersuchen

Die Lauf-ID steht in der ersten Zeile der Ausgabe des Laufs.

oloproof inspect RUN_ID --failures
4 of 15 cases failed, errored or did not finish

refund_review
  output: {"answer": "Every refund request on an annual plan is logged in the audit trail, and the same request is listed again on the day it was reviewed and approved."…
  answer_correct: failed

money_back
  output: {"answer": "I could not find that in the knowledge base.", "citations": []}
  answer_correct: failed
  hit_rate_at_2: failed
  recall_at_2: failed
  citations_valid: failed

security_review
  output: {"answer": "Security reviews during Enterprise onboarding include an access review and a written summary for the customer, and every review is scheduled with t…
  answer_correct: failed

seat_count
  output: {"answer": "Team plans include five seats.", "citations": ["kb-03"]}
  answer_correct: failed

oloproof inspect RUN_ID --case refund_review gibt Eingabe, erwartete Werte, Ausgabe und jedes Urteil eines Falls aus. Die erfassten Artefakte stehen im exportierten Bundle:

oloproof export RUN_ID

Jede Zeile von .oloproof/bundles/RUN_ID/cases.jsonl ist der Datensatz eines Falls; sein Feld artifacts enthält, was erfasst wurde. Für money_back lautet dieses Feld:

{"retrieval/v1": [{"candidates": [], "depth": 6, "query": "Where do I claim money back on a yearly subscription?"}], "context/v1": [{"dropped": [], "items": [], "source": "retrieval", "token_budget": 40}], "citations/v1": [{"ids": []}]}

Die vier Fehlschläge allein aus der erfassten Evidenz gelesen:

FallWas der Datensatz zeigtEin sinnvoller nächster Schritt
money_backDas Retrieval hat nichts geliefert: Die Frage teilt kein Wort mit der ErstattungspassageQuery-Umformulierung oder Synonyme, gemessen mit hit_rate_at_2
refund_review, security_reviewhit_rate_at_2 hat bestanden, doch die Antwort stammt aus einer anderen Passagecontext/v1 untersuchen: Wurde die relevante Passage wegen des Budgets verworfen?
seat_countDie richtige Passage wurde abgerufen, behalten und zitiert; die Antwort sagt "five", der Fall erwartet "5"Die Erwartung oder das Antwortformat korrigieren, nicht das Retrieval

Diese Tabelle ist Ihre Lesart des Datensatzes. Sie ist eine Assoziation zwischen einem Fehlschlag und einer Stufe, keine nachgewiesene Ursache: Nichts hat den Fall mit geänderter Stufe erneut ausgeführt.

Was diagnose bei einer Blackbox tut

oloproof diagnose RUN_ID --intervention gold-context --criterion answer_correct
Selected: 4 failed cases with gold context (observed; no population claim)
UNRESOLVED: 4 of 4, the system is not staged, so no case was re-executed
Diagnosis sha256:8809e100ab2ec1dad8ffeacc136cd510300081a0edf01ec11f881c543ed104bc
Cases: oloproof inspect sha256:8809e100ab2ec1dad8ffeacc136cd510300081a0edf01ec11f881c543ed104bc

Jeder Fall ist UNRESOLVED mit dem Grund intervention_unsupported. Oloproof kann einer Blackbox die Gold-Passage nicht anstelle ihres eigenen Retrievals übergeben, also tut es auch nicht so. Kontrollierte Interventionen brauchen Weg B.

Eine Kandidatenänderung vornehmen und vergleichen

Der Datensatz sagt, dass money_back beim Retrieval gescheitert ist. Die Kandidatenänderung erweitert die Frage vor der Suche um Synonyme. In app.py:

EXPAND_QUERY = True

Eine Codeänderung ändert die für den Lauf erfasste Systemversion. Führen Sie erneut aus und vergleichen Sie dann den Kandidaten mit der Baseline:

oloproof run
oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy compare.yaml

Der Kandidatenlauf allein: citations-valid ist jetzt PASS, hit_rate_at_2 zeigt 100.0% [75.2%, 100.0%], und das Gate blockiert weiterhin mit Exit 3, weil answer-floor und retrieval-floor INSUFFICIENT_EVIDENCE bleiben. Der Vergleich:

Comparison sha256:2feb024c… of run_01M4FCCJYCVVYA8NB4XZDV6YMB against run_01M4FCCHVBG9WHDP7G5HFX7RDT · 15 paired cases
answer_correct: +6.7 points [-26.5, +40.8] · 15 paired · 0 missing · 0 excluded
hit_rate_at_2: +7.7 points [-29.8, +45.5] · 13 paired · 0 missing · 2 excluded
  excluded 2: no_relevance_labels
recall_at_2: +7.7 points [-29.8, +45.5] · 13 paired · 0 missing · 2 excluded
  excluded 2: no_relevance_labels
citations_valid: +6.7 points [-26.5, +40.8] · 15 paired · 0 missing · 0 excluded
20 exploratory slice differences not shown; add --slices to list them
Decisions
  answers-not-worse  answer_correct  non-inferiority, margin 5.0 points  INSUFFICIENT_EVIDENCE  interval_overlaps_margin
    about 38 more paired cases would decide it, if the difference holds (53 in total at 7% discordance)
  citations-not-worse  citations_valid  non-inferiority, margin 2.0 points  INSUFFICIENT_EVIDENCE  interval_overlaps_margin
    about 68 more paired cases would decide it, if the difference holds (83 in total at 7% discordance)
Gate: BLOCK (exit 3)

Die Änderung hat den Fall behoben, auf den sie zielte (eine Antwort mehr, +6,7 Punkte über 15 gepaarte Fälle). Der Vergleich kann trotzdem nicht belegen, dass der Kandidat nicht um mehr als die Marge schlechter ist als die Baseline: 15 gepaarte Fälle lassen ein Intervall von etwa 67 Punkten Breite. Die Planungszeile sagt, wie viele weitere gepaarte Fälle die Entscheidung bringen würden, wenn der Unterschied Bestand hätte. Eine größere Suite, nicht eine andere Marge, ist der nächste Schritt. Siehe Einen Kandidaten mit einer Baseline vergleichen und Vergleichsregeln.

Weg B: eine gestufte Anwendung mit Diagnose

Die gestuften Dateien

Weg B führt das Beispiel support_rag aus, beschrieben auf der Seite RAG-Evaluation. Kopieren Sie es:

oloproof init --example support_rag my-staged-rag
cd my-staged-rag
DateiWas sie ist
app.pySupportRag, eine mit @rag_system dekorierte Klasse: retrieve(input, depth), generate(input, context), count_tokens(passage)
data/corpus.jsonl, data/support.jsonlDie Wissensbasis und 13 Fälle, jeweils mit relevant und gold_context
oloproof.yamlsystem.rag zeigt auf die Klasse und setzt depth, top_k, token_budget, index_version
release.yaml, compare.yamlDieselben Policies wie bei Weg A

Der Unterschied zu Weg A ist, wer den Kontext zusammenstellt. Hier ruft Oloproof retrieve auf, behält die ersten top_k Kandidaten, verwirft Passagen jenseits von token_budget und übergibt den Rest an generate. Weil es die Stufen getrennt hält, kann es sie getrennt cachen und die Generierung mit einem anderen Kontext erneut ausführen. Um Ihre eigene Anwendung anzupassen, ersetzen Sie die Rümpfe von retrieve (Ihren Index aufrufen, Retrieval(candidates=[Passage(...)]) in der Reihenfolge Ihres Retrievers zurückgeben) und generate (Ihr Modell mit den übergebenen Passagen aufrufen). Setzen Sie index_version auf etwas, das sich ändert, wenn sich Ihr Index ändert: Es ist Teil der Identität des Retrievals, und ein veralteter Wert verwendet gecachte Retrievals gegen einen Index wieder, der sie nicht mehr liefert.

Dieselbe Konfiguration erlaubt auch die Slices relevant_position und context_truncated sowie einen ndcg-Evaluator über die volle Retrieval-Tiefe.

Die gestufte Suite ausführen

oloproof run
Gate: BLOCK (exit 3)
│ answer-floor    │ answer_correct  │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold    │
│ retrieval-floor │ hit_rate_at_2   │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold    │
│ citations-valid │ citations_valid │ PASS                  │ observed_failures_within_limit │
│ answer_correct  │ 69.2%    │ [38.5%, 91.0%]  │ 9 / 13 observed · 0 missing · 0 excluded     │
│ hit_rate_at_2   │ 92.3%    │ [63.9%, 99.9%]  │ 12 / 13 observed · 0 missing · 0 excluded    │
│ recall_at_2     │ 92.3%    │ [63.9%, 99.9%]  │ 12 / 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    │
Cache: execution 0 hit/13 miss; judgment 0 hit/65 miss
Stages: retrieve 0 hit/13 miss; generate 0 hit/13 miss

Die Zeile Stages ist der eigene Cache des gestuften Systems. Exit 3: Nichts ist mit FAIL ausgegangen, aber zwei Regeln fehlt die Evidenz für ein PASS.

Mit Gold-Kontext diagnostizieren, neben einer Kontrolle

oloproof diagnose RUN_ID --intervention gold-context --criterion answer_correct
Selected: 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:50a6124f…
Child runs: gold context run_…, control run_…
Cases: oloproof inspect sha256:50a6124f…

Aus den fehlgeschlagenen Fällen entstehen zwei Kindläufe: einer mit dem gold_context des Falls anstelle des abgerufenen Kontexts und eine Kontrolle, die sie unverändert erneut ausführt. Die Kontrolle macht die Lesart sicher: Ein Fall, der bei einer einfachen Wiederholung besteht, war instabil, nicht diagnostiziert. diagnose endet mit Exit 0, was immer es findet; über das Release entscheidet es nichts.

oloproof inspect DIAGNOSIS_ID
money_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 2

Die Labels lesen

LabelWas beobachtet wurdeWas es nicht belegt
RETRIEVAL_MISSKeine relevante Passage wurde abgerufen, und der Fall bestand mit der Gold-PassageDass das Retrieval das Einzige ist, was falsch ist, oder dass eine bestimmte Retrieval-Änderung es beheben wird
RANKED_OUTEine relevante Passage wurde unterhalb von top_k abgerufen, und der Fall bestand mit der Gold-PassageDass ein größeres Top-k anderen Fällen hilft
CONTEXT_ASSEMBLY_LOSSEine relevante Passage innerhalb des Top-k wurde aus dem Kontext verworfen, und der Fall bestand mit der Gold-PassageWelches Budget ausreichen würde
GENERATION_FAILUREDer Fall schlug auch mit der Gold-Passage fehlDass das Modell und nicht der Prompt oder die Erwartung schuld ist
UNRESOLVEDNichts konnte geschlossen werden: Das System ist nicht gestuft (intervention_unsupported), der Fall erholte sich unter der Kontrolle (unstable_under_control), er hat keine Relevanz-Labels (no_relevance_labels), oder Evidenz fehltIrgendetwas über den Fall

Jedes Label ist eine Assoziation zwischen einem Fehlschlag und einer Stufe unter einer Intervention auf diesen Fällen. Es ist keine nachgewiesene Ursache: "Implicated" und "Candidate experiment" sind die stärksten Worte, die die Ausgabe verwendet, und die Zahlen beschreiben nur die ausgewählten Fälle ("no population claim"). seat_count ist eine gute Erinnerung: Er schlägt mit der richtigen Passage fehl, weil die Wissensbasis "five" sagt und der Fall "5" erwartet, was keine Retrieval-Änderung beheben kann.

Fälle mit und ohne Gold-Passagen

Nur fehlgeschlagene Fälle, die expected.gold_context deklarieren, können erneut ausgeführt werden. Entfernen Sie die Gold-Passage aus seat_count und money_back (und das Relevanz-Label aus money_back), und derselbe Befehl meldet:

Selected: 2 failed cases with gold context (observed; no population claim)
Excluded: 2 failed cases, no_gold_context - declare the passages that would have answered the case in its `expected.gold_context`, as a list of `{doc_id, text}` objects; an intervention needs them to tell a retrieval failure from a generation one
Control: 0 of 2 passed when re-executed without the intervention
Recovered under gold context: 2 of 2
CONTEXT_ASSEMBLY_LOSS: 2 of 2, recovered; relevant evidence within top-k was left out of the context

Die ausgeschlossenen Fälle werden aufgeführt, nicht stillschweigend verworfen. Beachten Sie auch, was das Entfernen eines Relevanz-Labels mit dem Lauf selbst macht: hit_rate_at_2 stieg auf 100.0% (12 / 12 observed, 1 excluded), weil der eine Fall, den das Retrieval verfehlt hat, nicht mehr gemessen wird. Ungelabelte Fälle verlassen den Nenner; sie zählen nicht als Bestehen, und eine Metrik über weniger Fälle kann besser aussehen, als die Anwendung ist. Labeln Sie die schwierigen Fälle zuerst.

Eine Korrektur testen, bevor man sie vornimmt: Top-k und ein Reranker

Zwei weitere Interventionen spielen das erfasste Retrieval mit einer anderen Einstellung erneut ab, sodass der Retriever nicht noch einmal aufgerufen wird:

oloproof diagnose RUN_ID --intervention top-k --top-k 4 --criterion answer_correct
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:50a6124f…): 3 of 4 recovered

Ein Reranker ist eine Funktion (input, candidates) -> candidates, die Sie schreiben. Speichern Sie sie als rerank.py neben app.py:

"""A candidate reranker: shorter passages first, so more of them fit the token budget."""

from oloproof import Passage


def shortest_first(input: dict, candidates: list[Passage]) -> list[Passage]:
    return sorted(candidates, key=lambda passage: len((passage.text or "").split()))
oloproof diagnose RUN_ID --intervention reranker --reranker rerank:shortest_first --criterion answer_correct
Recovered under reranker rerank:shortest_first: 0 of 4
Confirmed under reranker rerank:shortest_first: 0 of 0 RANKED_OUT cases also recovered

Keine von beiden erholt etwas, was die Gold-Kontext-Labels vorhergesagt haben: Kein Fehlschlag hier war eine Passage, die knapp unter dem Schnitt eingestuft wurde. Jede Wiedergabe trägt die Gold-Kontext-Labels weiter, sodass sich die Diagnosen zusammen lesen lassen.

Das von der Diagnose genannte Experiment ausführen und vergleichen

Erhöhen Sie token_budget in oloproof.yaml auf 120, dann:

oloproof run
oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy compare.yaml
Stages: retrieve 13 hit/0 miss; generate 7 hit/6 miss

Jedes Retrieval wurde wiederverwendet, weil top_k und das Budget außerhalb der Identität des Retrievals liegen; nur die sechs Fälle, deren Kontext sich geändert hat, wurden erneut generiert.

answer_correct: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excluded
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: Kein einziger Fall hat sein Urteil geändert, also wird die von der Diagnose angebotene Hypothese für diese Fälle nicht gestützt. Das ist ein nützliches Ergebnis. Das nächste Experiment sind kleinere Chunks oder die Prompts der beiden Fälle mit Verlust bei der Kontextzusammenstellung; bei seat_count muss die Erwartung korrigiert werden.

Fehlerbehebung

SymptomUrsacheAbhilfe
Configuration error: slice 'relevant_position' ... needs a staged systemEin Positions-Slice auf einem Callable- oder HTTP-SystemDen Slice entfernen oder zu Weg B wechseln
Der Lauf stoppt mit Exit 2 und malformed retrieval/v1 artifactEin Feld, das das Schema nicht erlaubt, oder mehr Kandidaten als depthNur die dokumentierten Felder abbilden; depth mindestens auf die Anzahl der gelieferten setzen
citations_valid zeigt 0 / 0 observed · 15 missing, und seine Regel ist INSUFFICIENT_EVIDENCE mit no_observationsDer Adapter hat citations/v1 (oder context/v1) nicht erfasst; jeder solche Fall fehlt, statt zu bestehenBeides auf jedem Pfad durch den Adapter erfassen, auch bei "keine Antwort"; oloproof inspect RUN_ID --failures zeigt den Fehler pro Fall
Eine Retrieval-Metrik zeigt viele excludedFälle ohne expected.relevantSie labeln oder den kleineren Nenner bewusst akzeptieren
diagnose meldet UNRESOLVED ... not stagedWeg AErwartet; für Interventionen Weg B verwenden
diagnose lehnt ab mit an intervention must re-execute the same systemCode oder Konfiguration haben sich seit dem Lauf geändertEinen Lauf der aktuellen Version diagnostizieren oder die gelaufene Version wiederherstellen
Die Diagnose wählt weniger Fälle aus, als fehlgeschlagen sindFehlgeschlagene Fälle ohne expected.gold_contextDie Gold-Passagen ergänzen; die ausgeschlossenen Fälle werden in der Ausgabe genannt
Retrievals werden nach einer Indexänderung wiederverwendetindex_version unverändertindex_version ändern, wenn sich der Index ändert

Einschränkungen

  • Oloproof ruft Ihre Anwendung auf; es hostet, isoliert oder setzt sie nicht zurück. Ihr Index, ihre Caches und jeder Zustand, den sie hält, gehören Ihnen.
  • Bei einer Blackbox sind keine Interventionen verfügbar: diagnose labelt jeden Fall als UNRESOLVED und führt nichts erneut aus.
  • Die Interventionen sind Gold-Kontext, Top-k und ein Reranker. Es gibt keine Intervention für Chunking, Embeddings oder Prompts.
  • Diagnose-Labels beschreiben die ausgewählten fehlgeschlagenen Fälle unter einer Intervention neben einer Kontrolle. Sie verbinden einen Fehlschlag mit einer Stufe; sie beweisen keine Ursache und treffen keine Aussage über nicht ausgewählte Fälle.
  • Retrieval-Metriken brauchen Relevanz-Labels, und die Diagnose braucht Gold-Passagen; Oloproof erzeugt beides nicht.
  • Die deterministischen Beispiele stehen stellvertretend für einen echten Retriever und ein echtes Modell. Ein Live-Modell in generate oder ein Judge-Evaluator ruft einen Provider auf, braucht Zugangsdaten und kostet Geld pro Fall.
  • Was wo funktioniert, SDK gegenüber YAML gegenüber Browser, steht in Was heute funktioniert.