Skip to content

Modo Individual

Etiqueta conjuntos de datos completos con un solo anotador colaborando con un LLM a través de un flujo de trabajo inteligente de 12 fases.

Modo Individual

Nuevo en v2.3.0

Los proyectos de anotación tradicionales requieren múltiples anotadores, cálculo de acuerdo entre anotadores, rondas de adjudicación y una sobrecarga significativa de coordinación. Para muchos equipos de investigación, este es el principal cuello de botella: no la interfaz de anotación, sino la logística de contratar, capacitar y gestionar un equipo.

El Modo Individual reemplaza el paradigma de múltiples anotadores con un solo experto humano colaborando con un LLM. El humano proporciona etiquetas de alta calidad en un subconjunto pequeño y estratégicamente seleccionado. El LLM aprende de esas etiquetas, propone etiquetas para el resto, y el humano revisa solo los casos donde el LLM es incierto o probablemente incorrecto. Un flujo de trabajo de 12 fases orquesta este proceso automáticamente.

En pruebas internas, el Modo Individual logró un acuerdo superior al 95% con pipelines completos de múltiples anotadores, requiriendo solo el 10-15% del total de etiquetas humanas.

El Flujo de Trabajo de 12 Fases

El Modo Individual progresa a través de 12 fases. El sistema avanza automáticamente basándose en umbrales configurables, aunque también puedes activar transiciones manualmente desde el panel de administración.

Fase 1: Anotación Semilla

El anotador humano etiqueta un conjunto semilla inicial. Potato selecciona instancias diversas y representativas usando clustering basado en embeddings para maximizar la cobertura de la distribución de datos.

Tamaño semilla predeterminado: 50 instancias (configurable mediante seed_count)

Fase 2: Calibración Inicial del LLM

El LLM recibe las anotaciones semilla como ejemplos few-shot y etiqueta un lote de calibración. Potato compara las predicciones del LLM contra las etiquetas semilla reservadas para establecer una precisión de referencia.

Fase 3: Análisis de Confusión

Potato identifica patrones sistemáticos de desacuerdo entre el humano y el LLM. Construye una matriz de confusión y presenta los tipos de error más comunes (por ejemplo, "el LLM etiqueta neutral como positivo el 40% de las veces").

Fase 4: Refinamiento de Directrices

Basándose en el análisis de confusión, Potato genera directrices de anotación refinadas para el LLM. El humano revisa y edita estas directrices antes de que se apliquen. Este es un paso interactivo donde el anotador puede agregar ejemplos, aclarar casos límite y ajustar definiciones de etiquetas.

Fase 5: Generación de Funciones de Etiquetado

Inspirado en el framework ALCHEmist, Potato genera funciones de etiquetado programáticas a partir de las anotaciones existentes. Estas son reglas simples basadas en patrones (por ejemplo, "si el texto contiene 'excelente' y no hay negación, etiquetar como positivo") que pueden etiquetar instancias fáciles con alta precisión, reservando el esfuerzo humano y del LLM para casos más difíciles.

Fase 6: Etiquetado Activo

El humano etiqueta instancias adicionales seleccionadas por aprendizaje activo. Potato prioriza instancias donde el LLM es más incierto, donde las funciones de etiquetado no están de acuerdo, o donde la instancia está lejos de los ejemplos de entrenamiento existentes en el espacio de embeddings.

Fase 7: Bucle de Refinamiento Automatizado

El LLM re-etiqueta el conjunto de datos completo con directrices y ejemplos few-shot actualizados. Potato compara contra todas las etiquetas humanas y activa otro ciclo de análisis de confusión y refinamiento de directrices si la precisión está por debajo del umbral.

Fase 8: Exploración de Desacuerdos

El humano revisa todas las instancias donde el LLM y las funciones de etiquetado no están de acuerdo. Estos son típicamente los ejemplos más informativos y difíciles. Las etiquetas del humano en estos casos proporcionan el mayor valor marginal.

Fase 9: Síntesis de Casos Límite

Potato usa el LLM para generar casos límite sintéticos basados en los patrones de confusión identificados. El humano etiqueta estos ejemplos sintéticos, que luego se agregan al contexto de entrenamiento del LLM para mejorar el rendimiento en los casos más difíciles.

Fase 10: Escalamiento en Cascada por Confianza

El LLM asigna puntuaciones de confianza a cada instancia no etiquetada restante. Las instancias se escalan al humano en orden descendente de dificultad (confianza ascendente). El humano etiqueta hasta que las métricas de calidad se estabilizan.

