Modo Solo: Como um Único Anotador Pode Rotular 10.000 Exemplos
Tutorial passo a passo sobre o uso do Modo Solo do Potato para rotular grandes conjuntos de dados de forma eficiente com colaboração humano-LLM, reduzindo o custo de anotação em até 90%.
Você tem 10.000 avaliações de produtos para rotular quanto ao sentimento (Positivo, Neutro, Negativo). Contratar três anotadores para rotular todas elas leva semanas e custa milhares de dólares. O Modo Solo permite que um único especialista do domínio obtenha qualidade comparável rotulando apenas 500-1.000 instâncias; um LLM cuida do restante, e a pessoa revisa o que quer que o LLM não tenha certeza.
Este tutorial percorre todo o processo.
O que você vai precisar
- Potato 2.3.0+ com os extras do Modo Solo:
pip install potato-annotation[solo] - Uma chave de API da OpenAI ou da Anthropic (para o componente LLM)
- Seu conjunto de dados em formato JSONL
- Um anotador com conhecimento (que pode ser você)
Passo 1: Prepare seus dados
Crie data/reviews.jsonl com uma avaliação por linha:
{"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, imagine que este arquivo contém 10.000 avaliações.
Passo 2: Crie a configuração
Crie config.yaml:
annotation_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/"
export_annotation_format: "jsonl"
parquet_export:
enabled: true
output_dir: "output/parquet/"Passo 3: Inicie o servidor
potato start config.yaml -p 8000Abra http://localhost:8000 e faça login. O painel do Modo Solo aparece, mostrando que você está na Fase 1: Anotação de Sementes.
Passo 4: Fase 1 -- Anotação de Sementes (50 Instâncias)
O Potato escolheu 50 avaliações diversas usando clusterização baseada em embeddings. Elas não são aleatórias; foram selecionadas para cobrir a distribuição dos seus dados da forma mais ampla possível.
Rotule cada uma delas. Esta é a fase que mais importa, pois a qualidade dos seus rótulos de semente define o teto do que o LLM consegue aprender. Reserve seu tempo e mantenha a consistência.
Estimativa de tempo: 15-25 minutos, a 20-30 segundos por instância.
Quando você terminar a 50ª instância, o Potato avança sozinho para a Fase 2.
Passo 5: Fase 2 -- Calibração Inicial do LLM
Esta fase roda sozinha. O Potato envia ao LLM um lote de 200 instâncias com seus 50 rótulos de semente como exemplos few-shot, depois compara as previsões com 10 rótulos de semente reservados para estimar a acurácia de base.
Um indicador de progresso aparece no painel. Isso normalmente leva de 1 a 2 minutos, dependendo do provedor do LLM.
Resultado típico: O LLM fica em 75-85% de acurácia na primeira calibração. Isso é esperado. Ele ainda não aprendeu o seu estilo de anotação.
Passo 6: Fase 3 -- Análise de Confusão
O Potato exibe uma matriz de confusão mostrando onde o LLM discorda dos seus rótulos. Uma saída típica:
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%)
Isso aponta para a principal fraqueza do LLM aqui: ele continua promovendo avaliações neutras a positivas. Essa é comum, já que os LLMs tendem a pender para o positivo.
Sua ação: Examine os pares de confusão. Clique em cada par para ver as instâncias específicas que o LLM errou, que é a forma mais rápida de entender como ele falha.
Passo 7: Fase 4 -- Refinamento das Diretrizes
Com base na análise de confusão, o Potato redige diretrizes refinadas para o LLM e as mostra lado a lado: o prompt atual de um lado, e as edições específicas que ele propõe a partir dos padrões de erro do outro.
Por exemplo, o Potato pode sugerir adicionar:
"Reviews that describe a product as 'fine', 'okay', or 'decent' without strong emotion should be labeled Neutral, even if they mention buying again."
Passe por cada edição sugerida e aprove, modifique ou rejeite. Você também pode escrever suas próprias clarificações.
Estimativa de tempo: 5-10 minutos.
Passo 8: Fase 5 -- Geração de Funções de Rotulagem
O Potato gera funções de rotulagem programáticas a partir de padrões nos seus rótulos de semente. São regras rápidas e determinísticas que tratam os casos fáceis:
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)
As funções de rotulagem cobrem 18% do seu conjunto de dados com 92%+ de precisão. Essas instâncias são rotuladas automaticamente, o que libera o LLM e a pessoa para os casos mais difíceis.
Sua ação: Examine as funções geradas e desative qualquer uma que pareça não confiável. Este passo é opcional, já que o Potato só mantém funções acima do limiar de precisão que você configurou.
Passo 9: Fase 6 -- Rotulagem Ativa (125-375 Instâncias)
É aqui que você faz a maior parte da sua rotulagem. O Potato escolhe instâncias usando o sistema de priorização de seis grupos:
- Incerto (30%): Avaliações em que a confiança do LLM está abaixo de 85%
- Discordância (25%): Avaliações em que o LLM e as funções de rotulagem dão rótulos diferentes
- Fronteira (20%): Avaliações próximas da fronteira de decisão no espaço de embeddings
- Novo (10%): Avaliações diferentes de tudo o que você já rotulou
- Padrão de erro (10%): Avaliações que correspondem a padrões de confusão conhecidos (por exemplo, positivo morno)
- Aleatório (5%): Avaliações aleatórias para calibração
Você rotula essas em lotes de 25. Após cada lote, o Potato atualiza a estimativa de acurácia do LLM e decide se continua.
Trajetória típica:
- Lote 1-3 (75 instâncias): A acurácia sobe de 82% para 87%
- Lote 4-6 (150 instâncias): A acurácia chega a 90%
- Lote 7-10 (250 instâncias): A acurácia estabiliza em 91-92%
Se a acurácia atingir 93% (seu limiar), o Modo Solo pula direto para a Fase 10. Caso contrário, segue para a Fase 7.
Estimativa de tempo: 45-90 minutos no total, dependendo de quantos lotes forem necessários.
Passo 10: Fase 7 -- Laço de Refinamento Automatizado
Se a acurácia ainda estiver abaixo do limiar depois da rotulagem ativa, o Potato roda mais uma rodada do laço de refinamento:
- O LLM re-rotula o conjunto de dados completo com diretrizes atualizadas e mais exemplos few-shot
- O Potato recalcula a acurácia em relação a todos os rótulos humanos
- Ele encontra os novos padrões de confusão
- Ele refina as diretrizes de novo
Esta fase é quase toda automática. Você só precisa aprovar as mudanças nas diretrizes.
Resultado típico: A acurácia melhora de 2 a 4% por rodada de refinamento.
Passo 11: Fase 8 -- Exploração de Discordância
O Potato apresenta as instâncias mais contenciosas: casos em que o LLM, as funções de rotulagem e a análise de vizinhos mais próximos dão respostas diferentes. Para cada instância, você vê:
- O texto da avaliação
- A previsão e a confiança do LLM
- Os votos das funções de rotulagem
- Os 3 exemplos rotulados mais próximos com seus rótulos
- O raciocínio em cadeia de pensamento do LLM
Esses são casos genuinamente difíceis, e seus rótulos aqui valem mais do que quaisquer outros em todo o processo.
Estimativa de tempo: 20-30 minutos para 100-150 instâncias.
Passo 12: Fase 9 -- Síntese de Casos Limítrofes
O Potato gera avaliações sintéticas que visam os padrões de confusão restantes. Por exemplo, se o LLM ainda tem dificuldade com "avaliações neutras que mencionam comprar de novo", ele gera exemplos como:
"It's an okay product for the price. I might get another one if there's a sale."
Você rotula esses exemplos sintéticos, e o Potato os adiciona ao contexto few-shot do LLM.
Estimativa de tempo: 10-15 minutos para 30 exemplos.
Passo 13: Fase 10 -- Escalonamento de Confiança em Cascata
A esta altura, o LLM já rotulou a maior parte do conjunto de dados. O Potato classifica todos os seus rótulos por confiança e lhe envia os de menor confiança em lotes de 25.
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
Quando três lotes seguidos voltam com o LLM acertando tudo, o Modo Solo trata os rótulos de alta confiança restantes como confiáveis.
Estimativa de tempo: 15-20 minutos.
Passo 14: Fase 11 -- Otimização de Prompt
Esta fase roda sozinha. O Potato testa 8 variantes de prompt e mantém aquela com a maior pontuação F1 nos seus rótulos humanos acumulados:
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
Em seguida, ele usa o melhor prompt para uma passagem final de re-rotulagem.
Passo 15: Fase 12 -- Validação Final
O Potato extrai 100 instâncias aleatórias rotuladas pelo LLM para você revisar. Você as rotula, e o Potato compara seus rótulos com os do LLM.
Final Validation:
Reviewed: 100 instances
LLM correct: 94/100 (94%)
Threshold: 93%
-> PASSED
Se o LLM superar o seu limiar, o conjunto de dados está pronto. Caso contrário, o Modo Solo volta para a Fase 6 para mais uma rodada de rotulagem ativa.
Estimativa de tempo: 10-15 minutos.
Resumo dos Resultados
Depois de todas as 12 fases, confira as estatísticas finais:
python -m potato.solo status --config config.yamlSolo 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%
A pessoa rotulou 612 de 10.000 instâncias, cerca de 6%. O LLM e as funções de rotulagem cuidaram do restante com 94%+ de acurácia.
Exportando os Resultados
Exporte o conjunto de dados final rotulado:
python -m potato.solo export --config config.yaml --output final_labels.jsonlCada linha inclui o rótulo e sua origem:
{"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 exportação em Parquet:
import pandas as pd
df = pd.read_parquet("output/parquet/annotations.parquet")
print(df["value"].value_counts())Garantia de Qualidade: Verificação Híbrida
Para conjuntos de dados em qualidade de publicação, adicione um segundo anotador para revisar uma amostra. A documentação de origem do Modo Solo descreve as opções de verificação em mais detalhe.
solo_mode:
verification:
enabled: true
sample_fraction: 0.10
annotator: "reviewer_1"Isso envia 1.000 instâncias aleatórias a um segundo anotador. Você pode então calcular a concordância entre anotadores entre os rótulos do Modo Solo e os rótulos do revisor.
Solução de Problemas
A acurácia do LLM estaciona abaixo do limiar
- Aumente a contagem de sementes: Tente 75-100 instâncias de semente em vez de 50
- Troque de LLM: Tente
claude-sonnet-4-20250514no lugar do GPT-4o (ou vice-versa) - Reduza o limiar: Se 93% não for alcançável, considere se 90% é aceitável para o seu caso de uso
- Verifique seus dados: Alguns conjuntos de dados são inerentemente ambíguos. Se a concordância humano-humano seria de apenas 90%, não espere que o LLM faça melhor
A Fase 6 leva lotes demais
- Aumente o tamanho do lote: Mude
batch_sizede 25 para 50 - Ajuste os pesos dos grupos: Se a maioria das instâncias escaladas vem do grupo "incerto", reduza seu peso e aumente "discordância" e "padrão de erro"
As funções de rotulagem têm cobertura baixa
- Isso é normal para tarefas sem sinais lexicais fortes (por exemplo, detecção de sarcasmo, sentimento implícito)
- As funções de rotulagem funcionam melhor para padrões explícitos, baseados em palavras-chave
- O Modo Solo ainda funciona sem funções de rotulagem -- o LLM compensa a diferença
Leitura Complementar
- Documentação do Modo Solo -- referência completa de configuração
- Aprendizado Ativo -- o algoritmo de seleção subjacente
- Suporte de IA -- configuração do provedor de LLM
- Controle de Qualidade -- opções adicionais de garantia de qualidade
- Exportação Parquet -- exportação eficiente de dados