Skip to content
Tutorials12 min read

Observe, Pause e Retroceda: Observação ao Vivo de Agentes de Código no Potato

Tutorial para configurar a observação ao vivo de agentes de código com Ollama, API da Anthropic ou Claude Agent SDK. Inclui pausa, rollback, ramificação e exportação de trajetórias.

Potato Team

O que torna a observação ao vivo diferente

A maior parte da avaliação de agentes de código acontece depois do fato. O agente roda, produz um trace e os revisores analisam a gravação mais tarde. A observação ao vivo funciona ao contrário. O anotador acompanha o agente trabalhando em tempo real e vê cada edição de arquivo, comando de terminal e passo de raciocínio assim que ele chega.

Isso muda o que você pode fazer. Se o agente começa a seguir por um caminho errado, o anotador pode intervir antes que ele desperdice tempo ali. Ele pode pausar para ler um diff com cuidado antes de o agente seguir adiante, ou enviar uma instrução em linguagem simples para redirecioná-lo. A parte que considero mais útil é o rollback. Em qualquer checkpoint anterior, você pode retroceder e deixar o agente tentar uma abordagem diferente. Essas ramificações são o tipo de dado de que o aprendizado por preferência precisa.

Isso não substitui a anotação estática de traces, e sim produz outro tipo de dado. A anotação estática vence quando você quer muito dado a um custo previsível. A observação ao vivo vence quando você busca dados específicos, tenta entender como um agente falha ou constrói pares de preferência ramificados.

Para a referência completa do recurso, veja a documentação de origem.

A interface de agente de código ao vivo transmite as ações do agente em tempo real, mostrando diffs de código e a saída do terminal enquanto o agente trabalha:

Interface de agente de código ao vivo mostrando diffs de código e saída do terminal em tempo realObservação ao vivo de agente de código com renderização de diff em tempo real e saída do terminal

Três backends

O Potato oferece três backends para observação ao vivo. Cada um executa um agente de código em um sandbox e transmite suas ações para a interface conforme elas acontecem.

Ollama (totalmente local)

O backend Ollama roda inteiramente na sua máquina, sem chaves de API e sem chamadas de rede. Recorra a ele quando a base de código for sensível ou quando você só quiser experimentar sem acumular uma conta de API.

Primeiro, instale o Ollama e baixe um modelo com capacidade de uso de ferramentas:

bash
# Install Ollama
curl -fsSL https://ollama.ai/install.sh | sh
 
# Pull a coding-capable model
ollama pull qwen2.5-coder:32b
 
# Verify the model is available
ollama list

Configure o Potato para usar o backend Ollama:

yaml
# config.yaml
annotation_task_name: "Live Agent Observation - Ollama"
port: 8000
 
live_coding_agent:
  backend_type: ollama_tool_use
  ai_config:
    model: "qwen2.5-coder:32b"
    base_url: "http://localhost:11434"
    temperature: 0.2
    max_tokens: 4096
  working_dir: ./workspace       # Agent's working directory
  max_turns: 50
  sandbox_mode: container        # container (default) | bubblewrap | trusted
  sandbox_image: "python:3.11-slim"

API da Anthropic (Claude com uso de ferramentas)

O backend da API da Anthropic se conecta aos modelos Claude com uso de ferramentas. Você obtém raciocínio e geração de código mais fortes do que a maioria dos modelos locais oferece e, em troca, paga pelas chamadas de API.

bash
# Set your API key
export ANTHROPIC_API_KEY="sk-ant-..."
yaml
# config.yaml
annotation_task_name: "Live Agent Observation - Claude"
port: 8000
 
live_coding_agent:
  backend_type: anthropic_tool_use
  ai_config:
    model: "claude-sonnet-4-20250514"
    max_tokens: 8192
    temperature: 0.1
  system_prompt: >
    You are a coding agent. You will be given a task description and
    access to a codebase. Use the provided tools to read files, make
    edits, and run commands to complete the task. Think step by step
    and verify your changes by running tests.
  working_dir: ./workspace
  max_turns: 50
  sandbox_mode: container
  sandbox_image: "python:3.11-slim"