Fase 11: Optimización de Prompts

Inspirado en DSPy, Potato ejecuta optimización automatizada de prompts usando las etiquetas humanas acumuladas como conjunto de validación. Prueba múltiples variaciones de prompts (redacción de instrucciones, orden de ejemplos, cadena de pensamiento vs. directo) y selecciona el prompt con mejor rendimiento.

Fase 12: Validación Final

El humano realiza una revisión final de una muestra aleatoria de las instancias etiquetadas por el LLM. Si la precisión cumple con el umbral, el conjunto de datos está completo. Si no, el sistema regresa a la Fase 6.


Configuración

Inicio Rápido

Una configuración mínima del Modo Individual:

yaml
task_name: "Sentiment Classification"
task_dir: "."
 
data_files:
  - "data/reviews.jsonl"
 
item_properties:
  id_key: id
  text_key: text
 
solo_mode:
  enabled: true
 
  # LLM provider
  llm:
    endpoint_type: openai
    model: "gpt-4o"
    api_key: ${OPENAI_API_KEY}
 
  # Basic thresholds
  seed_count: 50
  accuracy_threshold: 0.92
  confidence_threshold: 0.85
 
annotation_schemes:
  - annotation_type: radio
    name: sentiment
    labels:
      - Positive
      - Neutral
      - Negative
 
output_annotation_dir: "output/"
output_annotation_format: "jsonl"

Referencia Completa de Configuración

yaml
solo_mode:
  enabled: true
 
  # LLM configuration
  llm:
    endpoint_type: openai        # openai, anthropic, ollama, vllm
    model: "gpt-4o"
    api_key: ${OPENAI_API_KEY}
    temperature: 0.1             # low temperature for consistency
    max_tokens: 256
 
  # Phase control
  phases:
    seed:
      count: 50                  # number of seed instances
      selection: diversity        # diversity, random, or stratified
      embedding_model: "all-MiniLM-L6-v2"
 
    calibration:
      batch_size: 100
      holdout_fraction: 0.2      # fraction of seed used for validation
 
    confusion_analysis:
      min_samples: 30
      significance_threshold: 0.05
 
    guideline_refinement:
      auto_suggest: true         # LLM suggests guideline edits
      require_approval: true     # human must approve changes
 
    labeling_functions:
      enabled: true
      max_functions: 20
      min_precision: 0.90        # only keep high-precision rules
      min_coverage: 0.01         # must cover at least 1% of data
 
    active_labeling:
      batch_size: 25
      strategy: uncertainty       # uncertainty, diversity, or hybrid
      max_batches: 10
 
    refinement_loop:
      max_iterations: 3
      improvement_threshold: 0.02
 
    disagreement_exploration:
      max_instances: 200
      sort_by: confidence_gap
 
    edge_case_synthesis:
      enabled: true
      count: 50
      diversity_weight: 0.3
 
    confidence_escalation:
      escalation_budget: 200     # max instances to escalate
      batch_size: 25
      stop_when_stable: true     # stop if last batch accuracy is 100%
 
    prompt_optimization:
      enabled: true
      candidates: 10             # number of prompt variants to try
      metric: f1_macro
      search_strategy: bayesian  # bayesian, grid, or random
 
    final_validation:
      sample_size: 100
      min_accuracy: 0.92
      fallback_phase: 6          # go back to Phase 6 if validation fails
 
  # Instance prioritization across phases
  prioritization:
    pools:
      - name: uncertain
        weight: 0.30
        description: "LLM confidence below threshold"
      - name: disagreement
        weight: 0.25
        description: "LLM and labeling functions disagree"
      - name: boundary
        weight: 0.20
        description: "Near decision boundary in embedding space"
      - name: novel
        weight: 0.10
        description: "Far from all existing labeled examples"
      - name: error_pattern
        weight: 0.10
        description: "Matches known confusion patterns"
      - name: random
        weight: 0.05
        description: "Random sample for calibration"

Capacidades Principales

Análisis de Confusión

Después de cada ronda de etiquetado, Potato construye una matriz de confusión entre etiquetas humanas y del LLM. El panel de administración muestra:

  • Precisión, recall y F1 por clase desde la perspectiva del LLM
  • Pares de confusión más comunes (por ejemplo, "neutral clasificado incorrectamente como positivo: 23 instancias")
  • Instancias de ejemplo para cada par de confusión
  • Gráficos de tendencia que muestran la mejora a lo largo de las rondas de refinamiento

