Skip to content
Tutorials12 min read

Solo Mode: Cómo Un Anotador Puede Etiquetar 10,000 Ejemplos

Tutorial paso a paso sobre el uso de Solo Mode de Potato para etiquetar eficientemente grandes conjuntos de datos con colaboración humano-LLM, reduciendo el costo de anotación hasta un 90%.

Potato Team·

Solo Mode: Cómo Un Anotador Puede Etiquetar 10,000 Ejemplos

Tienes 10,000 reseñas de productos para etiquetar por sentimiento (Positivo, Neutral, Negativo). Contratar tres anotadores para etiquetar todo tomaría semanas y costaría miles de dólares. Con Solo Mode, un único experto en el dominio puede lograr una calidad comparable etiquetando solo 500-1,000 instancias mientras un LLM se encarga del resto -- con el humano revisando cada decisión donde el LLM tiene dudas.

Este tutorial recorre todo el proceso de principio a fin.


Lo Que Necesitarás

  • Potato 2.3.0+ con los extras de Solo Mode: pip install potato-annotation[solo]
  • Una clave de API de OpenAI o Anthropic (para el componente LLM)
  • Tu conjunto de datos en formato JSONL
  • Un anotador con conocimiento del dominio (puedes ser tú mismo)

Paso 1: Prepara Tus Datos

Crea data/reviews.jsonl con una reseña por línea:

json
{"id": "rev_001", "text": "Absolutely love this product! Best purchase I've made all year.", "source": "amazon"}
{"id": "rev_002", "text": "It works fine. Nothing special but gets the job done.", "source": "amazon"}
{"id": "rev_003", "text": "Broke after two weeks. Complete waste of money.", "source": "amazon"}
{"id": "rev_004", "text": "The quality is decent for the price point. I might buy again.", "source": "amazon"}
{"id": "rev_005", "text": "Arrived damaged and customer service was unhelpful.", "source": "amazon"}

Para este tutorial, imagina que este archivo contiene 10,000 reseñas.


Paso 2: Crea la Configuración

Crea config.yaml:

yaml
task_name: "Product Review Sentiment (Solo Mode)"
task_dir: "."
 
data_files:
  - "data/reviews.jsonl"
 
item_properties:
  id_key: id
  text_key: text
 
# --- Solo Mode Configuration ---
solo_mode:
  enabled: true
 
  llm:
    endpoint_type: openai
    model: "gpt-4o"
    api_key: ${OPENAI_API_KEY}
    temperature: 0.1
    max_tokens: 64
 
  # Quality targets
  seed_count: 50
  accuracy_threshold: 0.93
  confidence_threshold: 0.85
 
  # Phase-specific settings
  phases:
    seed:
      count: 50
      selection: diversity
      embedding_model: "all-MiniLM-L6-v2"
 
    calibration:
      batch_size: 200
      holdout_fraction: 0.2
 
    labeling_functions:
      enabled: true
      max_functions: 15
      min_precision: 0.92
      min_coverage: 0.01
 
    active_labeling:
      batch_size: 25
      strategy: hybrid
      max_batches: 15
 
    refinement_loop:
      max_iterations: 3
      improvement_threshold: 0.02
 
    disagreement_exploration:
      max_instances: 150
      show_llm_reasoning: true
      show_nearest_neighbors: 3
 
    edge_case_synthesis:
      enabled: true
      count: 30
 
    confidence_escalation:
      escalation_budget: 150
      batch_size: 25
      stop_when_stable: true
 
    prompt_optimization:
      enabled: true
      candidates: 8
      metric: f1_macro
 
    final_validation:
      sample_size: 100
      min_accuracy: 0.93
 
  # Instance prioritization
  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
 
# --- Annotation Schema ---
annotation_schemes:
  - annotation_type: radio
    name: sentiment
    description: "What is the overall sentiment of this review?"
    labels:
      - "Positive"
      - "Neutral"
      - "Negative"
    label_requirement:
      required: true
    sequential_key_binding: true
 
output_annotation_dir: "output/"
output_annotation_format: "jsonl"
 
parquet_export:
  enabled: true
  output_dir: "output/parquet/"

Paso 3: Inicia el Servidor

bash
potato start config.yaml -p 8000

Abre http://localhost:8000 e inicia sesión. Aparecerá el panel de Solo Mode, mostrando que estás en la Fase 1: Anotación Semilla.


