Skip to content

Rozpocznij

API Pythona

Angielska wersja tej strony zmieniła się od czasu tłumaczenia. Aktualna jest strona angielska. Przeczytaj po angielsku

Wszystko, co robi CLI, robi też biblioteka. Warto z niej korzystać, gdy ewaluacja ma się znaleźć wewnątrz skryptu, notatnika lub zestawu testów, a nie obok pliku konfiguracyjnego.

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

Wszystko pod oloproof_core to wewnętrzne elementy silnika i nie należy do tego interfejsu.

System otrzymuje wejście przypadku, a nie sam przypadek

To jedyna rzecz, którą warto od początku zrobić dobrze, ponieważ błąd w tym miejscu nie daje żadnego sygnału.

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

Wiersz zbioru danych wygląda tak:

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

Funkcja otrzymuje obiekt input, więc case["question"] to pytanie, a case["expected"] nie istnieje. To, co funkcja zwraca, jest wyjściem odczytywanym przez ewaluator, więc ExactMatch(field="label") porównuje zwrócone label z oczekiwanym label przypadku.

Uruchomienie

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

Trzydzieści przypadków, wszystkie poprawne, a przedział i tak sięga w dół do 88,4%. Trzydzieści przypadków nie może wykazać więcej, niezależnie od tego, co mówi estymata.

Odczytywanie przypadku, który się nie powiódł

Jeśli system zgłosi wyjątek, przypadek jest brakujący, a nie błędny, i metryka to raportuje:

exact_label None lower=0.0 upper=1.0 0 30

Estymata None z przedziałem obejmującym cały zakres oznacza, że niczego nie zaobserwowano. Przed zaufaniem estymacie należy sprawdzić n_missing: system, w którym każdy przypadek zgłosił wyjątek, tworzy obiekt wyniku o poprawnej strukturze, a to licznik mówi, że jest on pusty.

To kontrakt mianownika działa zgodnie z przeznaczeniem, a nie jego awaria — przypadek zakończony błędem jest ograniczany, a nie pomijany — ale nic nie zgłasza wyjątku w Twoim imieniu, więc to sprawdzenie należy do Ciebie.

Pisanie własnego ewaluatora

@evaluator zamienia funkcję w ewaluator. Funkcja przyjmuje jeden argument, przypadek, i odczytuje z niego to, czego potrzebuje: case.output to wartość zwrócona przez system, a case.expected to obiekt expected wiersza.

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 deklaruje, które części przypadku ewaluator odczytuje, na potrzeby pochodzenia danych; wartość domyślna to ("output", "expected"). Ewaluator zwraca True lub False albo wynik liczbowy, jeśli deklaruje value_type="score" oraz score_range, w którym mieszczą się jego wyniki. Jego wersja zawiera skrót pliku, który go definiuje, więc edycja unieważnia jego zapisane w pamięci podręcznej oceny.

Funkcja zapisana jako def f(output, expected) jest odrzucana już w chwili deklaracji, z podaniem działającej postaci, zamiast zawodzić przy każdym przypadku.

Stosowanie polityki

evaluate przyjmuje politykę i rozstrzyga o przebiegu według tych samych reguł, które CLI odczytuje z release.yaml:

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

Bez polityki result.gate ma wartość None: nie ma reguły, której można by nie spełnić, więc nie ma o czym rozstrzygać.

Co dalej

w ewaluatorze.

istnieją przedziały.