Przewodniki
Dokumentacja SDK
Każda nazwa eksportowana przez pakiety oloproof i oloproof.evaluators, z sygnaturą, informacją, czy jest synchroniczna czy asynchroniczna, i tym, co zwraca. Wprowadzenie krok po kroku znajdziesz najpierw w Python API.
Publiczną powierzchnię stanowią tylko te dwa pakiety. Wszystko importowane z oloproof_core to wnętrze silnika i może się zmienić bez uprzedzenia. Każda funkcja poniżej działa lokalnie na magazynie projektu; żadna nie wysyła danych nigdzie, chyba że przekazany ewaluator wywołuje dostawcę modelu.
Uruchamianie ewaluacji
evaluate i aevaluate
def evaluate(*, system, dataset, evaluators, policy=None, **kwargs) -> EvaluationResult
async def aevaluate(*, system, dataset, evaluators, policy=None, **kwargs) -> EvaluationResult| Argument | Typ | Czym jest |
|---|---|---|
| system | funkcja @system, klasa lub instancja @rag_system albo obiekt wywoływalny | Testowany system. |
| dataset | ścieżka | Zestaw JSONL. Zob. Zestawy. |
| evaluators | lista | Instancje z oloproof.evaluators lub funkcje @evaluator. |
| policy | ścieżka do release.yaml, ReleasePolicy lub None | Polityka wydań. None nie uruchamia bramki: result.gate to None i niczego nie rozstrzygnięto. |
| concurrency | ConcurrencyConfig lub mapowanie takie jak {"system": 8, "judge": 4} | Liczba wywołań w toku jednocześnie. |
| slices | lista napisów | Wycinki eksploracyjne, jak w oloproof.yaml. |
| min_slice_support | liczba całkowita | Poniżej tylu kwalifikujących się przypadków wycinek nie ma przedziału. Domyślnie 30. |
| replicates | liczba całkowita | Mierz każdy przypadek tyle razy. Domyślnie 1. |
evaluate jest synchroniczna. Wywołana bez działającej pętli zdarzeń używa asyncio.run; wywołana z wnętrza działającej pętli (notatnik, test asynchroniczny) uruchamia ewaluację w osobnym wątku i blokuje do jej zakończenia, więc jest bezpieczna w obu miejscach. aevaluate to korutyna; czekaj na nią przez await w kodzie asynchronicznym.
Pozostałe argumenty nazwane (metrics, store, predictive, event_sink, retry_policy, traffic_draw_id) przyjmują typy silnika z oloproof_core i nie należą do stabilnej powierzchni.
from oloproof import evaluate, system, current_case
from oloproof.evaluators import ExactMatch, evaluator
@system(name="support-bot", version="1")
def answer(case):
current_case().usage(input_tokens=12, output_tokens=3)
return {"label": "refund" if "refund" in case["question"].lower() else "other"}
@evaluator(criterion="short_label")
def short_label(case):
return len(case.output["label"]) <= 6
result = evaluate(
system=answer,
dataset="cases.jsonl",
evaluators=[ExactMatch(criterion="correct_label", field="label"), short_label],
)
for metric in result.metrics:
print(metric.metric, metric.estimate, metric.interval, metric.n_observed, metric.n_missing)Uruchomione na zestawie z dwoma przypadkami bez polityki wypisało:
correct_label 1.0 lower=0.15811388300841903 upper=1.0 2 0
short_label 1.0 lower=0.15811388300841903 upper=1.0 2 0EvaluationResult
| Składowa | Typ | Czym jest |
|---|---|---|
| run | rekord przebiegu | Zapisany przebieg, z jego id, statusem i kompletnością. |
| suite, system, evaluators | rekordy wersji | Dokładne wersje, które zmierzył ten przebieg. |
| metrics | krotka wyników metryk | Jeden na kryterium i zadeklarowaną metrykę: metric, estimate, interval, n_total, n_eligible, n_observed, n_missing, exclusions, method. |
| gate | wynik bramki lub None | Z polityką: release_action, exit_code, decisions i reasons. |
| decisions | krotka | Decyzje bramki albo pusta bez polityki. |
| cases() | lista | Każdy przypadek z wykonaniem i ocenami. |
| failures() | lista | Przypadki, które się nie zakończyły, zakończyły się błędem lub oblały co najmniej jeden ewaluator. |
| print(stderr=False) | brak | Raport terminalowy, który wypisuje oloproof run. |
| to_bundle(path) | ścieżka | Zapisuje przenośny pakiet, tak jak oloproof export. |
Co oznaczają stany, kody przyczyn i liczności, opisują Wyniki i wykonanie.
evaluate_comparison i aevaluate_comparison
def evaluate_comparison(*, candidate_system, baseline_system, dataset, evaluators, policy, **kwargs) -> ComparisonEvaluationResult
async def aevaluate_comparison(*, candidate_system, baseline_system, dataset, evaluators, policy, **kwargs) -> ComparisonEvaluationResultUruchamia oba systemy na tym samym zestawie w jednej kolejności wyznaczonej ziarnem i rozstrzyga reguły porównania polityki. policy jest wymagana i musi zawierać co najmniej jedną regułę superiority, non_inferiority lub equivalence, w przeciwnym razie wywołanie zgłasza błąd konfiguracji. Dodatkowe argumenty nazwane: concurrency, replicates oraz typowane typami silnika metrics, store i retry_policy. Zachowanie synchroniczne i asynchroniczne jest takie jak w evaluate.
ComparisonEvaluationResult ma candidate i baseline (każdy to EvaluationResult) oraz comparison, który niesie sparowane różnice i ich decyzje. Zob. Porównywanie dwóch wersji.
Deklarowanie systemu
@system
def system(func=None, *, name=None, version=None, config=None, timeout_s=None, records=())Można go użyć bez argumentów (@system) lub z argumentami (@system(name=..., version=...)) albo wywołać na obiekcie (system(model.answer, version="v2")). Funkcja otrzymuje obiekt input przypadku, a nie cały przypadek, i zwraca wynik, który czytają ewaluatory. Może być def lub async def; funkcja synchroniczna działa w wątku roboczym.
| Argument | Domyślnie | Czym jest |
|---|---|---|
| name | nazwa funkcji | Część tożsamości wersji. |
| version | brak | Wymagane dla metody związanej lub obiektu wywoływalnego, ponieważ ich zachowanie zależy od stanu, którego Oloproof nie widzi. |
| config | puste | Ustawienia zapisywane razem z wersją. |
| timeout_s | 120 | Limit na wywołanie. Wywołanie, które go przekroczy, jest zapisywane jako wykonanie z przekroczonym limitem czasu. |
| records | puste | Rodzaje artefaktów, które zapisuje system, takie jak retrieval/v1. Ewaluator wymagający rodzaju, którego system nie deklaruje, jest odrzucany przed startem przebiegu. |
Kod źródłowy własnego modułu funkcji wchodzi do skrótu wersji, więc jego edycja unieważnia wykonania z cache. Co jeszcze to robi, a co nie, opisuje Dokumentacja konfiguracji.
current_case
def current_case() -> CaseRecorderDostępne tylko wtedy, gdy Oloproof wywołuje Twój system; w każdym innym miejscu zgłasza RuntimeError. Metody rejestratora:
| Metoda | Zapisuje |
|---|---|
| usage(*, input_tokens=None, output_tokens=None, cost_usd=None) | Tokeny i koszt wywołania modelu. Pominięta wartość pozostaje niezapisana, a nie zerowa. |
| artifact(kind, data) | Dowolną wartość JSON lub model Pydantic pod rodzajem takim jak trace lub conversation/v1. |
| retrieval(retrieval) | Uszeregowanych kandydatów zwróconych przez retriever (retrieval/v1). |
| context(context) | Kontekst złożony do generowania (context/v1). |
| citations(ids) | Identyfikatory cytowane przez odpowiedź, jako doc_id lub doc_id#chunk_id (citations/v1). |
| agent_trajectory(trajectory) | Kroki agenta, wywołania narzędzi i wyniki oraz punkty kontrolne (agent_trajectory/v1). |
Każda zwraca ArtifactRef (z wyjątkiem usage, która nic nie zwraca). Typowane ładunki są eksportowane do budowania tych rekordów: Retrieval, Passage, Context, ContextItem, DroppedItem, Citations, StageTimings, AgentTrajectory, AgentStep, AgentCheckpoint, AgentConstraintCheck oraz nazwa rodzaju CONVERSATION (conversation/v1).
@rag_system
def rag_system(*, name, depth, top_k, token_budget=None, index_version=None, version=None, config=None, citations_path="citations")Dekorator klasy. Klasa dostarcza retrieve(input, depth) i generate(input, context), a także count_tokens(passage), gdy ustawia token_budget. context to lista obiektów Passage, które przetrwały top_k i budżet, w kolejności rankingu. Oloproof sam zapisuje retrieval/v1, context/v1, citations/v1 i stage_timings/v1 i cache'uje każdy etap osobno. citations_path wskazuje pole wyniku zawierające identyfikatory cytowane przez odpowiedź. Zob. RAG.
Ewaluatory
Wszystkie klasy są w oloproof.evaluators. criterion każdej z nich nazywa metrykę, którą wytwarza. Które artefakty czyta każda z nich i jej odpowiednik w YAML, podaje tabela ewaluatorów w Dokumentacji konfiguracji.
| Klasa | Sygnatura |
|---|---|
| ExactMatch | (*, criterion, field=None, expected_field=None, strip=True, casefold=False) |
| Contains | (*, criterion, field=None, expected_field=None) |
| Regex | (*, criterion, pattern, field=None, pass_if="match") |
| JsonSchema | (*, criterion, schema, field=None) |
| RubricJudge | (*, criterion, provider, model, rubric_text=None, rubric_file=None, api_key_env=None, base_url=None, temperature=0, max_tokens=512, timeout_s=60.0) |
| Groundedness | (*, provider, model, criterion="groundedness", **options) |
| CitationSupport | (*, provider, model, criterion="citation_support", **options) |
| CitationValidity | (*, criterion="citations_valid", require_citations=False) |
| HitRate, Recall | (k=None, *, criterion=None, relevance_unit="doc"), k domyślnie 5 |
| MRR, NDCG | (k=None, *, criterion=None, relevance_unit="doc"), k domyślnie 10 |
| AgentMaxSteps | (max_steps, *, criterion=None) |
| AgentToolCalled | (tool_name, *, min_calls=1, criterion=None) |
| AgentNoToolLoop | (*, max_repeats=2, criterion="agent_no_tool_loop") |
| AgentToolSequence | (*, ordered=True, criterion="agent_tool_sequence") |
| AgentNoUndeclaredTool | (*, criterion="agent_no_undeclared_tool") |
| AgentConstraintsSatisfied | (constraints=(), *, criterion="agent_constraints_satisfied") |
| AgentRoute | (*, criterion="agent_route") |
| AgentToolPermissions | (permissions, *, criterion="agent_tool_permissions") |
| AgentMaxHandoffs | (max_handoffs, *, criterion=None) |
| ConversationCompleted | (*, criterion="conversation_completed") |
| ConversationJudge | jak RubricJudge |
| PredictiveCorrect, PredictiveRecall, PredictivePrecision | (*, criterion, positive=True, field="label", expected_field="label") |
| AbsoluteError | (*, criterion, target_range, field="label", expected_field="label") |
| Brier, PredictiveRanking | (*, criterion, positive=True, field="score", expected_field="label") |
| LogLoss | (*, clip, criterion, positive=True, field="score", expected_field="label") |
| CustomEvaluator | (func, *, criterion, reads=("output", "expected"), cacheable=False, version=None, value_type="binary", score_range=None) |
provider to "anthropic", "openai" lub "openai_compatible". Sędzia czyta swój klucz ze zmiennej środowiskowej wskazanej przez api_key_env (domyślnie ANTHROPIC_API_KEY lub OPENAI_API_KEY) i jest rozliczany przez tego dostawcę. Groundedness i CitationSupport przyjmują pozostałe ustawienia RubricJudge przez **options. Sędzia probabilistyczny, klasyfikator-model i kaskada nie mają klasy w SDK; istnieją tylko w YAML.
ConversationCompleted i ConversationJudge czytają artefakt conversation/v1, który zapisuje Twój system. Oloproof nie prowadzi rozmowy: Twoja aplikacja wykonuje każdą turę i zapisuje zapis rozmowy. Zob. Agenci.
@evaluator
def evaluator(*, criterion, reads=("output", "expected"), cacheable=False, version=None, value_type="binary", score_range=None)Opakowuje funkcję jednego argumentu, przypadku, w CustomEvaluator. Przypadek ma output, expected i scenario, a artifacts(name) zwraca ładunki zapisanego rodzaju. Funkcja może być def lub async def. Ewaluator binarny zwraca True lub False; ewaluator wyniku liczbowego deklaruje value_type="score" i score_range=(low, high) i zwraca liczbę. Wyjątek zgłoszony przez funkcję zapisuje przypadek jako brakujący dla tego kryterium, nigdy jako niepowodzenie.
reads musi wymieniać każde pole, które czyta funkcja (input, output, expected, metadata, metadata.<key> lub artifacts.<name>), ponieważ ocena w cache jest kluczowana dokładnie nimi. Oceny są ponownie używane między przebiegami tylko przy cacheable=True. Kod źródłowy definiującego modułu wchodzi do wersji, więc jego edycja je unieważnia. YAML nie może wskazać własnego ewaluatora.
Diagnoza
diagnose i adiagnose
def diagnose(run_id, **kwargs) -> InterventionResult
async def adiagnose(run_id, *, system, evaluators, intervention, criterion, control=True, top_k=None, reranker=None, reranker_root=None, store=None, concurrency=None) -> InterventionResultPonownie wykonuje nieudane przypadki zapisanego przebiegu przy jednej interwencji: "gold-context", "top-k" (z top_k) lub "reranker" (z reranker). system i evaluators muszą być wersjami, których użył przebieg; inna wersja jest odrzucana, zanim cokolwiek się wykona. Przy control=True obok interwencji działa świeża próba kontrolna, aby zmianę dało się odróżnić od zmienności między przebiegami. diagnose to forma synchroniczna i wewnątrz działającej pętli zachowuje się jak evaluate. Przebieg pracy opisuje RAG.
InterventionResult zawiera identyfikator przebiegu nadrzędnego, interwencję, informację, czy była obsługiwana, przebiegi interwencji i kontroli, wynik dla każdego przypadku oraz DiagnosisReport z wpisami CaseDiagnosis, gdy taki powstał.
Odtwarzanie agenta
def supports_replay(system) -> bool
def checkpoint_for(trajectory, step_index) -> AgentCheckpoint | None
async def replay_case(system, *, scenario_id, trajectory, checkpoint, change) -> ReplayOutcome
def label_case(outcome) -> CaseDiagnosis
def label_cases(outcomes) -> tuple[CaseDiagnosis, ...]
def unnecessary_steps(labels) -> tuple[UnnecessaryStep, ...]Odtwarzanie to coś, co robi Twój system, a nie coś, co symuluje Oloproof. System je obsługuje tylko wtedy, gdy implementuje async def replay(self, trajectory, *, checkpoint, change) -> AgentTrajectory, zwracające to, co agent zrobił od punktu kontrolnego dalej; Oloproof dokleja zapisany początek i porównuje. Twoja aplikacja zarządza swoim stanem, sesjami i skutkami ubocznymi narzędzi, w tym ich resetem przed odtworzeniem. supports_replay informuje, czy system deklaruje tę metodę.
replay_case to korutyna: użyj await albo wywołaj ją przez asyncio.run. Przed odtworzeniem uruchamia kontrolę (ten sam punkt kontrolny z ReplayChange(kind="resume")) i nie próbuje odtworzenia, gdy kontrola nie odtwarza zapisu. change to ReplayChange(kind="drop_step", step_index=...) lub ReplayChange(kind="resume"). checkpoint_for wybiera najpóźniejszy zapisany punkt kontrolny ściśle przed krokiem albo None, a wtedy wynik jest odrzucany jako no_checkpoint_recorded bez dotykania systemu.
ReplayOutcome niesie scenario_id, change, statusy końcowe odtworzenia i kontroli oraz discarded z przyczyną, gdy przypadek nie daje dowodów. Odrzucony przypadek to nie przypadek nieudany. label_case zamienia wynik w CaseDiagnosis z FailureLabel i jego LabelReason; unnecessary_steps wymienia kroki, których usunięcie pozostawiło wynik nienaruszonym. Zob. Agenci.
Ludzkie etykiety i zaufanie do ewaluatorów
def record_label(*, run_id, scenario_id, criterion, passed, labelled_by, note=None, purpose="measurement", sample_index=0, config="oloproof.yaml", store=None, ...) -> HumanLabelZapisuje werdykt pass/fail jednej osoby dla jednego przypadku zapisanego przebiegu. Etykiety zasilają oloproof evaluators validate, które mierzy zgodność sędziego z nimi (AgreementResult) i zapisuje jego status (RegistryEntry). Dalsze argumenty measurement_sample_* wiążą etykietę z próbą pomiarową; oloproof labels export i oloproof labels import w CLI wypełniają je za Ciebie. Zob. Sędziowie.
Polityki w kodzie
ReleasePolicy, IntervalThresholdRule, ObservedCountRule i DecisionRule (suma dwóch poprzednich) budują politykę bez pliku. Ich pola to pola release.yaml z Dokumentacji konfiguracji; reguła przedziałowa przyjmuje direction (min lub max) i threshold zamiast min: lub max:. Reguły porównania nie mają eksportowanej klasy; zapisz je w release.yaml i przekaż jego ścieżkę.
from oloproof import IntervalThresholdRule, ReleasePolicy
policy = ReleasePolicy(
rules=(IntervalThresholdRule(id="accuracy", metric="correct_label", direction="min", threshold=0.8),),
)Inne eksporty
| Nazwa | Czym jest |
|---|---|
| ConcurrencyConfig | Limity system i judge, jak w oloproof.yaml. |
| TransientError | Zgłoś go z systemu z retryable=True, aby wywołanie zostało ponowione z wycofaniem. |
| ArtifactRef | Referencja zwracana przez zapisany artefakt: jego rodzaj i skrót. |
| __version__ | Zainstalowana wersja pakietu. |