Przewodniki
Ewaluacja RAG
Angielska wersja tej strony zmieniła się od czasu tłumaczenia. Aktualna jest strona angielska. Przeczytaj po angielsku
Odpowiedź wspomagana wyszukiwaniem może być błędna z czterech różnych powodów: właściwy fragment nigdy nie został wyszukany, został wyszukany, ale umieszczony w rankingu zbyt nisko, znalazł się wystarczająco wysoko, a potem wypadł z kontekstu, albo dotarł do modelu, a model i tak się pomylił. Pojedyncza liczba dokładności nie potrafi ich rozróżnić. Oloproof uruchamia system RAG jako dwa widoczne dla siebie etapy, mierzy każdy z nich i ponownie wykonuje nieudane przypadki przy kontrolowanych zmianach, aby ustalić, który powód ma zastosowanie.
examples/support_rag/ to projekt, który uruchamia ta strona. Nie wymaga poświadczeń żadnego dostawcy.
System etapowy
System to klasa z etapem wyszukiwania i etapem generowania, opatrzona dekoratorem @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) zwraca do depth kandydatów, jako Passage(doc_id=..., score=..., text=...), w kolejności, w jakiej wygenerował je Twój mechanizm wyszukiwania. Oloproof zapisuje pozycje i nigdy nie zmienia rankingu. Następnie zachowuje pierwsze top_k, odrzuca fragmenty przekraczające token_budget i przekazuje resztę do generate(input, context). count_tokens(passage) jest potrzebne tylko przy token_budget; Oloproof nigdy nie szacuje tokenów.
oloproof.yaml wskazuje na klasę i może nadpisać dowolne z jej ustawień:
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 jest częścią tożsamości wyszukiwania. Zmień go, gdy zmienia się indeks, w przeciwnym razie zbuforowane wyniki wyszukiwania zostaną ponownie użyte względem indeksu, który już ich nie zwraca.
Co deklaruje przypadek
Przypadek RAG zawiera pod expected dwa pola, których nie potrzebuje żaden inny rodzaj przypadku:
{"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 wymienia dokumenty, które odpowiadają na pytanie. Czytają je metryki
wyszukiwania, a przypadek bez tego pola jest z nich wykluczany z no_relevance_labels.
- expected.gold_context to sam tekst fragmentu. Diagnoza podstawia go w miejsce wyszukanego
kontekstu, a nieudanego przypadku bez niego nie da się zdiagnozować.
Ewaluatory
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 i ndcg przyjmują k i na jego podstawie nazywają własne kryterium: hit_rate_at_2. Wpis w expected.relevant może też zawierać chunk_id oraz grade, którego wartość domyślna to 1; relevance_unit: chunk liczy wtedy każdy fragment jako osobną jednostkę zamiast całych dokumentów. citation_validity sprawdza, czy każdy identyfikator cytowany w odpowiedzi wskazuje fragment w kontekście, który otrzymała, a przy require_citations: true odpowiedź, która niczego nie cytuje, kończy się niepowodzeniem. groundedness_judge i citation_support_judge to sędziowie LLM, którzy czytają złożony kontekst i przyjmują provider oraz model jak każdy inny sędzia.
oloproof runTrzy wiersze tabeli metryk:
│ 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 │Pomiędzy nimi zarówno hit_rate_at_2, jak i recall_at_2 wskazują 92.3%, 12 z 13 obserwowanych, z dolną granicą 63.9%: odpowiedni fragment dla jednego pytania nigdy nie został wyszukany.
Cache: execution 0 hit/13 miss; judgment 0 hit/65 miss
Stages: retrieve 0 hit/13 miss; generate 0 hit/13 missWiersz Stages to własna pamięć podręczna systemu etapowego. Wyszukiwanie i generowanie są buforowane osobno, więc zmiana w generowaniu nigdy nie uruchamia ponownie wyszukiwania.
Ustalanie przyczyny
Cztery pytania zakończyły się niepowodzeniem. diagnose wykonuje je ponownie ze złotym fragmentem w miejsce wyszukanego kontekstu, obok próby kontrolnej, która wykonuje je ponownie bez zmian:
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:b2846cbe04099225bda4bf21beb1738f54d6cc0e9a7ce210bb3eb467619cbd69Przypadek, który przechodzi ze złotym fragmentem i nie przechodzi bez niego, zawiódł przed modelem. Przypadek, który nie przechodzi, mając złoty fragment, obciąża model. To próba kontrolna sprawia, że taka interpretacja jest bezpieczna: przypadek, który odzyskuje się przy zwykłym ponownym uruchomieniu, był niestabilny, a nie zdiagnozowany.
Identyfikator diagnozy wymienia przypadek stojący za każdą liczbą:
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 2Wskazuje czynnik, nigdy przyczynę. „Implicated” i „candidate experiment” to najmocniejsze słowa, jakich używa, ponieważ cztery przypadki odzyskane pod jedną interwencją nie ustalają, dlaczego zawiodły.
Testowanie poprawki przed jej wprowadzeniem
Dwie inne interwencje odtwarzają zapisane wyszukiwanie z innym ustawieniem, więc nie jest wykonywane żadne wywołanie mechanizmu wyszukiwania. top-k poszerza odcięcie:
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:668084c3e99df84f7b63f138792aa96f48e5cb8251fee3acae8e1cc0500ba085Nic się nie odzyskało, co przewidziały etykiety: żadne niepowodzenie tutaj nie było fragmentem umieszczonym tuż poniżej odcięcia. Odtworzenie przenosi etykiety ze złotego kontekstu, więc obie diagnozy czyta się razem. reranker przyjmuje --reranker z module:function i zamiast tego odtwarza wyszukiwanie przez Twój reranker.
Przeprowadzanie eksperymentu
Diagnoza wskazała większy budżet tokenów. Zwiększ token_budget do 120 i uruchom ponownie:
Cache: execution 0 hit/13 miss; judgment 0 hit/65 miss
Stages: retrieve 13 hit/0 miss; generate 7 hit/6 missKażde wyszukiwanie zostało użyte ponownie, ponieważ top_k i budżet tokenów leżą poza tożsamością wyszukiwania; ponownie wygenerowano tylko sześć przypadków, których kontekst się zmienił. Następnie porównaj, z polityką porównania z przykładu:
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 excludedDla każdego wycinka i metryki następuje jeden wiersz eksploracyjny, a potem decyzje:
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)Eksperyment nie pomógł: żaden z trzynastu nie zmienił werdyktu. A trzynaście sparowanych przypadków nie mogło wykazać zmiany o jakiejkolwiek wielkości istotnej dla wydania, co jest drugą rzeczą, którą mówi przedział.
Co dalej
- Wycinki omawia relevant_position i context_truncated.
- Reguły porównania omawia reguły, według których rozstrzygnięto ostatni
krok.
- Sędziowie omawia, co sędzia ugruntowania musi spełnić, zanim będzie mógł
bramkować.