Skip to content

Inizia

L'API Python

La versione inglese di questa pagina è cambiata da quando è stata tradotta. La pagina inglese è quella aggiornata. Leggila in inglese

Tutto ciò che fa la CLI lo fa anche la libreria. Usala quando la valutazione appartiene a uno script, a un notebook o a una suite di test anziché stare accanto a un file di configurazione.

from oloproof import evaluate, system, current_case
from oloproof.evaluators import ExactMatch, Contains, JsonSchema, Regex, RubricJudge, evaluator

Tutto ciò che si trova sotto oloproof_core è parte interna del motore e non fa parte di questa superficie.

Un sistema riceve l'input di un caso, non il caso

È l'unica cosa che conviene fare bene per prima, perché sbagliarla fallisce in silenzio.

@system(name="support-bot", version="1")
def answer(case):
    return {"label": "refund" if "refund" in case["question"].lower() else "other"}

Una riga del dataset ha questo aspetto:

{"id":"refund_00","input":{"question":"Can I get a refund? #0"},"expected":{"label":"refund"}}

La funzione riceve l'oggetto input, quindi case["question"] è la domanda e non esiste alcun case["expected"]. Ciò che restituisce è l'output che un valutatore legge, quindi ExactMatch(field="label") confronta la label restituita con la label attesa del caso.

Eseguirne uno

result = evaluate(
    system=answer,
    dataset="data/example.jsonl",
    evaluators=[ExactMatch(criterion="exact_label", field="label")],
)

for metric in result.metrics:
    print(metric.metric, metric.estimate, metric.interval, metric.n_observed, metric.n_missing)
exact_label 1.0 lower=0.8842966917779722 upper=1.0 30 0

Trenta casi, tutti corretti, e l'intervallo scende comunque fino all'88,4%. Trenta casi non possono stabilire di più, qualunque cosa dica la stima.

Leggere un caso fallito

Se il sistema solleva un'eccezione, quel caso è mancante anziché sbagliato, e la metrica lo riporta:

exact_label None lower=0.0 upper=1.0 0 30

Una stima pari a None con un intervallo che copre l'intero intervallo di valori significa che non è stato osservato nulla. Controlla n_missing prima di fidarti di una stima: un sistema in cui ogni caso ha sollevato un'eccezione produce un oggetto risultato strutturalmente corretto, ed è il conteggio a dirti che è vuoto.

È il contratto sul denominatore che fa il proprio lavoro, non un suo fallimento — un caso andato in errore viene delimitato, non scartato — ma nulla solleva eccezioni al posto tuo, quindi il controllo spetta a te.

Scrivere il tuo valutatore

@evaluator trasforma una funzione in un valutatore. La funzione riceve un solo argomento, il caso, e ne legge ciò che le serve: case.output è ciò che il sistema ha restituito e case.expected è l'oggetto expected della riga.

from oloproof.evaluators import evaluator

@evaluator(criterion="known_label", reads=("output",))
def known_label(case):
    return case.output["label"] in {"refund", "other"}

result = evaluate(system=answer, dataset="data/example.jsonl", evaluators=[known_label])
known_label 1.0 lower=0.8842966917779722 upper=1.0 30 0

reads dichiara quali parti del caso vengono lette, a fini di provenienza; il valore predefinito è ("output", "expected"). Restituisce True o False, oppure un punteggio se dichiara value_type="score" e lo score_range in cui ricadono i suoi punteggi. La sua versione include un digest del file che lo definisce, quindi modificarlo invalida i suoi giudizi in cache.

Una funzione scritta come def f(output, expected) viene rifiutata nel momento in cui viene dichiarata, indicando la forma che funziona, anziché fallire su ogni caso.

Applicare una policy

evaluate accetta una policy e decide l'esecuzione, con le stesse regole che la CLI legge da release.yaml:

result = evaluate(
    system=answer,
    dataset="data/example.jsonl",
    evaluators=[ExactMatch(criterion="exact_label", field="label")],
    policy="release.yaml",
)
print(result.gate)

Senza una policy, result.gate è None: non c'è alcuna regola da non soddisfare, quindi non c'è nulla da decidere.

Dove andare dopo

degli artefatti in un valutatore.

esistono gli intervalli.