Skip to content

Osservazione dal vivo di un coding agent

Guarda i coding agent lavorare in tempo reale, con pausa, rollback e branching. Sono supportati tre backend: Ollama per i modelli locali, l'API di Anthropic e il Claude Agent SDK.

Novità della v2.4.0

L'annotazione di tracce statiche dice che cosa ha fatto un agente. L'osservazione dal vivo dice che cosa fa un agente in risposta alla guida di una persona. La modalità live coding agent di Potato permette agli annotatori di guardare un coding agent mentre lavora in tempo reale, mentre legge file, modifica codice ed esegue test, e di intervenire in qualsiasi momento. Puoi mettere in pausa l'agente, inviargli nuove istruzioni, tornare a un checkpoint precedente o diramare la traiettoria per esplorare approcci alternativi.

Ne escono dati di annotazione più ricchi di quelli che danno le sole tracce statiche: la traiettoria completa con i timestamp, gli interventi dell'annotatore, i punti di decisione in cui la traiettoria si dirama e i dati comparativi dei percorsi alternativi. Sono dati direttamente utilizzabili per addestrare process reward model, modelli di preferenza e valutatori dell'aderenza alle istruzioni.

Requisiti

  • Python 3.10+
  • Git (il sistema di checkpoint usa i commit git)
  • Uno di questi backend per l'agente:
    • Ollama per l'inferenza con modelli locali (non serve alcuna chiave API)
    • ANTHROPIC_API_KEY per l'accesso all'API di Anthropic
    • Claude Agent SDK per l'esperienza completa dell'agente Claude Code

Backend

Potato supporta tre backend per l'esecuzione dei coding agent. Ogni backend esegue l'agente in un sottoprocesso e trasmette le sue azioni all'interfaccia di annotazione in tempo reale.

1. Ollama (modelli locali)

Esegui i coding agent in locale senza bisogno di una chiave API. Ollama offre inferenza veloce per i modelli a pesi aperti. È la scelta giusta per lo sviluppo, per i test e per le situazioni in cui i dati non possono uscire dalla macchina locale.

Preparazione:

bash
# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
 
# Pull a coding-capable model
ollama pull qwen2.5-coder:7b
 
# Or a larger model for better performance
ollama pull deepseek-coder-v2:16b

Configurazione:

yaml
agentic:
  enabled: true
  display_type: coding_trace
  live_agent:
    enabled: true
    backend: ollama
    model: qwen2.5-coder:7b
 
    ollama:
      host: "http://localhost:11434"    # Ollama server URL
      temperature: 0.2
      num_ctx: 8192                     # context window size
      num_predict: 2048                 # max tokens per response
      keep_alive: "5m"                  # keep model loaded in memory
 
    # Agent capabilities
    tools:
      - read_file
      - edit_file
      - write_file
      - bash
      - glob
      - grep
    max_steps: 50
    step_timeout_seconds: 60

2. API di Anthropic

Usa i modelli Claude tramite l'API di Anthropic. Dà buone prestazioni sul codice e supporta l'uso di strumenti. Richiede una chiave API.

Preparazione:

bash
# Set your API key
export ANTHROPIC_API_KEY="sk-ant-..."
 
# Or add to .env file
echo "ANTHROPIC_API_KEY=sk-ant-..." >> .env

Configurazione:

yaml
agentic:
  enabled: true
  display_type: coding_trace
  live_agent:
    enabled: true
    backend: anthropic
    model: claude-sonnet-4-20250514
 
    anthropic:
      api_key: ${ANTHROPIC_API_KEY}
      max_tokens: 4096
      temperature: 0.2
      system_prompt: |
        You are a coding assistant working on a software project.
        Read files before editing them. Run tests after making changes.
        Explain your reasoning before each action.
 
    # Agent capabilities
    tools:
      - read_file
      - edit_file
      - write_file
      - bash
      - glob
      - grep
    max_steps: 100
    step_timeout_seconds: 120

3. Claude Agent SDK

Il Claude Agent SDK offre l'esperienza completa dell'agente Claude Code, con orchestrazione automatica degli strumenti, gestione del contesto e ragionamento su più file. È il backend più capace, ma richiede che l'SDK sia installato.

Preparazione:

bash
# Install the Claude Agent SDK
pip install claude-agent-sdk
 