Accede al análisis de confusión programáticamente:

bash
python -m potato.solo confusion --config config.yaml

Salida:

text
Confusion Analysis (Round 2)
============================
Overall Accuracy: 0.87 (target: 0.92)

Top Confusion Pairs:
  neutral -> positive:  23 instances (15.3%)
  negative -> neutral:  11 instances (7.3%)
  positive -> neutral:   5 instances (3.3%)

Per-Class Performance:
  Positive:  P=0.91  R=0.94  F1=0.92
  Neutral:   P=0.78  R=0.71  F1=0.74
  Negative:  P=0.93  R=0.88  F1=0.90

Bucle de Refinamiento Automatizado

El bucle de refinamiento itera entre el etiquetado del LLM, el análisis de confusión y las actualizaciones de directrices. Cada iteración:

  1. El LLM etiqueta el conjunto de datos completo con las directrices actuales
  2. Potato compara contra todas las etiquetas humanas disponibles
  3. Si la precisión está por debajo del umbral, se ejecuta el análisis de confusión
  4. El LLM propone ediciones a las directrices basándose en los patrones de error
  5. El humano revisa y aprueba las ediciones
  6. El ciclo se repite (hasta max_iterations)
yaml
solo_mode:
  llm:
    endpoint_type: anthropic
    model: "claude-sonnet-4-20250514"
    api_key: ${ANTHROPIC_API_KEY}
 
  phases:
    refinement_loop:
      max_iterations: 3
      improvement_threshold: 0.02    # stop if improvement is less than 2%

Funciones de Etiquetado (Inspiradas en ALCHEmist)

Potato genera funciones de etiquetado ligeras a partir de patrones observados en las anotaciones humanas. Estas no son llamadas al LLM; son reglas rápidas y deterministas.

Ejemplo de funciones de etiquetado generadas:

python
# Auto-generated labeling function 1
# Precision: 0.96, Coverage: 0.08
def lf_strong_positive_words(text):
    positive = {"excellent", "amazing", "fantastic", "outstanding", "perfect"}
    if any(w in text.lower() for w in positive):
        if not any(neg in text.lower() for neg in {"not", "never", "no"}):
            return "Positive"
    return None  # abstain
 
# Auto-generated labeling function 2
# Precision: 0.93, Coverage: 0.05
def lf_explicit_negative(text):
    negative = {"terrible", "awful", "horrible", "worst", "disgusting"}
    if any(w in text.lower() for w in negative):
        return "Negative"
    return None

Configura el comportamiento de las funciones de etiquetado:

yaml
solo_mode:
  phases:
    labeling_functions:
      enabled: true
      max_functions: 20
      min_precision: 0.90
      min_coverage: 0.01
      types:
        - keyword_match
        - regex_pattern
        - length_threshold
        - embedding_cluster

Explorador de Desacuerdos

El explorador de desacuerdos presenta instancias donde diferentes señales entran en conflicto. Para cada instancia, el anotador ve:

  • La etiqueta predicha por el LLM y su confianza
  • Votos de las funciones de etiquetado (si los hay)
  • Vecinos etiquetados más cercanos en el espacio de embeddings
  • El texto/contenido sin procesar

Esta es la actividad de anotación de mayor valor: cada etiqueta resuelve una ambigüedad genuina.

yaml
solo_mode:
  phases:
    disagreement_exploration:
      max_instances: 200
      sort_by: confidence_gap     # or "lf_disagreement" or "random"
      show_llm_reasoning: true    # display LLM's chain-of-thought
      show_nearest_neighbors: 3   # show 3 nearest labeled examples

Escalamiento en Cascada por Confianza

Después de que la mayor parte del conjunto de datos es etiquetado por el LLM, Potato clasifica todas las instancias etiquetadas por el LLM según su confianza y escala las menos confiables al humano. Esto continúa en lotes hasta que la calidad se estabiliza.

yaml
solo_mode:
  phases:
    confidence_escalation:
      escalation_budget: 200
      batch_size: 25
      stop_when_stable: true
      stability_window: 3        # stop if last 3 batches are all correct

Priorización de Instancias Multi-Señal

En todas las fases que involucran etiquetado humano, Potato usa un sistema de pools ponderados para seleccionar las instancias más informativas. Seis pools alimentan una cola de prioridad unificada:

yaml
solo_mode:
  prioritization:
    pools:
      - name: uncertain
        weight: 0.30
      - name: disagreement
        weight: 0.25
      - name: boundary
        weight: 0.20
      - name: novel
        weight: 0.10
      - name: error_pattern
        weight: 0.10
      - name: random
        weight: 0.05
  • uncertain: Instancias donde la confianza del LLM está por debajo de confidence_threshold
  • disagreement: Instancias donde el LLM y las funciones de etiquetado producen etiquetas diferentes
  • boundary: Instancias cerca del límite de decisión en el espacio de embeddings
  • novel: Instancias lejos de cualquier ejemplo etiquetado existente
  • error_pattern: Instancias que coinciden con patrones de confusión conocidos de rondas anteriores
  • random: Una pequeña muestra aleatoria para mantener la calibración y detectar puntos ciegos

Síntesis de Casos Límite

Potato usa el LLM para generar ejemplos sintéticos que apuntan a debilidades conocidas:

yaml
solo_mode:
  phases:
    edge_case_synthesis:
      enabled: true
      count: 50
      diversity_weight: 0.3
      confusion_pairs:            # focus on these error types
        - ["neutral", "positive"]
        - ["negative", "neutral"]

El LLM genera ejemplos que son ambiguos entre los pares de etiquetas especificados. El humano los etiqueta, y estas etiquetas se agregan al contexto few-shot para las rondas subsiguientes de etiquetado del LLM.

Optimización de Prompts (Inspirada en DSPy)

En la Fase 11, Potato ejecuta optimización automatizada de prompts para encontrar el mejor formato de instrucción para el LLM:

yaml
solo_mode:
  phases:
    prompt_optimization:
      enabled: true
      candidates: 10
      metric: f1_macro
      search_strategy: bayesian
      variations:
        - instruction_style      # formal vs. conversational
        - example_ordering       # random, by-class, by-difficulty
        - reasoning_mode         # direct, chain-of-thought, self-consistency
        - example_count          # 3, 5, 10, 15 few-shot examples

Monitoreo del Progreso

El panel de administración muestra el progreso del Modo Individual en tiempo real:

  • Fase actual y progreso dentro de cada fase
  • Etiquetas humanas completadas vs. presupuesto total
  • Precisión del LLM a lo largo del tiempo (por ronda)
  • Cobertura y precisión de las funciones de etiquetado
  • Histograma de distribución de confianza
  • Tiempo estimado de finalización

Accede desde la línea de comandos:

bash
python -m potato.solo status --config config.yaml
text
Solo Mode Status
================
Current Phase: 6 (Active Labeling) - Batch 3/10
Human Labels: 142 / ~300 estimated total
LLM Accuracy: 0.89 (target: 0.92)
LF Coverage: 0.23 (labeling functions cover 23% of data)
Dataset Size: 10,000 instances
  - Human labeled: 142
  - LF labeled: 2,300
  - LLM labeled: 7,558
  - Unlabeled: 0

Cuándo Usar el Modo Individual vs. Múltiples Anotadores Tradicional

Usa el Modo Individual cuando:

  • Tienes un experto del dominio que puede proporcionar etiquetas de alta calidad
  • El presupuesto o la logística impiden contratar múltiples anotadores
  • La tarea tiene categorías claras y bien definidas
  • Necesitas etiquetar un conjunto de datos grande (más de 1,000 instancias)
  • La velocidad importa más que medir el acuerdo entre anotadores

Usa múltiples anotadores tradicional cuando:

  • Necesitas estadísticas de acuerdo entre anotadores para publicación
  • La tarea es altamente subjetiva (por ejemplo, ofensividad, humor)
  • Necesitas estudiar patrones de desacuerdo entre anotadores
  • Los requisitos regulatorios exigen múltiples anotadores independientes
  • El espacio de etiquetas es complejo o está en evolución (las directrices de anotación aún se están desarrollando)

Enfoque híbrido: Usa el Modo Individual para el etiquetado masivo inicial, luego asigna un segundo anotador a una muestra aleatoria del 10-20% para calcular estadísticas de acuerdo. Esto te da la eficiencia del Modo Individual con la garantía de calidad de la verificación con múltiples anotadores.

yaml
solo_mode:
  enabled: true
  # ... solo mode config ...
 
  # Hybrid: assign verification sample to second annotator
  verification:
    enabled: true
    sample_fraction: 0.15
    annotator: "reviewer_1"

Lectura Adicional

Para detalles de implementación, consulta la documentación fuente.