Configuración del motor de etiquetado
Todas las claves del bloque labeling_engine: fuentes y métodos de confianza, grupos de personas, gasto en crowdsourcing, presupuestos, límites de ejecución, funciones y lo que rechaza la validación.
Todo lo que hace el motor de etiquetado se configura en un único bloque labeling_engine. Un bloque no válido detiene el servidor al arrancar y enumera todos los problemas a la vez. Para que los anotadores reciban las peticiones del motor, define también assignment_strategy: engine. Definir esa estrategia sin un motor activado es un error de validación.
El bloque tiene estas secciones, cada una explicada más abajo:
assignment_strategy: engine
labeling_engine:
enabled: true
schemas: [sentiment] # default: every scheme a source can label
sources: []
cascade: [laya, gemma] # default: the first source alone
contracts: []
humans: {}
crowd: {}
budgets: {}
runtime: {}
features: {}
redaction: {}
distill: {}Claves de primer nivel
Cinco claves van directamente bajo labeling_engine:
| Clave | Valor por defecto | Significado |
|---|---|---|
enabled | false | Activa el motor. Un motor activado necesita al menos una fuente. |
schemas | todos | Los esquemas de anotación que etiqueta el motor. Con assignment_strategy: engine, un esquema que se deja fuera solo se responde en los ítems que el motor envía a las personas para sus propios esquemas, no en todos los ítems, y la validación lo advierte. Un esquema que ninguna fuente puede etiquetar (el texto libre, por ejemplo) no puede estar en el motor, así que con esta estrategia nunca se responde en todos los ítems. Usa otra estrategia de asignación si tiene que responderse. |
sources | [] | Los modelos. Consulta Fuentes. |
cascade | primera fuente | Ids de las fuentes en el orden en que se prueban. Las personas van después de la última. |
contracts | [] | Lo que deben cumplir las etiquetas. Consulta Contratos. |
Fuentes
Una fuente es un modelo, o un conjunto de etiquetas que ya existe, que propone una etiqueta y una confianza para cada ítem. Cada fuente tiene un id único y un kind, y una clave desconocida en una fuente es un error:
| Clave | Valor por defecto | Significado |
|---|---|---|
id | obligatorio | Nombre que se usa en cascade, en el registro de llamadas y en el certificado. |
kind | obligatorio | Uno de llm, vlm, decision, detector, judge, jury, trained, static, fixture, asr, lf, simulator. |
endpoint_type | obligatorio para llm, vlm, decision, judge | El endpoint de IA, como vllm, openai, anthropic, gemini, ollama, openrouter, openai_vision, ollama_vision, laya o systemone. detector usa yolo por defecto. |
model | el del endpoint | Nombre del modelo. |
base_url | ninguno | URL del servidor para endpoints autoalojados o compatibles con OpenAI. |
api_key | ninguno | Nunca entra en el hash de una versión y nunca se exporta. Se sustituye ${ENV_VAR}. |
temperature | 0.0 | De 0 a 2. |
max_tokens | 256 | Límite de tokens de salida por llamada. |
timeout | el del endpoint | Segundos por llamada. |
prompt | generado a partir del esquema | Plantilla del prompt. Cambiarla crea una nueva versión de la fuente. |
confidence | {method: auto} | Cómo expresa la fuente su confianza. Consulta Métodos de confianza. |
concurrency | runtime.concurrency | Llamadas en paralelo a esta fuente. |
schemas | todos los esquemas del motor | Limita la fuente a estos esquemas. |
options | {} | Opciones específicas de cada tipo, que se enumeran más abajo. |
judge | {} | Solo judge. Las mismas opciones que options, bajo su propia clave, y options prevalece cuando ambas definen una. |
members | ninguno | Solo jury. Al menos otros dos ids de fuente. |
aggregation | plurality | Solo jury. La mayoría simple es la única regla. |
field / predictions_file | ninguno | Solo static. Dónde están las etiquetas existentes. El campo contiene {scheme: label}, o una etiqueta sin más cuando la fuente etiqueta un solo esquema. Un campo con la forma equivocada en todos los ítems hace fallar la ejecución con un mensaje que lo nombra. |
error_rate, seed | ninguno | Solo fixture. Una fuente sintética con una tasa de error conocida, para pruebas. |
revision | ninguno | Una revisión del modelo que se registra en la versión, por ejemplo el hash de un checkpoint. |
Todo lo que puede cambiar una respuesta (modelo, prompt, temperatura, opciones) entra en el hash de versión de la fuente. Una versión nueva marca como stale todos los contratos que dependen de la fuente.
Una respuesta que no es un valor que el esquema pueda contener, como una etiqueta que no está en su lista, un campo numérico que no es un número o una lista en un esquema de una opción entre N, se registra como error y nunca como etiqueta, y el mensaje de la ejecución cuenta esos errores. Un ítem cuyas llamadas fallan se vuelve a pedir en ejecuciones posteriores, como mucho tres veces por versión de la fuente, y después espera a que cambie la fuente (una clave o un prompt corregidos son una versión nueva). Una ejecución en la que falla una fuente no detiene los demás niveles. El siguiente nivel etiqueta todos los ítems, y potato label run termina con estado 1 y nombra la fuente que falló.
Métodos de confianza
Las reglas de aceptación del motor aplican umbrales a la confianza de cada predicción, así que la forma en que una fuente expresa su confianza decide cuánto puede aceptar el motor. confidence.method admite uno de cinco valores:
confidence.method | Se aplica a | Qué hace |
|---|---|---|
verbalized | llm, vlm, judge | El modelo indica un valor de 0 a 100 en su respuesta. Una llamada, y el método menos fiable. |
k_sample | llm | samples respuestas (5 por defecto) con sample_temperature (0.7 por defecto). La etiqueta es la respuesta más frecuente y la confianza es su proporción. Cuesta k llamadas. |
logprob | llm | Las etiquetas se identifican con letras y el modelo responde con una letra, y la confianza se lee de las probabilidades del primer token. Una llamada, y normalmente el mejor calibrado. Necesita un backend que devuelva logprobs (vLLM, compatible con OpenAI) y como mucho 20 etiquetas, y un esquema con más es un error de validación. |
native | decision, detector, trained | Las probabilidades propias del modelo. En una fuente llm es un error de validación. |
auto | todos | native cuando la fuente lo tiene y, si no, verbalized. |
Opciones específicas de cada tipo
Cinco tipos de fuente leen opciones propias:
decisioncubre Laya dentro del proceso, o cualquier servidor/v1/systemone, como Jev alojado u OpenJev. Una sola pasada hacia delante devuelve una probabilidad para cada opción, y funciona con esquemasradio,select,likertyslider.endpoint_typetiene que serlayaosystemone, ysystemonenecesitabase_url, la raíz del servidor (también se acepta una URL que termine en/v1/systemone). En ambos casos el estado se envía como{"text": ...}, así que un mismo checkpoint da las mismas respuestas dentro del proceso y detrás delaya-serve, yoptions: {state_key: ""}envía la cadena sin más. En las escalas de valoración (likert,slider), las puntuaciones de Laya apenas siguen la escala, así que revisa unos cuantos ítems antes de confiar en él. El endpointlayadentro del proceso necesitapip install 'potato-annotation[decision]'.detectorlee cajas de un detector de objetos en esquemasimage_annotation.keep_threshold(0.35) fija la puntuación a partir de la cual, inclusive, una caja forma parte de la predicción. Las cajas entrecandidate_threshold(0.05) ykeep_thresholdreducen la confianza de la imagen.label_mapasigna las clases del detector a etiquetas del esquema, y las clases sin asignar se ignoran.image_fieldnombra el campo del ítem que tiene la ruta o la URL de la imagen. Las rutas se resuelven igual que en la página de anotación, con/media/x.jpgbajo elmedia_directoryde la tarea y una ruta relativa bajotask_dir.judgeadmiterubric(por defecto, la descripción del esquema),fields(los campos del ítem que se muestran al juez, en orden) yswap_order, que pregunta dos veces con el orden de las etiquetas invertido y convierte un veredicto que cambia en una abstención. En los esquemas de trazas de agentes (process_reward,trajectory_eval, ...) el juez etiqueta cada paso.vlmusa un endpoint de visión (openai_vision,anthropic_vision,ollama_vision). Para un modelo autoalojado detrás de un servidor compatible con OpenAI, usaopenai_visionconbase_url.trainedadmiteartifact_dir,trainer(sklearn-textpor defecto) yrun_id. Normalmente esta fuente la crea la destilación, no una configuración escrita a mano.
humans
El bloque humans define quién etiqueta y cómo los muestrea el motor:
| Clave | Valor por defecto | Significado |
|---|---|---|
pools | [team] | Quién etiqueta: team, crowd, solo. |
calibration_rate | auto | Proporción de ítems muestreados para la calibración ciega. auto elige una tasa a partir de las proyecciones de los contratos, con suficientes etiquetas por clase para poder probarlas, como mucho la mitad de un estudio pequeño y una quinta parte de uno de más de 1000 ítems. |
dev_fraction | 0.5 | Proporción de etiquetas de calibración que se usa para elegir umbrales. El resto los pone a prueba. |
min_calibration_per_class | 10 | Mínimo por clase antes de probar los contratos por clase. |
audit_rate | 0.02 | Proporción de etiquetas de máquina recién aceptadas que vuelve a las personas, a ciegas, para vigilar la deriva. |
overlap | 0.0 | Proporción de ítems de calibración que etiquetan varias personas. |
overlap_k | 3 | Personas por ítem solapado. El contrato no_worse_than_human necesita 3. |
distribution_k | 5 | Personas por ítem para los contratos distributional. |
truth | majority | Cómo las etiquetas de varias personas sobre un ítem se convierten en la etiqueta con la que se ponen a prueba los contratos, majority o dawid_skene. |
verify_visibility | shown | Si una petición de verificación muestra la respuesta de la máquina (shown) o no (blind). |
crowd
El bloque crowd se aplica cuando crowd está en humans.pools, y Prolific es la única plataforma de crowdsourcing que puede manejar el motor:
| Clave | Valor por defecto | Significado |
|---|---|---|
provider | prolific | La plataforma de crowdsourcing. |
study_id | ninguno | El estudio de Prolific que se redimensiona. |
reward_usd | ninguno | Recompensa por plaza, para las proyecciones de coste. |
per_worker_quota | 20 | Peticiones por trabajador. Las plazas son ceil(open requests / quota). |
El reclutamiento en crowdsourcing es una simulación por defecto, y el planificador informa de lo que haría. Gastar dinero necesita features.crowd_live_spend: true y un tope budgets.human_usd, y una configuración que activa el gasto real sin el tope se rechaza. Crowdsourcing explica cómo configurar el propio estudio de Prolific.
budgets
El bloque budgets detiene el gasto antes de que se supere un límite:
| Clave | Significado |
|---|---|
model_usd | Deja de llamar a modelos de pago cuando se ha gastado esta cantidad. Cada llamada reserva primero su coste previsto. Los modelos sin precio, y los modelos autoalojados en localhost, no están limitados por ella. |
human_usd | Techo del gasto en crowdsourcing. Obligatorio para el gasto real en crowdsourcing. |
human_labels | Máximo de peticiones a personas que puede abrir el motor, contadas al abrir cada petición. |
runtime
El bloque runtime controla los lotes, la concurrencia y cuánto tiempo puede tener una persona asignada una petición:
| Clave | Valor por defecto | Significado |
|---|---|---|
batch_size | 32 | Ítems por bloque confirmado. Una ejecución interrumpida se reanuda en el siguiente bloque sin repetir llamadas. |
concurrency | 4 | Llamadas en paralelo por fuente. El concurrency propio de una fuente tiene prioridad. |
cache | true | Reutiliza las respuestas a peticiones idénticas de la misma versión de la fuente. |
retries | 2 | Intentos adicionales tras un tiempo de espera agotado, un error de conexión, un 429 o un 5xx. Cada intento se registra. |
planner_interval | 30 | Segundos entre pasadas del planificador en el servidor. |
hold_minutes | 60 | Minutos que una persona puede tener asignada una petición sin responder antes de que vuelva a la reserva. El ítem también desaparece de su página, así que una pestaña que se queda abierta no puede responderlo más tarde. |
features
Todas las funciones están desactivadas por defecto excepto drift:
| Clave | Qué activa |
|---|---|
drift | Activada por defecto. Actúa según los resultados de las auditorías. Cuando las auditorías muestran que la tasa de error de las etiquetas aceptadas está por encima del objetivo, el contrato pasa a violated, las etiquetas de máquina de ese esquema dejan de aceptarse y se extraen etiquetas de calibración nuevas. Cada certificación inicia una nueva secuencia de auditorías, así que volver a certificar tras una corrección restablece la aceptación. Ponla en false para limitarse a informar del incumplimiento, y entonces el contrato indica «met, audits breached». |
distill | Entrena un modelo con las etiquetas del estudio y lo pone el primero en la cascada (consulta distill). |
optimize | Hace que cada pasada del planificador puntúe todos los subconjuntos de la cascada con las etiquetas dev e informe del más barato que mantiene la cobertura de los contratos, en GET /api/engine/v1/schemes/<name>/optimize. No se aplica nada, porque adoptar una cascada es un cambio de configuración y una nueva certificación. |
crowd_recruit | Deja que el planificador dimensione el estudio de Prolific, como simulación salvo que crowd_live_spend esté activado. |
crowd_live_spend | Modifica de verdad el estudio de Prolific. Necesita el grupo crowd y budgets.human_usd. |
pii_redaction | Enmascara correos electrónicos, URL, direcciones IP, números de tarjeta, SSN, números de teléfono y @usuarios antes de que el texto vaya a una API de terceros. El registro de llamadas guarda lo que se enmascaró como categorías y hashes, nunca el texto. |
payload_capture | Guarda los prompts y las respuestas completos en <task_dir>/engine_payloads/. Desactivada por defecto, y el registro de llamadas solo guarda hashes. |
redaction
redaction.categories indica cuáles de email, url, ip, card, ssn, phone y handle se enmascaran, y por defecto son todas. El enmascaramiento solo se aplica con features.pii_redaction, y solo a las API de terceros. Los tipos de endpoint autoalojados (vllm, ollama, laya, yolo, ...) no se enmascaran se ejecuten donde se ejecuten, y tampoco ningún endpoint cuyo base_url esté en la misma máquina.
distill
Con features.distill activado, el motor entrena un modelo barato con las etiquetas del estudio y lo pone el primero en la cascada:
| Clave | Valor por defecto | Significado |
|---|---|---|
trainer | sklearn-text | Un entrenador de potato/training. |
min_labels | 200 | Solo entrena cuando existen al menos estas etiquetas. |
include_silver | true | Entrena también con etiquetas de máquina que certificó un contrato, marcadas como silver. |
every | 2.0 | Vuelve a entrenar cuando el número de etiquetas ha crecido en este factor. |
Los ítems de las particiones cert y de auditoría nunca entran en el conjunto de entrenamiento, así que el modelo destilado nunca se pone a prueba con etiquetas con las que se entrenó.
Validación
potato validate config.yaml comprueba el bloque labeling_engine junto con el resto de la configuración, y cada error nombra su clave, por ejemplo labeling_engine.sources[1].kind must be one of ... o labeling_engine.contracts[0].error is required for selective_risk. La validación también rechaza:
- una clave de contrato que el tipo de contrato no lee, como una errata en
error; - un contrato sobre un esquema que ninguna fuente de la cascada puede etiquetar, con el motivo de cada fuente;
- un contrato sobre un esquema que el motor no puede puntuar (texto libre, por pares);
- una fuente
decisioncuyoendpoint_typeno es un modelo de decisión, y una fuentellm,vlmojudgecuyoendpoint_typesí lo es; y no_worse_than_humanconhumans.overlap_kpor debajo de 3.
La validación también avisa cuando budgets.human_labels es demasiado pequeño para certificar un contrato selective_risk aunque todas las respuestas de la máquina fueran correctas. Sube el presupuesto, o relaja error, hasta que desaparezca el aviso.
Lecturas adicionales
- El motor de etiquetado
- Contratos del motor de etiquetado
- Línea de comandos, REST API, herramientas MCP y SDK
- Soporte de IA, para los tipos de endpoint que las fuentes comparten con el resto de Potato
Para los detalles de implementación, consulta la documentación del código fuente.