Przejdź do treści

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
ArgumentTypCzym jest
systemfunkcja @system, klasa lub instancja @rag_system albo obiekt wywoływalnyTestowany system.
datasetścieżkaZestaw JSONL. Zob. Zestawy.
evaluatorslistaInstancje z oloproof.evaluators lub funkcje @evaluator.
policyścieżka do release.yaml, ReleasePolicy lub NonePolityka wydań. None nie uruchamia bramki: result.gate to None i niczego nie rozstrzygnięto.
concurrencyConcurrencyConfig lub mapowanie takie jak {"system": 8, "judge": 4}Liczba wywołań w toku jednocześnie.
sliceslista napisówWycinki eksploracyjne, jak w oloproof.yaml.
min_slice_supportliczba całkowitaPoniżej tylu kwalifikujących się przypadków wycinek nie ma przedziału. Domyślnie 30.
replicatesliczba całkowitaMierz 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 0

EvaluationResult

SkładowaTypCzym jest
runrekord przebieguZapisany przebieg, z jego id, statusem i kompletnością.
suite, system, evaluatorsrekordy wersjiDokładne wersje, które zmierzył ten przebieg.
metricskrotka wyników metrykJeden na kryterium i zadeklarowaną metrykę: metric, estimate, interval, n_total, n_eligible, n_observed, n_missing, exclusions, method.
gatewynik bramki lub NoneZ polityką: release_action, exit_code, decisions i reasons.
decisionskrotkaDecyzje bramki albo pusta bez polityki.
cases()listaKażdy przypadek z wykonaniem i ocenami.
failures()listaPrzypadki, które się nie zakończyły, zakończyły się błędem lub oblały co najmniej jeden ewaluator.
print(stderr=False)brakRaport terminalowy, który wypisuje oloproof run.
to_bundle(path)ścieżkaZapisuje 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) -> ComparisonEvaluationResult

Uruchamia 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.

ArgumentDomyślnieCzym jest
namenazwa funkcjiCzęść tożsamości wersji.
versionbrakWymagane dla metody związanej lub obiektu wywoływalnego, ponieważ ich zachowanie zależy od stanu, którego Oloproof nie widzi.
configpusteUstawienia zapisywane razem z wersją.
timeout_s120Limit na wywołanie. Wywołanie, które go przekroczy, jest zapisywane jako wykonanie z przekroczonym limitem czasu.
recordspusteRodzaje 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() -> CaseRecorder

Dostępne tylko wtedy, gdy Oloproof wywołuje Twój system; w każdym innym miejscu zgłasza RuntimeError. Metody rejestratora:

MetodaZapisuje
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.

KlasaSygnatura
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")
ConversationJudgejak 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) -> InterventionResult

Ponownie 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, ...) -> HumanLabel

Zapisuje 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

NazwaCzym jest
ConcurrencyConfigLimity system i judge, jak w oloproof.yaml.
TransientErrorZgłoś go z systemu z retryable=True, aby wywołanie zostało ponowione z wycofaniem.
ArtifactRefReferencja zwracana przez zapisany artefakt: jego rodzaj i skrót.
__version__Zainstalowana wersja pakietu.