Claude Agent SDK (capacidades completas do Claude Code)

O backend do Claude Agent SDK é o mais capaz dos três, com o conjunto completo de ferramentas do Claude Code e comportamento autônomo. Ele requer o pacote claude-agent-sdk.

bash
# Install the Claude Agent SDK
pip install claude-agent-sdk
yaml
# config.yaml
annotation_task_name: "Live Agent Observation - Claude Agent SDK"
port: 8000
 
live_coding_agent:
  backend_type: claude_sdk
  ai_config:
    model: "claude-sonnet-4-20250514"
  working_dir: ./workspace
  max_turns: 50                  # Maximum number of agent turns
  sandbox_mode: container
  sandbox_image: "node:20-slim"

O fluxo de trabalho de anotação

Assim que o servidor está no ar, uma sessão de observação ao vivo passa por algumas etapas.

Iniciando uma sessão

O anotador abre a interface do Potato e vê um campo de entrada para a descrição da tarefa. Ele cola ou digita a tarefa que o agente deve concluir, como "Corrija o teste que falha em tests/test_parser.py por causa do novo formato de configuração" ou "Adicione suporte a paginação ao endpoint /api/users".

bash
# Start the server
potato start config.yaml -p 8000

O anotador clica em "Start Agent" e o agente de código começa a trabalhar. Cada ação aparece em tempo real no painel CodingTraceDisplay.

Acompanhando o agente trabalhar

Conforme o agente roda, cada passo aparece no visualizador de trace:

  • Passos de raciocínio aparecem como blocos cinza recolhíveis mostrando o raciocínio do agente.
  • Leituras de arquivo aparecem como blocos de código com realce de sintaxe, números de linha e o caminho do arquivo.
  • Edições de arquivo aparecem como diffs unificados com realce em vermelho/verde.
  • Comandos de terminal aparecem como blocos de terminal escuros com o comando, a saída e o código de saída.
  • A árvore de arquivos é atualizada na barra lateral conforme os arquivos são criados, modificados ou lidos.

Um indicador de progresso no topo mostra o número do passo atual e o tempo decorrido. O status do agente é exibido como "Thinking...", "Editing file...", "Running command...", etc.

Controles de pausa e instrução

Enquanto o agente está rodando, o anotador pode intervir pela barra de controle:

Pause: congela o agente depois que o passo atual é concluído. O agente não avança para o próximo passo até ser retomado. Use isso para examinar com cuidado um diff ou a saída do terminal antes de o agente seguir adiante.

Enviar instrução: enquanto pausado (ou mesmo enquanto roda), digite uma mensagem em linguagem natural que é injetada no contexto do agente. Por exemplo, "Não modifique o schema do banco de dados, use uma migração" ou "Verifique o log de erros em /var/log/app.log antes de fazer alterações".

Resume: continua a execução do agente após uma pausa.

Stop: encerra a sessão do agente por completo. A trajetória até esse ponto é salva.

Os anotadores podem avaliar o trabalho do agente usando anotação PRM junto com a exibição do trace:

Anotação de recompensa de processo junto com o trace do agente de códigoInterface de anotação PRM para rotulagem de correção em nível de passo junto com o trace de código

A barra de controle vem com o visualizador do agente de código ao vivo. Pausar, retomar, injetar instruções, parar, fazer rollback e trocar de branch são ações de sessão que a interface executa pelos endpoints do agente ao vivo, então não há nada para ativar na configuração.

Sistema de checkpoints baseado em git

Rollback, ramificação e exportação de trajetórias dependem todos do sistema de checkpoints, que faz commit no git após cada mudança de arquivo feita pelo agente.

Como funciona

Quando uma sessão começa, o Potato inicializa um repositório git no workspace do sandbox, ou usa o que já está lá. Após cada edição de arquivo, ele faz commit automaticamente com uma mensagem estruturada:

text
[potato-checkpoint] Step 7: Edit src/parser.py
- Modified lines 45-52
- Agent reasoning: Fix the regex pattern to handle escaped quotes