# Set your API key
export ANTHROPIC_API_KEY="sk-ant-..."

Configurazione:

yaml
agentic:
  enabled: true
  display_type: coding_trace
  live_agent:
    enabled: true
    backend: claude_agent_sdk
 
    claude_agent_sdk:
      api_key: ${ANTHROPIC_API_KEY}
      model: claude-sonnet-4-20250514
      max_turns: 100
      permission_mode: auto           # auto-approve tool use
      enable_thinking: true           # show extended thinking
 
    max_steps: 100
    step_timeout_seconds: 180

Controlli

L'interfaccia di annotazione offre quattro azioni di controllo con cui gli annotatori guidano il comportamento dell'agente.

Pausa / Ripresa

Clicca su Pause per fermare l'agente tra un passo e l'altro. L'agente completa il passo in corso e aspetta. L'annotatore può rivedere lo stato attuale, esaminare i file e decidere se lasciarlo proseguire o intervenire. Clicca su Resume per farlo ripartire.

yaml
live_agent:
  controls:
    pause_resume:
      enabled: true
      auto_pause_on_error: true      # pause when a command fails
      auto_pause_after_steps: 0      # pause after N steps (0 = disabled)
      keyboard_shortcut: "Space"

Invio di istruzioni

Con l'agente in pausa, gli annotatori possono inviare nuove istruzioni che lo reindirizzano. Serve quando l'agente sta imboccando la strada sbagliata, o quando l'annotatore vuole verificare come reagisce a un'indicazione.

yaml
live_agent:
  controls:
    send_instructions:
      enabled: true
      placeholder: "Type instructions for the agent..."
      inject_as: system_message      # "system_message" or "user_message"
      keyboard_shortcut: "Enter"
      presets:
        - "Try a different approach"
        - "Read the error message more carefully"
        - "Check the test file for expected behavior"
        - "Revert your last change and try again"

Le istruzioni vengono iniettate nel contesto di conversazione dell'agente. L'opzione inject_as stabilisce se compaiono come system message (istruzione autorevole) o come user message (indicazione conversazionale).

Rollback

Il rollback riporta il progetto a un checkpoint git precedente. Ogni modifica ai file fatta dall'agente viene committata in automatico, quindi l'annotatore può cliccare su un passo qualsiasi della timeline e tornare esattamente a quello stato. Anche il contesto di conversazione dell'agente viene troncato di conseguenza.

yaml
live_agent:
  controls:
    rollback:
      enabled: true
      show_checkpoint_diff: true     # show what will be undone
      require_confirmation: true     # "Are you sure?" dialog
      keyboard_shortcut: "Ctrl+Z"

Branch e replay

Branch e replay combina il rollback con l'invio di istruzioni. L'annotatore torna a un checkpoint e invia istruzioni diverse, creando una traiettoria che si dirama. È utile quando raccogli dati di preferenza: puoi esplorare due approcci diversi a partire dallo stesso punto e confrontare gli esiti.

yaml
live_agent:
  controls:
    branch:
      enabled: true
      max_branches: 5                # maximum branches from any checkpoint
      branch_naming: auto            # "auto" or "manual"
      compare_view: true             # side-by-side branch comparison
      keyboard_shortcut: "Ctrl+B"

La vista di confronto mostra due branch affiancati ed evidenzia il punto in cui divergono. Gli annotatori possono indicare quale branch ha prodotto il risultato migliore, generando coppie di preferenza per l'addestramento DPO.

Il sistema di checkpoint su git

La modalità live agent usa git per tracciare ogni modifica ai file. Da lì vengono il rollback affidabile, il branching e la cronologia completa delle modifiche.

Come funziona

  1. Prima che l'agente parta, Potato crea un nuovo branch git chiamato potato-session-{session_id}
  2. Dopo ogni modifica a un file (edit, write, create, delete), Potato committa in automatico con un messaggio descrittivo
  3. Ogni commit viene marcato come checkpoint e compare nella timeline
  4. Il rollback usa git checkout per riportare la working directory a un checkpoint qualsiasi
  5. Il branching crea un nuovo branch git a partire dal commit del checkpoint

Configurazione