Paso 4: Fase 1 -- Anotación Semilla (50 Instancias)

Potato ha seleccionado 50 reseñas diversas usando clustering basado en embeddings. No son aleatorias; están elegidas para maximizar la cobertura de la distribución de tus datos.

Etiqueta cada una. Esta es la fase más importante -- la calidad de tus etiquetas semilla determina qué tan bien aprenderá el LLM. Tómate tu tiempo y sé consistente.

Tiempo estimado: 15-25 minutos a 20-30 segundos por instancia.

Cuando termines la instancia 50, Potato avanza automáticamente a la Fase 2.


Paso 5: Fase 2 -- Calibración Inicial del LLM

Esta fase se ejecuta automáticamente. Potato envía al LLM un lote de 200 instancias con tus 50 etiquetas semilla como ejemplos few-shot. Luego compara las predicciones del LLM contra 10 etiquetas semilla reservadas para estimar la precisión base.

Verás un indicador de progreso en el panel. Esto típicamente toma 1-2 minutos dependiendo del proveedor de LLM.

Resultado típico: El LLM logra 75-85% de precisión en la primera calibración. Esto es esperado -- el LLM aún no ha aprendido tu estilo específico de anotación.


Paso 6: Fase 3 -- Análisis de Confusión

Potato muestra una matriz de confusión mostrando dónde el LLM discrepa con tus etiquetas. Una salida típica:

text
Confusion Analysis (Round 1)
============================
Overall Accuracy: 0.82 (target: 0.93)

Top Confusion Pairs:
  Neutral -> Positive:  14 instances (7.0%)
  Negative -> Neutral:   9 instances (4.5%)
  Positive -> Neutral:   4 instances (2.0%)

Esto te dice la principal debilidad del LLM: tiende a elevar reseñas neutrales a positivas. Esto es común -- los LLMs a menudo tienen sesgo hacia el sentimiento positivo.

Tu acción: Revisa los pares de confusión. Haz clic en cada par para ver las instancias específicas donde el LLM se equivocó. Esto te ayuda a entender los modos de fallo del LLM.


Paso 7: Fase 4 -- Refinamiento de Directrices

Basándose en el análisis de confusión, Potato genera directrices refinadas para el LLM. Ves una vista lado a lado:

  • Directrices actuales: El prompt inicial usado para el LLM
  • Ediciones sugeridas: Cambios específicos que el LLM propone basándose en patrones de error

Por ejemplo, Potato podría sugerir agregar:

"Las reseñas que describen un producto como 'aceptable', 'bien' o 'decente' sin emoción fuerte deben etiquetarse como Neutral, incluso si mencionan comprar de nuevo."

Revisa cada edición sugerida. Aprueba, modifica o rechaza cada una. También puedes agregar tus propias aclaraciones.

Tiempo estimado: 5-10 minutos.


Paso 8: Fase 5 -- Generación de Funciones de Etiquetado

Potato genera funciones de etiquetado programáticas a partir de patrones en tus etiquetas semilla. Son reglas rápidas y determinísticas que manejan casos fáciles:

text
Generated Labeling Functions:
  LF1: Strong positive words (love, amazing, best, excellent)
       Precision: 0.97, Coverage: 0.06
  LF2: Strong negative words (terrible, awful, worst, waste)
       Precision: 0.95, Coverage: 0.04
  LF3: Exclamation + positive adjective
       Precision: 0.94, Coverage: 0.03
  LF4: Return/refund mention + negative context
       Precision: 0.92, Coverage: 0.02
  ...
  Total coverage: 0.18 (1,800 of 10,000 instances)

Las funciones de etiquetado cubren el 18% de tu conjunto de datos con 92%+ de precisión. Estas instancias se etiquetan automáticamente, liberando el esfuerzo del LLM y humano para casos más difíciles.

Tu acción: Revisa las funciones generadas. Deshabilita cualquiera que parezca poco confiable. Esto es opcional -- Potato solo mantiene funciones por encima de tu umbral de precisión configurado.


Paso 9: Fase 6 -- Etiquetado Activo (125-375 Instancias)

