Skip to content
Questa pagina non è ancora disponibile nella tua lingua. Viene mostrata la versione in inglese.

Modalità Solo

Etichetta interi dataset con un singolo annotatore che collabora con un LLM attraverso un flusso di lavoro intelligente a 12 fasi.

Modalità Solo

Novità della v2.3.0

I tradizionali progetti di annotazione richiedono più annotatori, calcoli dell'accordo inter-annotatore, round di adjudication e un notevole overhead di coordinamento. Per molti team di ricerca, questo è il principale collo di bottiglia: non l'interfaccia di annotazione, ma la logistica di assumere, addestrare e gestire un team.

La Modalità Solo sostituisce il paradigma multi-annotatore con un singolo esperto umano che collabora con un LLM. L'umano fornisce etichette di alta qualità su un sottoinsieme piccolo e strategicamente selezionato. L'LLM impara da quelle etichette, propone etichette per il resto e l'umano rivede solo i casi in cui l'LLM è incerto o probabilmente sbagliato. Un flusso di lavoro a 12 fasi orchestra automaticamente questo processo.

In benchmark interni, la Modalità Solo ha raggiunto un accordo del 95%+ con le pipeline multi-annotatore complete richiedendo solo il 10-15% delle etichette umane totali.

Il Flusso di Lavoro a 12 Fasi

La Modalità Solo avanza attraverso 12 fasi. Il sistema avanza automaticamente in base a soglie configurabili, sebbene sia possibile attivare le transizioni manualmente dalla dashboard di amministrazione.

Fase 1: Annotazione Seed

L'annotatore umano etichetta un insieme iniziale seed. Potato seleziona istanze diverse e rappresentative usando il clustering basato su embedding per massimizzare la copertura della distribuzione dei dati.

Dimensione seed predefinita: 50 istanze (configurabile tramite seed_count)

Fase 2: Calibrazione Iniziale dell'LLM

L'LLM riceve le annotazioni seed come esempi few-shot ed etichetta un batch di calibrazione. Potato confronta le previsioni dell'LLM con le etichette seed trattenute per stabilire un'accuratezza baseline.

Fase 3: Analisi della Confusione

Potato identifica i pattern sistematici di disaccordo tra umano e LLM. Costruisce una matrice di confusione e mette in evidenza i tipi di errore più comuni (es. "L'LLM etichetta neutrale come positivo nel 40% dei casi").

Fase 4: Raffinamento delle Linee Guida

Sulla base dell'analisi della confusione, Potato genera linee guida di annotazione raffinate per l'LLM. L'umano rivede e modifica queste linee guida prima che vengano applicate. Questo è un passaggio interattivo in cui l'annotatore può aggiungere esempi, chiarire casi limite e adeguare le definizioni delle etichette.

Fase 5: Generazione delle Funzioni di Etichettatura

Ispirata al framework ALCHEmist, Potato genera funzioni di etichettatura programmatiche dalle annotazioni esistenti. Queste sono semplici regole basate su pattern (es. "se il testo contiene 'eccellente' e nessuna negazione, etichetta come positivo") che possono etichettare le istanze facili con alta precisione, riservando lo sforzo umano e dell'LLM per i casi più difficili.

Fase 6: Etichettatura Attiva

L'umano etichetta ulteriori istanze selezionate dall'apprendimento attivo. Potato dà priorità alle istanze in cui l'LLM è più incerto, dove le funzioni di etichettatura non concordano, o dove l'istanza è lontana dagli esempi di addestramento esistenti nello spazio degli embedding.

Fase 7: Ciclo di Raffinamento Automatizzato

L'LLM ri-etichetta l'intero dataset con linee guida ed esempi few-shot aggiornati. Potato confronta con tutte le etichette umane e attiva un altro ciclo di analisi della confusione e raffinamento delle linee guida se l'accuratezza è sotto la soglia.

Fase 8: Esplorazione dei Disaccordi

L'umano rivede tutte le istanze in cui l'LLM e le funzioni di etichettatura non concordano. Questi sono tipicamente gli esempi più informativi e difficili. Le etichette dell'umano su questi casi forniscono il valore marginale più alto.

Fase 9: Sintesi dei Casi Limite

Potato usa l'LLM per generare casi limite sintetici basati sui pattern di confusione identificati. L'umano etichetta questi esempi sintetici, che vengono poi aggiunti al contesto di addestramento dell'LLM per migliorare le prestazioni sui casi più difficili.

Fase 10: Escalation Cascata della Confidenza

L'LLM assegna punteggi di confidenza a ogni istanza non etichettata rimanente. Le istanze vengono escalate all'umano in ordine decrescente di difficoltà (crescente confidenza). L'umano etichetta fino a quando le metriche di qualità si stabilizzano.

Fase 11: Ottimizzazione del Prompt

Ispirata a DSPy, Potato esegue l'ottimizzazione automatizzata del prompt usando le etichette umane accumulate come set di validazione. Prova più variazioni del prompt (formulazione delle istruzioni, ordine degli esempi, chain-of-thought vs. diretto) e seleziona il prompt con le migliori prestazioni.

