Skip to content

Contratos del motor de etiquetado

Los seis tipos de contrato que el motor de etiquetado pone a prueba frente a etiquetas humanas, desde el riesgo selectivo y los intervalos PPI hasta la prueba del anotador alternativo, y cómo falla cada uno.

Un contrato es una afirmación sobre las etiquetas finales que el motor de etiquetado pone a prueba frente a las etiquetas humanas de una muestra aleatoria. Cada contrato nombra un esquema de anotación (schema) y tiene una confidence, 0.9 por defecto, que es la probabilidad de que la afirmación se cumpla. Por tanto, una confidence de 0.9 admite un 10% de probabilidad de que un contrato cumplido sea erróneo.

Los seis tipos hacen afirmaciones distintas y se adaptan a estudios distintos:

TipoAfirmaciónPara
selective_riskComo mucho una proporción error de las etiquetas de máquina aceptadas es incorrectaConjuntos de datos y de entrenamiento en los que cada etiqueta tiene que ser utilizable
ppiUn intervalo para la prevalencia de cada etiqueta (o para una puntuación media) que es válido sea cual sea la calidad de la máquinaInformar de tasas, como «el 12% de las publicaciones son tóxicas [10.5, 13.6]»
no_worse_than_humanLa máquina coincide con las personas al menos tanto como una personaSustituir a anotadores o a un juez LLM
budget_firstQué se puede obtener con un presupuesto de etiquetas humanasPlanificar antes de gastar
distributionalLa distribución de etiquetas de la máquina se acerca a cómo se reparten las personasTareas subjetivas en las que el desacuerdo es un dato
threshold_legacyNinguna, acepta por encima de una confianza fijaSolo configuraciones traducidas

Ninguno de estos contratos dice que las etiquetas estén libres de errores. selective_risk acota la tasa de error entre las etiquetas aceptadas, y cada contrato que pone a prueba las máquinas las mide frente a las personas que etiquetaron la muestra.

Estado de un contrato

Cada contrato tiene uno de cinco estados, que se muestran en la página de administración, con potato label status y en el certificado:

EstadoSignificado
metLa prueba se superó con la cascada actual.
insufficientTodavía no hay suficientes etiquetas humanas, con una estimación de cuántas más hacen falta. Cuando esa estimación supera lo que le queda al corpus por muestrear, el estado indica que el objetivo no se puede alcanzar con este corpus.
infeasibleHay suficientes etiquetas, pero ninguna regla de aceptación supera la prueba, por ejemplo porque la confianza de la máquina no separa las respuestas correctas de las incorrectas.
violatedLas auditorías de las etiquetas aceptadas muestran que la tasa de error está por encima del objetivo (con features.drift, activado por defecto).
staleUna fuente, un prompt o el esquema cambiaron desde la última prueba. Las etiquetas aceptadas esperan en pending_recert.

Una etiqueta de máquina solo se acepta cuando todos los contratos selective_risk y threshold_legacy de su esquema están cumplidos y la aceptan. Los contratos indican qué deben cumplir las etiquetas, así que uno no cumplido bloquea la aceptación en lugar de saltarse, y el estado, la página de administración y el certificado nombran el contrato que no se cumple. Cuando ninguna regla puede estar en vigor y ya no se está muestreando nada más (un contrato es inviable, la muestra de calibración está completa o no se pudo proyectar nada), los ítems que siguen sin etiqueta van a las personas, dentro de budgets.human_labels.

Particiones dev y cert

El motor mantiene separadas las etiquetas que eligen una regla y las etiquetas que la ponen a prueba. Las peticiones de calibración se extraen al azar con una probabilidad de inclusión registrada, siempre son ciegas, y cada una va al azar a una de dos particiones:

  • dev (humans.dev_fraction, la mitad por defecto) ajusta los calibradores y elige los umbrales;
  • cert pone a prueba la regla elegida, y nada más la lee.

Inspecciones

