Potato 2.3: anotação agêntica, Solo Mode e Best-Worst Scaling
O Potato 2.3.0 adiciona o Solo Mode para rotulagem conjunta entre humano e LLM, anotação de traces de agentes, Best-Worst Scaling, login por SSO e OAuth, exportação para Parquet e 15 projetos de demonstração.
Nota: este post descreve o Potato 2.3 como ele era no lançamento, em março de 2026. Várias das chaves de configuração abaixo foram renomeadas ou substituídas em versões posteriores, e a sintaxe atual está na documentação. Não copie estes blocos para um projeto que use uma versão atual do Potato.
O Potato 2.3.0 adiciona o Solo Mode, um fluxo de rotulagem entre humano e LLM que percorre dez fases documentadas, além de anotação de traces de agentes com onze conversores de trace registrados, Best-Worst Scaling com três métodos de escore, login por SSO e OAuth para Google, GitHub e provedores OIDC genéricos, exportação para Parquet e 15 projetos de demonstração. As notas de versão registram 50 ou mais commits desde a 2.2.0 e correções de 12 vulnerabilidades de segurança em 8 módulos.
O lançamento acompanha uma mudança naquilo que as pessoas anotam. Pesquisadores que há dois anos rotulavam sentimento e entidades nomeadas hoje destrincham traces de agentes com vários passos, comparam saídas de modelos em grande volume e constroem datasets para tarefas que não existiam quando o conjunto de esquemas do Potato foi projetado. O Solo Mode e o trabalho com traces de agentes miram essa mudança.
Atualização
pip install --upgrade potato-annotation==2.3.0A exportação para Parquet exige o PyArrow 12.0.0 ou mais recente, que é instalado separadamente:
pip install "pyarrow>=12.0.0"Anotação de traces de agentes
Uma execução de agente é uma sequência de chamadas de ferramentas, passos de raciocínio e saídas intermediárias, e achatá-la em texto puro descarta a estrutura que um avaliador precisa ver. O Potato 2.3 renderiza os traces pelo sistema de exibição, de modo que o trace aparece como uma conversa com avaliações associadas a turnos individuais.
A exibição é declarada em instance_display, com os esquemas de avaliação por turno aninhados sob o campo que contém a conversa:
instance_display:
layout:
direction: vertical
gap: 16px
fields:
- key: task_description
type: text
label: "Task"
- key: conversation
type: dialogue
label: "Agent Trace"
span_target: true
display_options:
show_turn_numbers: true
alternating_shading: trueDois tipos de exibição cuidam do trabalho com agentes na 2.3. A exibição dialogue renderiza um trace como turnos e oferece anotação de spans sobre eles, e interactive_chat cobre conversas das quais o anotador participa em vez de apenas relê-las. Definir span_target: true é o que permite aos anotadores destacar um trecho dentro de um turno, e é assim que alucinações e afirmações sem sustentação são marcadas no lugar onde ocorrem.
Traces de outros frameworks entram pelo conversor, que registra onze formatos neste lançamento: openai, anthropic, swebench, otel, mcp, multi_agent, langchain, langfuse, react, webarena e atif.
python -m potato.trace_converter -i traces.json -f react -o data/traces.jsonlSolo Mode
A rotulagem com vários anotadores exige contratar, treinar e coordenar pessoas, e em muitos projetos de pesquisa essa logística é o gargalo, mais do que a interface de anotação. O Solo Mode, em vez disso, junta um especialista de domínio a um LLM. O humano rotula, o LLM propõe, cada correção volta para o prompt, e o humano repassa uma parte maior da fila à medida que os dois convergem.
O fluxo percorre dez fases documentadas: configuração, revisão do prompt, síntese de casos extremos, rotulagem de casos extremos, validação do prompt, anotação em paralelo, resolução de divergências, revisão periódica, rotulagem autônoma e validação final. Nem todo projeto passa por todas as fases.
solo_mode:
enabled: true
labeling_models:
- endpoint_type: "ollama"
model: "qwen3:4b"
endpoint_url: "http://localhost:11434"
max_tokens: 256
temperature: 0.1
revision_models:
- endpoint_type: "ollama"
model: "qwen3:4b"
endpoint_url: "http://localhost:11434"
uncertainty:
strategy: "direct_confidence"
thresholds:
end_human_annotation_agreement: 0.90
minimum_validation_sample: 20
confidence_low: 0.5
periodic_review_interval: 50
instance_selection:
low_confidence_weight: 0.4
diversity_weight: 0.3
random_weight: 0.2
disagreement_weight: 0.1
state_dir: "solo_state"Os quatro pesos de instance_selection decidem quais itens merecem a atenção de um humano. Dar peso 0.4 à baixa confiança e 0.3 à diversidade manda a maior parte do tempo do humano para instâncias sobre as quais o modelo está inseguro, mantendo cobertura suficiente do resto da distribuição para perceber um erro sistemático. O 0.2 da amostragem aleatória é o que torna significativa a estimativa de concordância em end_human_annotation_agreement, já que uma taxa de concordância calculada só sobre instâncias difíceis não é a taxa que você obtém no corpus.
O Solo Mode vem com 85 testes de integração e de ponta a ponta, um guia para desenvolvedores e dois projetos de exemplo em examples/advanced/solo-mode/ e examples/advanced/simple-solo-mode/. Comece pelo simples, que roda com um modelo local do Ollama e não precisa de chave de API, para que a primeira coisa que você avalie seja se o fluxo serve para a sua tarefa, e não se o modelo vale o que custa.
Best-Worst Scaling
O Best-Worst Scaling mostra ao anotador uma tupla de itens, geralmente quatro, e pede apenas o melhor e o pior segundo um critério. Essas duas escolhas implicam um conjunto de comparações par a par, e os escores obtidos a partir de muitas tuplas sobrepostas saem em uma escala real, com julgamentos mais rápidos de fazer do que uma nota.
annotation_schemes:
- annotation_type: bws
name: sentiment_bws
description: "Sentiment Intensity"
best_description: "Which sentence expresses the MOST positive sentiment?"
worst_description: "Which sentence expresses the LEAST positive sentiment?"
tuple_size: 4
sequential_key_binding: trueTrês métodos de escore rodam sobre as tuplas coletadas. counting é a linha de base transparente, com (best_count - worst_count) / appearances, não precisa de dependência extra e é determinístico. bradley_terry ajusta um modelo de comparação par a par e produz parâmetros de força em escala logarítmica. plackett_luce ajusta um modelo de ranqueamento completo. Os dois métodos baseados em modelo precisam de pip install choix.
python -m potato.bws_scoring --config config.yaml --method bradley_terryOs escores vão para bws_scores.tsv no diretório de saída, com o escore de cada item, sua posição no ranking, as contagens de melhor e pior e o número de aparições. O painel de administração tem uma aba BWS Scoring que executa o mesmo cálculo a partir de um botão e mostra os resultados em uma tabela.
SSO e OAuth
Uma implantação que os anotadores acessam pela internet precisa de contas reais, e a 2.3 adiciona OAuth 2.0 e OpenID Connect para que eles possam usar a identidade que já têm. Google, GitHub e qualquer provedor OIDC genérico são suportados, e o acesso pode ser restrito por domínio de e-mail ou por organização do GitHub.
authentication:
method: "oauth"
providers:
google:
client_id: ${GOOGLE_CLIENT_ID}
client_secret: ${GOOGLE_CLIENT_SECRET}
user_identity_field: "email"
secret_key: ${POTATO_SECRET_KEY}Adicione este bloco à sua configuração. Ele traz dois requisitos. O OAuth precisa de uma implantação com HTTPS, com localhost isento para desenvolvimento, e precisa de uma secret_key estável, porque uma chave de assinatura que muda a cada reinício invalida as sessões que o login já emitiu. Registre a URI de redirecionamento no seu provedor como https://your-domain.com/auth/callback/google, trocando pelo nome do provedor.
Exportação para Parquet
Os dados de anotação acabam cada vez mais em ferramentas de análise que esperam um formato colunar, por isso a 2.3 adiciona o Parquet ao registro de exportação. Uma exportação produz até três tabelas: annotations.parquet, com uma linha por instância e anotador, spans.parquet, com uma linha por anotação de span, e items.parquet, com os dados de origem.
python -m potato.export -c config.yaml -f parquet -o ./export/As opções são passadas na linha de comando, e não configuradas no projeto, e o codec de compressão é um entre snappy (o padrão), gzip, zstd, lz4 ou none:
python -m potato.export -c config.yaml -f parquet -o ./export/ \
--option compression=gzip --option include_items=falseAs tabelas se unem pela chave da instância, embora o nome da coluna mude entre elas: annotations.parquet e spans.parquet têm instance_id, enquanto items.parquet tem item_id. É isso que torna a exportação utilizável no DuckDB sem carregar nada no pandas antes:
import duckdb
duckdb.sql("""
SELECT i.item_id, a.user_id, a.*
FROM './export/annotations.parquet' a
JOIN './export/items.parquet' i ON a.instance_id = i.item_id
""")annotations.parquet tem uma linha por instância e anotador, com cada esquema de anotação achatado em sua própria coluna, então não há uma coluna genérica value para selecionar. Um esquema que guarda várias respostas ao mesmo tempo se expande em subcolunas com ponto no nome, no formato <scheme>.<part>.
Correções de segurança
O lançamento corrige 12 vulnerabilidades de segurança em 8 módulos, além de problemas de XSS, robustez e integridade de dados em 25 arquivos, e uma exclusão em cascata de spans que iterava sobre as chaves de um dicionário em vez dos valores e deixava registros de ligação para trás. Uma auditoria de dependências atualizou as dependências de Python e JavaScript para as versões atuais.
Duas das outras correções podem ter alterado dados que você já coletou. Uma falha com o booleano has_free_response (issue #111) e um loop de navegação com todas as fases afetavam se as anotações eram registradas como pretendido, e o tratamento de aspas no multirate dinâmico afetava como esses valores eram gravados. Se você conduziu um estudo na 2.2 usando opções de resposta livre ou esquemas multirate, verifique a saída antes de tratá-la como final.
Projetos de demonstração
O lançamento traz 15 projetos de demonstração em demo/, numerados na ordem em que se apoiam uns nos outros, de 01-sentiment-admin até 15-agentic-chat, e cobrindo spans, layouts de moderação personalizados, classificação de imagens, emoção em áudio, vídeo, itens multimodais, adjudicação, sliders, caixas delimitadoras, árvores de dependência, anotação ELAN em camadas e chat agêntico. Cada diretório de demonstração contém um config.yaml e sua pasta data/, e o conjunto compartilha um script que gera a mídia de que as demonstrações baseadas em mídia precisam.
# From the repository root: generates the demo data, then starts all 15 servers
bash demo/launch.shPara o changelog completo, incluindo cada correção citada acima, consulte as notas de versão da v2.3.0 no repositório. Abra issues no GitHub ou inicie um tópico no GitHub Discussions.