Skip to content

Empezar

La API de Python

La versión en inglés de esta página ha cambiado desde que se tradujo. La página en inglés es la vigente. Leerla en inglés

Todo lo que hace la CLI lo hace también la biblioteca. Úsela cuando la evaluación deba vivir dentro de un script, un notebook o una suite de pruebas, y no junto a un archivo de configuración.

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

Todo lo que está bajo oloproof_core son componentes internos del motor y no forma parte de esta superficie.

Un sistema recibe la entrada de un caso, no el caso

Esto es lo primero que conviene hacer bien, porque hacerlo mal falla sin avisar.

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

Una fila del conjunto de datos tiene este aspecto:

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

La función recibe el objeto input, así que case["question"] es la pregunta y no existe case["expected"]. Lo que devuelve es la salida que lee un evaluador, así que ExactMatch(field="label") compara el label devuelto con el label esperado del caso.

Ejecutar una evaluación

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

Treinta casos, todos correctos, y aun así el intervalo baja hasta el 88,4%. Treinta casos no pueden establecer más que eso, diga lo que diga la estimación.

Leer un caso que falló

Si el sistema lanza una excepción, ese caso queda faltante, no incorrecto, y la métrica lo informa:

exact_label None lower=0.0 upper=1.0 0 30

Una estimación None con un intervalo que abarca todo el rango significa que no se observó nada. Revise n_missing antes de confiar en una estimación: un sistema en el que todos los casos lanzaron una excepción produce un objeto de resultado estructuralmente correcto, y es el conteo lo que indica que está vacío.

Eso es el contrato del denominador haciendo su trabajo, no un fallo de ese contrato (un caso con error se acota, no se descarta), pero nada lanza una excepción por usted, así que la comprobación le corresponde.

Escribir un evaluador propio

@evaluator convierte una función en un evaluador. La función recibe un argumento, el caso, y lee de él lo que necesita: case.output es lo que devolvió el sistema y case.expected es el objeto expected de la fila.

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 declara qué partes del caso lee, por motivos de procedencia; el valor por defecto es ("output", "expected"). Devuelve True o False, o una puntuación si declara value_type="score" y el score_range en el que se encuentran sus puntuaciones. Su versión incluye un digest del archivo que lo define, así que editarlo invalida sus juicios en caché.

Una función escrita como def f(output, expected) se rechaza en el momento de declararla, indicando la forma que funciona, en lugar de fallar en cada caso.

Aplicar una política

evaluate acepta una política y decide la ejecución, con las mismas reglas que la CLI lee de release.yaml:

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

Sin una política, result.gate es None: no hay ninguna regla que incumplir, así que no hay nada que decidir.

Siguientes pasos

artefactos en un evaluador.

existen los intervalos.