Esta es la fase principal de etiquetado humano. Potato selecciona instancias usando el sistema de priorización de seis grupos:

  • Incierto (30%): Reseñas donde la confianza del LLM está por debajo del 85%
  • Desacuerdo (25%): Reseñas donde el LLM y las funciones de etiquetado dan diferentes etiquetas
  • Frontera (20%): Reseñas cerca del límite de decisión en el espacio de embeddings
  • Novedad (10%): Reseñas diferentes a todo lo que has etiquetado hasta ahora
  • Patrón de error (10%): Reseñas que coinciden con patrones de confusión conocidos (p.ej., positivo-tibio)
  • Aleatorio (5%): Reseñas aleatorias para calibración

Etiquetas estas en lotes de 25. Después de cada lote, Potato actualiza la estimación de precisión del LLM y decide si continuar.

Trayectoria típica:

  • Lotes 1-3 (75 instancias): La precisión sube del 82% al 87%
  • Lotes 4-6 (150 instancias): La precisión alcanza el 90%
  • Lotes 7-10 (250 instancias): La precisión se estabiliza en 91-92%

Si la precisión alcanza el 93% (tu umbral), Solo Mode salta a la Fase 10. De lo contrario, continúa a la Fase 7.

Tiempo estimado: 45-90 minutos en total, dependiendo de cuántos lotes se necesiten.


Paso 10: Fase 7 -- Bucle de Refinamiento Automatizado

Si la precisión sigue por debajo del umbral después del etiquetado activo, Potato ejecuta otra ronda del bucle de refinamiento:

  1. El LLM re-etiqueta todo el conjunto de datos con directrices actualizadas y más ejemplos few-shot
  2. La precisión se recalcula contra todas las etiquetas humanas
  3. Se identifican nuevos patrones de confusión
  4. Las directrices se refinan nuevamente

Esta fase es mayormente automática. Solo necesitas aprobar los cambios de directrices.

Resultado típico: La precisión mejora 2-4% por ronda de refinamiento.


Paso 11: Fase 8 -- Exploración de Desacuerdos

Potato presenta las instancias más polémicas: casos donde el LLM, las funciones de etiquetado y el análisis de vecinos más cercanos dan diferentes respuestas. Para cada instancia, ves:

  • El texto de la reseña
  • La predicción y confianza del LLM
  • Los votos de las funciones de etiquetado
  • 3 ejemplos etiquetados más cercanos con sus etiquetas
  • El razonamiento cadena-de-pensamiento del LLM

Estos son casos genuinamente difíciles. Tus etiquetas aquí tienen el mayor valor marginal de cualquier anotación en todo el proceso.

Tiempo estimado: 20-30 minutos para 100-150 instancias.


Paso 12: Fase 9 -- Síntesis de Casos Límite

Potato genera reseñas sintéticas enfocadas en los patrones de confusión restantes. Por ejemplo, si el LLM aún tiene dificultades con "reseñas neutrales que mencionan comprar de nuevo", genera ejemplos como:

"Es un producto aceptable por el precio. Podría comprar otro si hay oferta."

Etiquetas estos ejemplos sintéticos, y se agregan al contexto few-shot del LLM.

Tiempo estimado: 10-15 minutos para 30 ejemplos.


Paso 13: Fase 10 -- Escalamiento de Confianza en Cascada

El LLM ahora ha etiquetado la mayor parte del conjunto de datos. Potato clasifica todas las instancias etiquetadas por el LLM por confianza y te envía las de menor confianza en lotes de 25.

text
Confidence Escalation Progress:
  Batch 1: 25 instances, 23/25 correct (92%)
  Batch 2: 25 instances, 24/25 correct (96%)
  Batch 3: 25 instances, 25/25 correct (100%)
  -> Stopping: last 3 batches stable

Una vez que ves tres lotes consecutivos donde el LLM acertó todo, Solo Mode concluye que las etiquetas de alta confianza restantes son confiables.

Tiempo estimado: 15-20 minutos.


Paso 14: Fase 11 -- Optimización de Prompts

Esta fase se ejecuta automáticamente. Potato prueba 8 variantes de prompts y selecciona la que tiene la mayor puntuación F1 en tus etiquetas humanas acumuladas:

text
Prompt Optimization Results:
  Variant 1 (direct, 5 examples):     F1=0.91
  Variant 2 (CoT, 5 examples):        F1=0.93
  Variant 3 (direct, 10 examples):    F1=0.92
  Variant 4 (CoT, 10 examples):       F1=0.94  <-- selected
  Variant 5 (direct, 15 examples):    F1=0.92
  Variant 6 (CoT, 15 examples):       F1=0.93
  Variant 7 (self-consistency, 5x):   F1=0.94
  Variant 8 (self-consistency, 10x):  F1=0.94