Fase 12: Validazione Finale

L'umano esegue una revisione finale di un campione casuale delle istanze etichettate dall'LLM. Se l'accuratezza soddisfa la soglia, il dataset è completo. In caso contrario, il sistema torna alla Fase 6.


Configurazione

Avvio Rapido

Una configurazione minimale della Modalità Solo:

yaml
task_name: "Sentiment Classification"
task_dir: "."
 
data_files:
  - "data/reviews.jsonl"
 
item_properties:
  id_key: id
  text_key: text
 
solo_mode:
  enabled: true
 
  # Provider LLM
  llm:
    endpoint_type: openai
    model: "gpt-4o"
    api_key: ${OPENAI_API_KEY}
 
  # Soglie di base
  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"

Riferimento Completo alla Configurazione

yaml
solo_mode:
  enabled: true
 
  # Configurazione LLM
  llm:
    endpoint_type: openai        # openai, anthropic, ollama, vllm
    model: "gpt-4o"
    api_key: ${OPENAI_API_KEY}
    temperature: 0.1             # bassa temperatura per coerenza
    max_tokens: 256
 
  # Controllo delle fasi
  phases:
    seed:
      count: 50                  # numero di istanze seed
      selection: diversity        # diversity, random o stratified
      embedding_model: "all-MiniLM-L6-v2"
 
    calibration:
      batch_size: 100
      holdout_fraction: 0.2      # frazione del seed usata per la validazione
 
    confusion_analysis:
      min_samples: 30
      significance_threshold: 0.05
 
    guideline_refinement:
      auto_suggest: true         # L'LLM suggerisce modifiche alle linee guida
      require_approval: true     # L'umano deve approvare le modifiche
 
    labeling_functions:
      enabled: true
      max_functions: 20
      min_precision: 0.90        # mantieni solo le regole ad alta precisione
      min_coverage: 0.01         # deve coprire almeno l'1% dei dati
 
    active_labeling:
      batch_size: 25
      strategy: uncertainty       # uncertainty, diversity o 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     # istanze massime da escalare
      batch_size: 25
      stop_when_stable: true     # ferma se l'accuratezza dell'ultimo batch è al 100%
 
    prompt_optimization:
      enabled: true
      candidates: 10             # numero di varianti di prompt da provare
      metric: f1_macro
      search_strategy: bayesian  # bayesian, grid o random
 
    final_validation:
      sample_size: 100
      min_accuracy: 0.92
      fallback_phase: 6          # torna alla Fase 6 se la validazione fallisce
 
  # Prioritizzazione delle istanze tra le fasi
  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"

Capacità Chiave

Analisi della Confusione

Dopo ogni round di etichettatura, Potato costruisce una matrice di confusione tra etichette umane e LLM. La dashboard di amministrazione mostra:

  • Precisione, recall e F1 per classe dal punto di vista dell'LLM
  • Le coppie di confusione più comuni (es. "neutrale classificato come positivo: 23 istanze")
  • Istanze di esempio per ogni coppia di confusione
  • Grafici di tendenza che mostrano il miglioramento tra i round di raffinamento

Accedi all'analisi della confusione in modo programmatico:

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

Output:

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

Ciclo di Raffinamento Automatizzato