yaml
live_agent:
  git_checkpoints:
    enabled: true
    branch_prefix: "potato-session"
    commit_message_format: "Step {step}: {tool} {file_path}"
    auto_commit: true
    cleanup_on_complete: false       # delete session branches when done
    require_clean_working_dir: true  # fail if there are uncommitted changes

Gestione manuale dei checkpoint

bash
# List all Potato session branches
git branch | grep potato-session
 
# View checkpoints for a session
git log potato-session-abc123 --oneline
 
# Clean up old session branches
python -m potato.cleanup_sessions --older-than 7d

Formato dei dati

I dati di input per i task di live coding agent indicano la descrizione del compito e, se serve, un file o una directory di partenza:

json
{
  "id": "task_001",
  "task_description": "Fix the bug in src/parser.py where empty input causes a crash",
  "project_dir": "/path/to/project",
  "start_file": "src/parser.py",
  "test_command": "python -m pytest tests/test_parser.py -v",
  "context_files": [
    "src/parser.py",
    "tests/test_parser.py"
  ]
}
CampoObbligatorioDescrizione
idIdentificatore univoco del task
task_descriptionChe cosa deve fare l'agente
project_dirPercorso della directory del progetto
start_fileNoFile da mostrare all'agente all'inizio
test_commandNoComando per verificare la correzione
context_filesNoFile da precaricare nel contesto dell'agente

Riferimento di configurazione

Configurazione completa per un task di osservazione dal vivo di un coding agent:

yaml
task_name: "Live Coding Agent Observation"
task_dir: "."
 
data_files:
  - "data/coding_tasks.jsonl"
 
item_properties:
  id_key: id
  text_key: task_description
 
agentic:
  enabled: true
  display_type: coding_trace
 
  coding_trace_display:
    diff_style: unified
    diff_context_lines: 3
    syntax_highlight: true
    show_line_numbers: true
    terminal_theme: dark
    file_tree:
      enabled: true
      position: left
      click_to_navigate: true
 
  live_agent:
    enabled: true
    backend: anthropic
    model: claude-sonnet-4-20250514
 
    anthropic:
      api_key: ${ANTHROPIC_API_KEY}
      max_tokens: 4096
      temperature: 0.2
 
    tools:
      - read_file
      - edit_file
      - write_file
      - bash
      - glob
      - grep
 
    max_steps: 100
    step_timeout_seconds: 120
 
    controls:
      pause_resume:
        enabled: true
        auto_pause_on_error: true
        keyboard_shortcut: "Space"
      send_instructions:
        enabled: true
        inject_as: system_message
        presets:
          - "Try a different approach"
          - "Read the error message carefully"
          - "Run the tests first"
      rollback:
        enabled: true
        require_confirmation: true
      branch:
        enabled: true
        max_branches: 5
        compare_view: true
 
    git_checkpoints:
      enabled: true
      branch_prefix: "potato-session"
      auto_commit: true
      cleanup_on_complete: false
 
annotation_schemes:
  # Per-step ratings during observation
  - annotation_type: per_turn_rating
    name: step_quality
    description: "Rate each agent step as you observe it"
    target: agentic_steps
    rating_type: radio
    labels:
      - "Good"
      - "Acceptable"
      - "Unnecessary"
      - "Incorrect"
 
  # Overall task completion after agent finishes
  - annotation_type: radio
    name: task_completion
    description: "Did the agent complete the task?"
    labels:
      - "Fully Complete"
      - "Partially Complete"
      - "Failed"
 
  # Branch comparison (when branching is used)
  - annotation_type: radio
    name: branch_preference
    description: "Which branch produced a better result?"
    labels:
      - "Branch A"
      - "Branch B"
      - "Both Equal"
      - "Both Failed"
 
  # Notes on the observation
  - annotation_type: text
    name: observation_notes
    description: "Describe what you observed and any interventions you made"
    label_requirement:
      required: false
 
output_annotation_dir: "output/"
output_annotation_format: "jsonl"

Esportazione delle traiettorie con branching

Quando gli annotatori usano branch e replay, l'output comprende l'intero albero delle diramazioni. Il formato è pensato per addestrare modelli di preferenza e process reward model a partire da traiettorie messe a confronto.