Cada nueva prueba de un contrato se hace con un nivel más estricto, así que volver a probar a medida que llegan etiquetas no infla la confianza. La inspección k recibe (1 - confidence) * 6 / (pi^2 k^2) del presupuesto de error, que suma el presupuesto completo sobre todas las inspecciones posibles, y la primera inspección recibe el 61%.

  • Las inspecciones se cuentan por contrato, a lo largo de todas las cascadas con las que se ha probado, y un contrato renombrado conserva las inspecciones de su id anterior. Probar prompts o modelos hasta que uno supere la prueba cuesta una inspección cada vez. Volver a una cascada anterior también es una inspección nueva, y su resultado anterior no se restaura.
  • Volver a probar los mismos datos no es una inspección nueva. Las mismas etiquetas cert, las mismas predicciones y la misma regla elegida en dev devuelven el resultado guardado. Una prueba que no se pudo ejecutar, por ejemplo porque no hay etiquetas cert en una clase, no gasta nada.
  • potato label certify pone a prueba a la vez las nuevas etiquetas cert y las nuevas predicciones, igual que sus equivalentes de REST, MCP y SDK. Cuando solo cambiaron las etiquetas dev, devuelve el resultado guardado con una nota de que dev elige ahora otra regla, y --retest pone a prueba esa regla en la siguiente inspección.
  • El planificador certifica por su cuenta a medida que llegan etiquetas. Un contrato selective_risk cumplido sigue cumplido para su cascada, y las auditorías lo vigilan. Un contrato no cumplido se vuelve a probar cuando sus etiquetas han crecido una cuarta parte, y al menos en 10. Los resultados de ppi, distributional y no_worse_than_human son estimaciones y no pruebas de aprobado o suspenso, así que el planificador los vuelve a estimar en los mismos hitos y una vez más cuando la muestra de calibración está completa.
  • Una etiqueta cert editada es un dato nuevo. Cuando un anotador cambia su respuesta, la edición no cuesta más que una etiqueta nueva. Si se edita de vuelta a un estado ya probado, vuelve el resultado de esa prueba. Si ninguna de las pruebas del resultado guardado ve más errores tras la edición, el resultado y su inspección se mantienen. Si no, el planificador espera a que las etiquetas crezcan una cuarta parte desde la primera edición, de modo que una racha de correcciones se convierte en una sola prueba, y mientras tanto las etiquetas aceptadas siguen aceptadas con una nota en el contrato. Cuando no van a llegar más etiquetas, prueba de inmediato, y una certificación explícita prueba en la siguiente inspección.

Las etiquetas que las personas dieron después de ver una respuesta de máquina (peticiones de verificación) y las etiquetas dadas fuera de las peticiones del motor nunca certifican ni estiman nada. Pueden servir para entrenar un modelo destilado.

selective_risk

selective_risk acota la proporción de etiquetas de máquina aceptadas que son incorrectas. La clave error es la mayor tasa de error tolerada entre las etiquetas aceptadas y es obligatoria:

yaml
- id: accuracy
  kind: selective_risk
  schema: sentiment
  error: 0.05          # required: largest tolerated error among accepted labels
  confidence: 0.9
  per_class: true      # test each predicted class separately
  tolerance: 0.5       # graded families only: loss at or below this counts as correct

La regla es un umbral de confianza para cada nivel de la cascada y, con per_class, para cada clase predicha. En todos los niveles salvo el último, el umbral se elige en dev y se prueba una vez en cert. El último nivel prueba umbrales desde el elegido en dev hacia otros más permisivos, uno tras otro, y se detiene en el primero que falla. Ese procedimiento es Learn-then-Test de secuencia fija (Angelopoulos et al., 2025). Cada prueba es una prueba binomial unilateral de que el error entre las etiquetas aceptadas está por encima de error, con el nivel repartido entre niveles de la cascada y clases. Un nivel que falla no acepta nada, y sus ítems van a las personas.

Lo que cuenta como «correcto» depende de la familia del esquema. La pérdida de cada familia está en la tabla, y una etiqueta cuenta como correcta cuando su pérdida es menor o igual que tolerance:

Familia de esquemaPérdidatolerance por defecto
Una opción entre N (radio, select)0 si es la misma etiqueta0
Ordinal (likert)distancia en la escala / (puntos - 1)0
Continua (slider, number)distancia / (max - min)0.05
Multietiqueta (multiselect)1 - solapamiento de Jaccard0
Regiones de imagen (image_annotation)1 - IoU media sobre las formas emparejadas0.5
Segmentos de audio o vídeo, temporal_grounding, tiered_annotation1 - IoU temporal media0.5
Objetos 3D (spatial_annotation)1 - IoU 3D media0.5
Trazas de agentes (process_reward, trajectory_eval, ...)proporción de pasos comunes etiquetados de forma distinta0

Las pérdidas para regiones, segmentos, objetos 3D y trazas son las que usa el informe de acuerdo en /admin/iaa, así que una máquina se puntúa frente a una persona igual que dos personas se puntúan entre sí. El texto libre y los esquemas por pares todavía no tienen familia, y el certificado los indica como no admitidos.

La prueba necesita que cada grupo de ítems cert que se prueba sea una muestra uniforme. Un grupo cuyos ítems se muestrearon con probabilidades desiguales no se prueba, y el resultado lo nombra.