O resultado é um histórico de commits linear que corresponde um a um aos passos da trajetória. Cada checkpoint captura o estado completo do workspace naquele momento.

bash
# You can inspect checkpoints directly with git
cd workspace/
git log --oneline
 
# Output:
# f8a2c1d [potato-checkpoint] Step 12: Edit tests/test_parser.py
# 3b7e9f0 [potato-checkpoint] Step 10: Edit src/parser.py
# a1c4d8e [potato-checkpoint] Step 8: Edit src/parser.py
# 9e2f6b3 [potato-checkpoint] Step 5: Edit src/config.py
# 7d0a3c1 [potato-checkpoint] Step 0: Initial state

Rollback

Clique em "Rollback" e escolha qualquer checkpoint anterior no menu suspenso. O Potato redefine o workspace para aquele estado com git checkout e retrocede a exibição da trajetória para corresponder, e então o agente retoma a partir dali com o contexto cortado de volta àquele passo.

Use isso quando você vir o agente tomar um caminho errado. Em vez de deixá-lo rodar e queimar tempo, você retrocede para o último estado bom e o deixa tentar de novo, talvez com uma instrução que o empurre para uma direção melhor.

Trajetórias ramificadas

A ramificação é um rollback que mantém os dois caminhos. Quando você retrocede e o agente segue por outro caminho, o Potato cria um branch git nomeado e rastreia as duas trajetórias:

text
Step 0 → Step 1 → Step 2 → Step 3 → Step 4 (Branch A: original path)
                          ↘
                           Step 3' → Step 4' → Step 5' (Branch B: after rollback)

Você pode ramificar a partir de qualquer checkpoint, construindo uma árvore inteira de trajetórias. Isso é útil para o aprendizado por preferência, porque cada par de branches já é uma comparação rotulada. Você retrocedeu porque julgou o Branch A errado, o que torna o Branch B o caminho preferido do ponto de ramificação em diante.

A ramificação também não precisa de configuração. O Potato cria o branch quando você retrocede e o agente depois segue por outro caminho, e rastreia as duas trajetórias pelo resto da sessão.

Formatos de exportação

Uma sessão ao vivo produz dados detalhados de trajetória, e você pode exportá-los em alguns formatos dependendo do que está treinando.

Exportação de trajetória linear

Exporte cada branch como uma trajetória independente:

bash
python -m potato.export \
  -c config.yaml \
  -f trajectory_correction \
  -o ./training_data/
json
{
  "session_id": "session_001",
  "branch": "branch-A",
  "task": "Fix the failing test in tests/test_parser.py",
  "steps": [
    {"step_idx": 0, "type": "file_read", "path": "tests/test_parser.py", "...": "..."},
    {"step_idx": 1, "type": "thinking", "content": "The test expects..."},
    {"step_idx": 2, "type": "file_edit", "path": "src/parser.py", "diff": "..."},
    {"step_idx": 3, "type": "bash_command", "command": "pytest tests/test_parser.py"}
  ],
  "human_interventions": [
    {"after_step": 2, "type": "instruction", "content": "Use a migration instead"}
  ],
  "rollback_from_step": null,
  "outcome": "resolved"
}

Pares de preferência a partir de branches

Exporte pares de branches como dados de preferência para DPO ou RLHF:

O mesmo exportador grava esses dados. No diretório de saída, trajectory_dpo.jsonl guarda as comparações entre branches como pares de preferência, ao lado de trajectory_sft.jsonl e trajectory_corrections.json.

bash
python -m potato.export \
  -c config.yaml \
  -f trajectory_correction \
  -o ./training_data/
json
{
  "session_id": "session_001",
  "task": "Fix the failing test in tests/test_parser.py",
  "branch_point_step": 2,
  "branch_point_reason": "Agent started modifying the wrong file",
  "rejected_branch": "branch-A",
  "rejected_steps": [
    {"step_idx": 3, "type": "file_edit", "path": "src/wrong_file.py", "...": "..."},
    {"step_idx": 4, "type": "bash_command", "command": "pytest", "exit_code": 1}
  ],
  "chosen_branch": "branch-B",
  "chosen_steps": [
    {"step_idx": 3, "type": "file_edit", "path": "src/parser.py", "...": "..."},
    {"step_idx": 4, "type": "bash_command", "command": "pytest", "exit_code": 0}
  ]
}

