Começar
A API Python
A versão em inglês desta página mudou desde que foi traduzida. A página em inglês é a atual. Ler em inglês
Tudo o que a CLI faz, a biblioteca faz. Use-a quando a avaliação pertencer a um script, um notebook ou uma suíte de testes, e não a um arquivo de configuração ao lado.
from oloproof import evaluate, system, current_case
from oloproof.evaluators import ExactMatch, Contains, JsonSchema, Regex, RubricJudge, evaluatorTudo o que está sob oloproof_core é parte interna do engine e não faz parte desta superfície.
Um sistema recebe a entrada de um caso, não o caso
Esta é a única coisa que vale a pena acertar primeiro, porque errá-la falha em silêncio.
@system(name="support-bot", version="1")
def answer(case):
return {"label": "refund" if "refund" in case["question"].lower() else "other"}Uma linha do dataset tem esta forma:
{"id":"refund_00","input":{"question":"Can I get a refund? #0"},"expected":{"label":"refund"}}A função recebe o objeto input, então case["question"] é a pergunta e não existe case["expected"]. O que ela retorna é a saída que um avaliador lê, então ExactMatch(field="label") compara o label retornado com o label esperado do caso.
Executando uma avaliação
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 0Trinta casos, todos corretos, e o intervalo ainda desce até 88,4%. Trinta casos não conseguem estabelecer mais do que isso, diga a estimativa o que disser.
Lendo um caso que falhou
Se o sistema levanta uma exceção, aquele caso fica ausente em vez de errado, e a métrica informa isso:
exact_label None lower=0.0 upper=1.0 0 30Uma estimativa None com um intervalo que cobre toda a faixa significa que nada foi observado. Confira n_missing antes de confiar em uma estimativa: um sistema em que todos os casos levantaram exceção produz um objeto de resultado estruturalmente correto, e é a contagem que diz que ele está vazio.
Isso é o contrato de denominador fazendo o seu trabalho, e não uma falha dele — um caso que deu erro é limitado, não descartado —, mas nada levanta exceção por você, então a verificação é sua.
Escrevendo o seu próprio avaliador
@evaluator transforma uma função em um avaliador. A função recebe um argumento, o caso, e lê dele o que precisa: case.output é o que o sistema retornou e case.expected é o objeto expected da linha.
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 0reads declara quais partes do caso ele lê, para fins de proveniência; o padrão é ("output", "expected"). Ele retorna True ou False, ou uma pontuação se declarar value_type="score" e o score_range em que suas pontuações ficam. A versão dele inclui um digest do arquivo que o define, então editá-lo invalida os julgamentos dele em cache.
Uma função escrita como def f(output, expected) é recusada no momento em que é declarada, com a forma que funciona, em vez de falhar em cada caso.
Aplicando uma política
evaluate recebe uma política e decide a execução, com as mesmas regras que a CLI lê de release.yaml:
result = evaluate(
system=answer,
dataset="data/example.jsonl",
evaluators=[ExactMatch(criterion="exact_label", field="label")],
policy="release.yaml",
)
print(result.gate)Sem uma política, result.gate é None: não há regra a deixar de cumprir, então não há nada a decidir.
Próximos passos
- Escrevendo uma suíte trata dos mesmos avaliadores como configuração.
- Registrando o que um sistema fez trata de current_case() e da leitura de artefatos
em um avaliador.
- Comparando um candidato com uma linha de base trata do fluxo de trabalho para o qual
os intervalos existem.