En el último nivel, un umbral se elige en dev solo cuando el error en dev es como mucho la mitad del objetivo y se espera que haya suficientes etiquetas cert para superar una primera prueba. La proyección de cuántas etiquetas más hacen falta solo cuenta umbrales que se podrían elegir de ese modo. Cuando cert ya tiene las etiquetas que pedía la proyección y la prueba sigue fallando, la siguiente proyección usa la tasa de error que muestran dev y cert juntas, no solo la de dev. Cuando el menor error en dev está por debajo del objetivo pero por encima de su mitad, no se prueba nada ni se proyecta nada. El resultado lo indica y nombra el error, ya que más etiquetas solo ayudan si el error resulta ser menor.

metrics.accepted_by_tier es la cobertura de la regla sobre toda la población, incluidos los ítems de calibración, y no es un recuento de etiquetas de máquina entregadas. La línea «Machine labels accepted, by source» del certificado es la que las cuenta.

La pérdida de trazas compara solo los pasos que ambas partes etiquetaron, así que una persona que marcó algunos pasos se compara en esos pasos. Los pasos que nadie etiquetó no se comprueban, y una persona que etiqueta solo el paso 0 y coincide allí con el juez cuenta como si coincidiera con la etiqueta de toda la traza. Cuando haya que comprobar todos los pasos, pide a las personas que etiqueten todos los pasos.

ppi

ppi da un intervalo para la prevalencia de cada etiqueta, o para una puntuación media, corregido por los errores de la máquina:

yaml
- id: prevalence
  kind: ppi
  schema: sentiment
  estimand: prevalence   # or mean, for numeric scores
  by: language           # optional: an interval per value of this item field
  confidence: 0.95
  max_width: 0.05        # optional: met once every interval is at most this wide

La inferencia potenciada por predicciones (Angelopoulos et al., 2023) corrige la estimación de la máquina con su error en la muestra etiquetada por personas. El intervalo es válido sea cual sea la calidad de la máquina. Una buena máquina lo hace más estrecho de lo que conseguirían las personas solas, y una mala no lo hace más ancho. Con probabilidades de inclusión iguales, el motor usa PPI++ con un peso ajustado, y con probabilidades desiguales (muestreo estratificado o guiado por la incertidumbre) usa el estimador de diferencia de Horvitz-Thompson. La etiqueta de máquina que usa es la que entregaría la cascada. El campo by se copia de los ítems cuando se registran. Sin max_width, el contrato se cumple en cuanto tiene suficientes etiquetas para informar.

no_worse_than_human

no_worse_than_human pregunta si la máquina coincide con las personas al menos con la misma frecuencia que una persona:

yaml
- id: replaces-a-person
  kind: no_worse_than_human
  schema: verdict
  epsilon: 0.1

El contrato ejecuta la prueba del anotador alternativo (Calderon et al., 2025). Dejando fuera a cada persona por turnos, prueba si la máquina coincide con las personas restantes al menos con la misma frecuencia que la persona excluida, con un margen de epsilon. La máquina supera la prueba cuando gana frente a al menos la mitad de las personas, con la tasa de falsos descubrimientos controlada entre personas.

La prueba necesita ítems etiquetados por varias personas. Define humans.overlap (la proporción de la muestra etiquetada más de una vez) y humans.overlap_k (personas por ítem, al menos 3), y la prueba necesita al menos 3 anotadores con 30 ítems cada uno. El contrato sigue en insufficient hasta tenerlos. Usa este contrato cuando un objetivo fijo de exactitud mediría sobre todo el ruido de los anotadores. Si dos personas cuidadosas coinciden el 85% de las veces, no se puede demostrar que ningún etiquetador «acierte» el 95%.

budget_first

budget_first proyecta qué se obtiene con un presupuesto de etiquetas humanas antes de gastarlo:

yaml
- id: plan
  kind: budget_first
  schema: sentiment
  human_labels: 500      # or human_usd, priced at the crowd reward

La proyección sale de las etiquetas dev recogidas hasta el momento. Para cada objetivo de error de una cuadrícula, da la proporción del corpus que se podría certificar que etiquetan las máquinas con este presupuesto y lo ancho que sería cada intervalo de prevalencia. El contrato está en met en cuanto hay suficientes etiquetas dev para proyectar. No promete nada sobre las etiquetas; eso lo hacen selective_risk y ppi una vez que llegan las etiquetas.

distributional

distributional compara la distribución de etiquetas de la máquina con cómo se reparten las personas, en tareas subjetivas en las que las personas discrepan por razones que forman parte de los datos:

yaml
- id: disagreement
  kind: distributional
  schema: offensiveness
  max_distance: 0.15     # optional
  groups_by: age_band    # optional: a prestudy question whose answer groups the annotators

Cada ítem etiquetado por varias personas (humans.distribution_k, 5 por defecto) tiene una distribución de etiquetas humanas. El contrato informa de la distancia de Jensen-Shannon media entre la distribución de la máquina y la de las personas, con un intervalo bootstrap. También informa de un techo de ruido, que es la misma distancia entre dos mitades aleatorias de las personas en cada ítem. Una máquina que está más cerca de las personas de lo que están ellas entre sí está tan cerca como permiten los datos.

La distribución de la máquina son sus probabilidades cuando la fuente las da (modelos de decisión, k_sample, logprob), o su etiqueta como vector one-hot. El contrato se cumple cuando el extremo superior del intervalo es como mucho max_distance o, sin max_distance, en cuanto hay 20 ítems etiquetados por 3 o más personas. Cuando el extremo inferior del intervalo está por encima de max_distance, el estado es infeasible, ya que más ítems solo estrechan el intervalo en torno a una distancia que es demasiado grande.

Con groups_by, las mismas cifras se dan por grupo de anotadores. La distribución de cada grupo en un ítem se construye solo con las personas de ese grupo, a partir de sus respuestas a la pregunta previa al estudio indicada, y si nadie respondió a la pregunta, el contrato lo indica.

threshold_legacy

threshold_legacy acepta etiquetas de máquina por encima de una confianza fija y no ejecuta ninguna prueba estadística:

yaml
- id: old-rule
  kind: threshold_legacy
  schema: sentiment
  threshold: 0.8

potato label migrate-config escribe este contrato para icl_labeling, con el antiguo confidence_threshold, de modo que una configuración traducida se comporta como antes, y también puedes escribirlo a mano. El certificado marca estas etiquetas como no certificadas e informa de su error medido sobre las etiquetas de calibración, y la exportación les da el estado accepted_uncertified.

Resultados de los estudios de ejemplo

Los tres estudios de ejemplo de examples/labeling-engine/ se ejecutaron con las fuentes de LLM, de juez y de visión apuntando a Gemma 12B en un servidor vLLM, en lugar de a los modelos de Ollama que usan las configuraciones del repositorio. El README de cada ejemplo muestra el bloque de fuente que se cambió, y con los valores por defecto de Ollama las cifras serán distintas.

  • Sentimiento en texto (481 reseñas, Gemma 12B con confianza logprob como último nivel). selective_risk al 10% y 0.9 se cumplió con 165 etiquetas humanas, y se aceptaron 316 etiquetas de máquina. Su error medido frente a las etiquetas verdaderas fue del 7.6%, y los intervalos PPI cubrieron la prevalencia verdadera de las tres etiquetas.
  • Imágenes (128 imágenes de COCO, YOLOv8n y Gemma 12B como modelo de visión). Se certificó una etiqueta de si hay una persona al 10%. El contrato de cajas se quedó en insufficient, porque las cajas de YOLOv8n eran incorrectas en el 32% de las imágenes dev con IoU 0.5.
  • Trazas de agentes (288 trazas, Gemma 12B como juez). El juez acertó en el 80% de las trazas, pero su confianza fue 1.0 en todas, así que selective_risk resultó inviable. La prueba del anotador alternativo quedó en insuficiente, con la máquina en 0.82 frente al 0.93 de las personas. PPI estimó el éxito de la tarea en 0.66 [0.57, 0.76], cuando el valor verdadero era 0.60 y el juez solo decía 0.76, 16 puntos por encima.

Lecturas adicionales

Para los detalles de implementación, consulta la documentación del código fuente.

Referencias

  1. Angelopoulos, A. N., Bates, S., Candès, E. J., et al. (2025). Learn then test: Calibrating predictive algorithms to achieve risk control. The Annals of Applied Statistics. https://doi.org/10.1214/24-AOAS1998
  2. Angelopoulos, A. N., Bates, S., Fannjiang, C., et al. (2023). Prediction-powered inference. Science, 382(6671). https://doi.org/10.1126/science.adi6000
  3. Angelopoulos, A. N., Duchi, J. C., and Zrnic, T. (2023). PPI++: Efficient prediction-powered inference. arXiv. https://arxiv.org/abs/2311.01453
  4. Calderon, N., Reichart, R., and Dror, R. (2025). The alternative annotator test for LLM-as-a-judge: How to statistically justify replacing human annotators with LLMs. Proceedings of ACL 2025. https://aclanthology.org/2025.acl-long.782/