Skip to content

Aan de slag

De Python-API

De Engelse versie van deze pagina is gewijzigd sinds hij werd vertaald. De Engelse pagina is de actuele. Lees hem in het Engels

Alles wat de CLI doet, doet de library ook. Gebruik die wanneer de evaluatie thuishoort in een script, een notebook of een testsuite in plaats van naast een configuratiebestand.

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

Alles onder oloproof_core is interne engine-code en maakt geen deel uit van dit oppervlak.

Een systeem krijgt de input van een case, niet de case

Dit is het enige dat je eerst goed moet krijgen, omdat het fout doen stilletjes misgaat.

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

Een datasetrij ziet er zo uit:

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

De functie ontvangt het input-object, dus case["question"] is de vraag en er is geen case["expected"]. Wat ze teruggeeft is de output die een evaluator leest, dus ExactMatch(field="label") vergelijkt het teruggegeven label met het verwachte label van de case.

Er een draaien

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

Dertig cases, allemaal correct, en het interval reikt nog steeds tot 88.4%. Dertig cases kunnen niet meer vaststellen dan dat, wat de schatting ook zegt.

Een mislukte case lezen

Als het systeem een exceptie werpt, ontbreekt die case in plaats van fout te zijn, en de metriek rapporteert dat:

exact_label None lower=0.0 upper=1.0 0 30

Een schatting van None met een interval over het hele bereik betekent dat er niets werd geobserveerd. Controleer n_missing voordat je een schatting vertrouwt: een systeem waarvan elke case een exceptie wierp, levert een resultaatobject op dat structureel in orde is, en het aantal is wat je vertelt dat het leeg is.

Dat is het noemercontract dat zijn werk doet, niet een tekortkoming ervan — een case die een fout gaf, wordt begrensd, niet weggelaten — maar niets werpt namens jou een exceptie, dus de controle is aan jou.

Je eigen evaluator schrijven

@evaluator maakt van een functie een evaluator. De functie neemt één argument, de case, en leest daaruit wat ze nodig heeft: case.output is wat het systeem teruggaf en case.expected is het expected-object van de rij.

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 declareert welke delen van de case ze leest, voor de herkomst; de standaard is ("output", "expected"). Ze geeft True of False terug, of een score als ze value_type="score" declareert en de score_range waarin haar scores liggen. Haar versie bevat een digest van het bestand dat haar definieert, dus haar bewerken maakt haar gecachte oordelen ongeldig.

Een functie geschreven als def f(output, expected) wordt geweigerd op het moment dat ze wordt gedeclareerd, met de vorm die wel werkt, in plaats van bij elke case te falen.

Een policy toepassen

evaluate neemt een policy en beslist over de run, met dezelfde regels die de CLI uit release.yaml leest:

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

Zonder policy is result.gate gelijk aan None: er is geen regel om tekort te schieten, dus er valt niets te beslissen.

Verder lezen

artefacten in een evaluator.

intervallen bestaan.