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, evaluatorTodo 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 0Treinta 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 30Una 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 0reads 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
- Escribir una suite cubre los mismos evaluadores como configuración.
- Registrar lo que hizo un sistema cubre current_case() y la lectura de
artefactos en un evaluador.
- Comparar un candidato con una línea base cubre el flujo de trabajo para el que
existen los intervalos.