json
{
  "id": "task_001",
  "annotator": "observer_01",
  "root_branch": {
    "branch_id": "main",
    "steps": [
      {"step": 0, "type": "file_read", "file": "src/parser.py", "rating": "Good"},
      {"step": 1, "type": "edit", "file": "src/parser.py", "rating": "Incorrect"}
    ],
    "children": [
      {
        "branch_id": "branch_1",
        "branch_point": 1,
        "instruction": "Try a different approach -- use a try/except block instead",
        "steps": [
          {"step": 2, "type": "edit", "file": "src/parser.py", "rating": "Good"},
          {"step": 3, "type": "terminal", "command": "pytest", "rating": "Good"}
        ],
        "outcome": "Fully Complete",
        "children": []
      },
      {
        "branch_id": "branch_2",
        "branch_point": 1,
        "instruction": "Read the test file first to understand expected behavior",
        "steps": [
          {"step": 2, "type": "file_read", "file": "tests/test_parser.py", "rating": "Good"},
          {"step": 3, "type": "edit", "file": "src/parser.py", "rating": "Good"},
          {"step": 4, "type": "terminal", "command": "pytest", "rating": "Good"}
        ],
        "outcome": "Fully Complete",
        "children": []
      }
    ]
  },
  "branch_preference": "Branch B",
  "observation_notes": "Both branches solved the problem, but branch B produced cleaner code by reading the tests first."
}

Esporta le traiettorie con branching per l'apprendimento delle preferenze:

bash
# Export as DPO preference pairs from branch comparisons
python -m potato.export \
  -i output/ \
  -f branching_dpo \
  -o results/branch_preferences.jsonl
 
# Export full trajectory trees
python -m potato.export \
  -i output/ \
  -f trajectory_tree \
  -o results/trajectory_trees.jsonl

Sicurezza

Il live agent gira nella directory di progetto indicata nei dati del task. Può leggere, scrivere ed eseguire file dentro quella directory. Vale la pena adottare queste precauzioni:

  • Sandboxing: per codice non fidato o modelli di agente non fidati, esegui Potato dentro un container Docker o una VM. L'agente può eseguire comandi shell arbitrari, quindi l'isolamento conta.
  • Modalità di sola lettura: disabilita gli strumenti bash e write_file se vuoi che l'agente si limiti ad analizzare il codice senza modificarlo.
  • Restrizioni di rete: usa il flag --network none di Docker per impedire all'agente di fare richieste di rete.
  • Limiti di risorse: imposta max_steps e step_timeout_seconds per fermare gli agenti che scappano di mano.
yaml
# Restricted tool set for analysis-only tasks
live_agent:
  tools:
    - read_file
    - glob
    - grep
  # No edit_file, write_file, or bash

Risoluzione dei problemi

Ollama non è in esecuzione

text
Error: Connection refused at http://localhost:11434

Avvia il server Ollama:

bash
ollama serve

Verifica che sia attivo:

bash
ollama list

Chiave API mancante

text
Error: ANTHROPIC_API_KEY environment variable not set

Imposta la variabile d'ambiente:

bash
export ANTHROPIC_API_KEY="sk-ant-..."

Oppure aggiungila al file .env del progetto. Potato carica i file .env in automatico.

Git non inizializzato

text
Error: Project directory is not a git repository

Il sistema di checkpoint richiede git. Inizializza un repository nella directory del progetto:

bash
cd /path/to/project
git init
git add -A
git commit -m "Initial commit"

L'agente è bloccato in un ciclo

Se l'agente ripete più volte la stessa azione, potrebbe essersi impantanato. Potato rileva i cicli quando la stessa chiamata a uno strumento con gli stessi argomenti si ripete 3 volte, e mette l'agente in pausa da solo. La soglia è configurabile:

yaml
live_agent:
  loop_detection:
    enabled: true
    threshold: 3                     # pause after N identical consecutive steps
    action: pause                    # "pause" or "terminate"

Pulizia dei branch di sessione

Con il tempo i branch di sessione si accumulano. Ripuliscili ogni tanto:

bash
# Remove branches older than 7 days
python -m potato.cleanup_sessions --older-than 7d
 
# Remove all session branches
python -m potato.cleanup_sessions --all
 
# Dry run (show what would be deleted)
python -m potato.cleanup_sessions --older-than 7d --dry-run

Vedi anche

Per i dettagli implementativi, vedi la documentazione sorgente.