Rótulos PRM a partir de observação ao vivo

Você pode combinar a observação ao vivo com rotulagem PRM, já que um ponto de rollback costuma ser o passo do primeiro erro:

bash
python -m potato.export \
  -c config.yaml \
  -f coding_eval \
  -o ./training_data/ \
  --option types=prm

Aqui o passo do qual você retrocedeu é rotulado como o primeiro erro, e os passos do novo branch são rotulados como corretos, já que você os aceitou.

Conjuntos de dados de revisão de código

Exporte as instruções do anotador e os motivos de rollback como dados de treinamento para revisão de código:

bash
python -m potato.export \
  -c config.yaml \
  -f coding_eval \
  -o ./training_data/ \
  --option types=code_review

Quick start completo

A sequência inteira, do zero a uma sessão Ollama rodando:

bash
# 1. Install Potato with live agent support
pip install potato-annotation[live-agents]
 
# 2. Install and start Ollama
curl -fsSL https://ollama.ai/install.sh | sh
ollama pull qwen2.5-coder:32b
 
# 3. Set up a workspace with a repo to work on
mkdir -p workspace/
git clone https://github.com/example/test-project workspace/repo
 
# 4. Create the config file
cat > config.yaml << 'YAML'
annotation_task_name: "Live Agent Observation"
port: 8000
 
live_coding_agent:
  backend_type: ollama_tool_use
  ai_config:
    model: "qwen2.5-coder:32b"
    base_url: "http://localhost:11434"
    temperature: 0.2
  working_dir: ./workspace/repo
  max_turns: 50
  sandbox_mode: trusted
 
annotation_schemes:
  - annotation_type: radio
    name: outcome
    description: "Final outcome"
    labels:
      - name: "resolved"
        text: "Task Fully Resolved"
      - name: "partial"
        text: "Partially Resolved"
      - name: "failed"
        text: "Failed"
 
  - annotation_type: text
    name: notes
    description: "Session Notes"
    placeholder: "Key observations about agent behavior..."
    label_requirement:
      required: false
 
output_annotation_dir: "./output/"
export_annotation_format: jsonl
 
user_config:
  allow_all_users: false
  users:
    - "observer1"
YAML
 
# 5. Start Potato
potato start config.yaml -p 8000
 
# 6. Open http://localhost:8000 in your browser

Depois de fazer login, cole uma tarefa como "Adicione validação de entrada ao endpoint POST /api/users" e clique em "Start Agent". Acompanhe o agente trabalhar, pause quando algo parecer errado, envie instruções para guiá-lo e retroceda para tentar outras abordagens. Quando terminar, avalie o resultado e anote suas observações.

Boas práticas

Comece com tarefas claras e delimitadas. O ponto ideal é um trabalho que leva de 5 a 15 minutos para o agente. Algo mais curto não produz trajetória suficiente para valer a anotação. Algo muito mais longo cansa o anotador.

Mantenha o sandbox ativado em produção. sandbox_mode: container é o padrão e mantém o agente longe do seu host. bubblewrap é a alternativa mais leve no Linux. trusted executa as chamadas de ferramentas do agente diretamente na máquina, o que só é razoável enquanto você desenvolve com um modelo em que confia.

Registre por que você fez rollback. Nada na configuração exige isso, então transforme em regra para seus anotadores, com uma nota curta em cada ponto de ramificação dizendo o que deu errado. Essas notas são um sinal de treinamento útil por si só, e tornam os dados de preferência melhores.

Compare múltiplos backends. Rode as mesmas tarefas pelo Ollama, pela API da Anthropic e pelo Claude Agent SDK para obter dados de preferência entre agentes. Como apenas a seção do backend na configuração muda, é fácil de montar.

Exporte cedo e com frequência. Rode uma exportação após cada sessão em vez de guardar tudo para o final. Você perde menos se algo travar, e pode acompanhar a qualidade dos dados conforme avança.