Il ciclo di raffinamento itera tra l'etichettatura LLM, l'analisi della confusione e gli aggiornamenti delle linee guida. Ogni iterazione:

  1. L'LLM etichetta l'intero dataset con le linee guida attuali
  2. Potato confronta con tutte le etichette umane disponibili
  3. Se l'accuratezza è sotto la soglia, viene eseguita l'analisi della confusione
  4. L'LLM propone modifiche alle linee guida in base ai pattern di errore
  5. L'umano rivede e approva le modifiche
  6. Il ciclo si ripete (fino a 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    # ferma se il miglioramento è inferiore al 2%

Funzioni di Etichettatura (Ispirate ad ALCHEmist)

Potato genera funzioni di etichettatura leggere dai pattern osservati nelle annotazioni umane. Queste non sono chiamate LLM; sono regole veloci e deterministiche.

Esempi di funzioni di etichettatura generate automaticamente:

python
# Funzione di etichettatura auto-generata 1
# Precisione: 0.96, Copertura: 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  # astieniti
 
# Funzione di etichettatura auto-generata 2
# Precisione: 0.93, Copertura: 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 il comportamento delle funzioni di etichettatura:

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

Esploratore dei Disaccordi

L'esploratore dei disaccordi presenta le istanze in cui segnali diversi sono in conflitto. Per ogni istanza, l'annotatore vede:

  • L'etichetta prevista dall'LLM e la confidenza
  • I voti delle funzioni di etichettatura (se presenti)
  • I vicini etichettati più prossimi nello spazio degli embedding
  • Il testo/contenuto grezzo

Questa è l'attività di annotazione dal più alto valore: ogni etichetta risolve un'ambiguità genuina.

yaml
solo_mode:
  phases:
    disagreement_exploration:
      max_instances: 200
      sort_by: confidence_gap     # o "lf_disagreement" o "random"
      show_llm_reasoning: true    # mostra la chain-of-thought dell'LLM
      show_nearest_neighbors: 3   # mostra 3 esempi etichettati più vicini

Escalation Cascata della Confidenza

Dopo che la maggior parte del dataset è stata etichettata dall'LLM, Potato classifica tutte le istanze etichettate dall'LLM per confidenza ed esegue l'escalation delle meno sicure all'umano. Questo continua in batch fino a quando la qualità si stabilizza.

yaml
solo_mode:
  phases:
    confidence_escalation:
      escalation_budget: 200
      batch_size: 25
      stop_when_stable: true
      stability_window: 3        # ferma se gli ultimi 3 batch sono tutti corretti

Prioritizzazione Multi-Segnale delle Istanze

In tutte le fasi che coinvolgono l'etichettatura umana, Potato usa un sistema di pool ponderato per selezionare le istanze più informative. Sei pool alimentano una coda di priorità unificata:

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: Istanze in cui la confidenza dell'LLM è sotto confidence_threshold
  • disagreement: Istanze in cui l'LLM e le funzioni di etichettatura producono etichette diverse
  • boundary: Istanze vicino al confine decisionale nello spazio degli embedding
  • novel: Istanze lontane da qualsiasi esempio etichettato esistente
  • error_pattern: Istanze che corrispondono a pattern di confusione noti dai round precedenti
  • random: Un piccolo campione casuale per mantenere la calibrazione e individuare i punti ciechi

Sintesi dei Casi Limite

Potato usa l'LLM per generare esempi sintetici che mirano alle debolezze note:

yaml
solo_mode:
  phases:
    edge_case_synthesis:
      enabled: true
      count: 50
      diversity_weight: 0.3
      confusion_pairs:            # concentrati su questi tipi di errore
        - ["neutral", "positive"]
        - ["negative", "neutral"]

L'LLM genera esempi ambigui tra le coppie di etichette specificate. L'umano le etichetta e queste etichette vengono aggiunte al contesto few-shot per i successivi round di etichettatura LLM.

Ottimizzazione del Prompt (Ispirata a DSPy)

Nella Fase 11, Potato esegue l'ottimizzazione automatizzata del prompt per trovare il miglior formato di istruzioni per l'LLM:

yaml
solo_mode:
  phases:
    prompt_optimization:
      enabled: true
      candidates: 10
      metric: f1_macro
      search_strategy: bayesian
      variations:
        - instruction_style      # formale vs. colloquiale
        - example_ordering       # casuale, per-classe, per-difficoltà
        - reasoning_mode         # diretto, chain-of-thought, self-consistency
        - example_count          # 3, 5, 10, 15 esempi few-shot

Monitoraggio del Progresso

La dashboard di amministrazione mostra il progresso della Modalità Solo in tempo reale:

  • Fase attuale e progresso all'interno di ogni fase
  • Etichette umane completate vs. budget totale
  • Accuratezza dell'LLM nel tempo (per round)
  • Copertura e precisione delle funzioni di etichettatura
  • Istogramma della distribuzione della confidenza
  • Tempo stimato al completamento

Accedi dalla riga di comando:

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

Quando Usare la Modalità Solo vs. il Multi-Annotatore Tradizionale

Usa la Modalità Solo quando:

  • Hai un esperto di dominio che può fornire etichette di alta qualità
  • Il budget o la logistica impediscono di assumere più annotatori
  • Il compito ha categorie chiare e ben definite
  • Hai bisogno di etichettare un dataset di grandi dimensioni (1.000+ istanze)
  • La velocità è più importante della misurazione dell'accordo inter-annotatore

Usa il multi-annotatore tradizionale quando:

  • Hai bisogno di statistiche sull'accordo inter-annotatore per la pubblicazione
  • Il compito è altamente soggettivo (es. offensività, umorismo)
  • Hai bisogno di studiare i pattern di disaccordo tra gli annotatori
  • I requisiti normativi impongono più annotatori indipendenti
  • Lo spazio delle etichette è complesso o in evoluzione (le linee guida di annotazione sono ancora in fase di sviluppo)

Approccio ibrido: Usa la Modalità Solo per l'etichettatura iniziale in blocco, poi assegna un secondo annotatore a un campione casuale del 10-20% per calcolare le statistiche di accordo. Questo ti dà l'efficienza della Modalità Solo con la garanzia della qualità della verifica multi-annotatore.

yaml
solo_mode:
  enabled: true
  # ... configurazione solo mode ...
 
  # Ibrido: assegna il campione di verifica a un secondo annotatore
  verification:
    enabled: true
    sample_fraction: 0.15
    annotator: "reviewer_1"

Ulteriori Letture

Per i dettagli di implementazione, consulta la documentazione sorgente.