El mejor prompt se usa para una pasada final de re-etiquetado.


Paso 15: Fase 12 -- Validación Final

Potato selecciona 100 instancias aleatorias etiquetadas por el LLM para que las revises. Las etiquetas, y Potato compara contra las etiquetas del LLM.

text
Final Validation:
  Reviewed: 100 instances
  LLM correct: 94/100 (94%)
  Threshold: 93%
  -> PASSED

Si la precisión del LLM cumple tu umbral, el conjunto de datos está completo. Si no, Solo Mode regresa a la Fase 6 para otra ronda de etiquetado activo.

Tiempo estimado: 10-15 minutos.


Resumen de Resultados

Después de ejecutar las 12 fases, revisa las estadísticas finales:

bash
python -m potato.solo status --config config.yaml
text
Solo Mode Complete
==================
Dataset: 10,000 instances
Total human labels: 612
  Seed: 50
  Active labeling: 275
  Disagreement exploration: 137
  Edge case synthesis: 30
  Confidence escalation: 75
  Final validation: 45

LLM labels: 8,200 (accuracy: 94.1%)
LF labels: 1,800 (precision: 95.3%)
Unlabeled: 0

Final label distribution:
  Positive: 4,823 (48.2%)
  Neutral:  3,011 (30.1%)
  Negative: 2,166 (21.7%)

Total human time: ~3.5 hours
Estimated multi-annotator cost (3x): ~$4,500
Solo Mode cost: ~$450 (API fees) + ~$175 (annotator time)
Savings: ~88%

El humano etiquetó 612 de 10,000 instancias (6.1%). El LLM y las funciones de etiquetado manejaron el resto con 94%+ de precisión.


Exportación de Resultados

Exporta el conjunto de datos etiquetado final:

bash
python -m potato.solo export --config config.yaml --output final_labels.jsonl

Cada línea incluye la etiqueta y su fuente:

json
{"id": "rev_001", "sentiment": "Positive", "source": "human", "confidence": 1.0}
{"id": "rev_002", "sentiment": "Neutral", "source": "llm", "confidence": 0.91}
{"id": "rev_003", "sentiment": "Negative", "source": "labeling_function", "confidence": 0.97}

Para exportación Parquet:

python
import pandas as pd
df = pd.read_parquet("output/parquet/annotations.parquet")
print(df["value"].value_counts())

Aseguramiento de Calidad: Verificación Híbrida

Para conjuntos de datos con calidad de publicación, añade un segundo anotador para revisar una muestra:

yaml
solo_mode:
  verification:
    enabled: true
    sample_fraction: 0.10
    annotator: "reviewer_1"

Esto asigna 1,000 instancias aleatorias a un segundo anotador. Luego puedes calcular el acuerdo entre anotadores entre las etiquetas de Solo Mode y las del revisor.


Solución de Problemas

La precisión del LLM se estanca por debajo del umbral

  • Aumentar la cuenta de semillas: Prueba 75-100 instancias semilla en lugar de 50
  • Cambiar de LLM: Prueba claude-sonnet-4-20250514 en lugar de GPT-4o (o viceversa)
  • Bajar el umbral: Si el 93% no es alcanzable, considera si el 90% es aceptable para tu caso de uso
  • Revisa tus datos: Algunos conjuntos de datos son inherentemente ambiguos. Si el acuerdo humano-humano solo sería del 90%, no esperes que el LLM lo haga mejor

La Fase 6 toma demasiados lotes

  • Aumentar tamaño de lote: Cambia batch_size de 25 a 50
  • Ajustar pesos de grupos: Si la mayoría de las instancias escaladas son del grupo "uncertain", reduce su peso y aumenta "disagreement" y "error_pattern"

Las funciones de etiquetado tienen baja cobertura

  • Esto es normal para tareas sin señales léxicas fuertes (p.ej., detección de sarcasmo, sentimiento implícito)
  • Las funciones de etiquetado funcionan mejor para patrones explícitos basados en palabras clave
  • Solo Mode sigue funcionando sin funciones de etiquetado -- el LLM cubre la diferencia

Lectura Adicional