Guarda, metti in pausa, torna indietro: osservazione dal vivo dei coding agent in Potato
Tutorial per configurare l'osservazione dal vivo dei coding agent con Ollama, l'API di Anthropic o il Claude Agent SDK. Comprende pausa, rollback, branching ed esportazione delle traiettorie.
Che cosa cambia con l'osservazione dal vivo
Quasi tutta la valutazione dei coding agent avviene a cose fatte: l'agente gira, produce una traccia e i revisori si mettono a spulciare la registrazione più tardi. L'osservazione dal vivo funziona al contrario. L'annotatore guarda l'agente lavorare in tempo reale e vede ogni modifica ai file, ogni comando da terminale e ogni passo di ragionamento nel momento in cui arriva.
Questo cambia le cose che puoi fare. Se l'agente imbocca la strada sbagliata, l'annotatore può intervenire prima che ci perda tempo. Può mettere in pausa per leggere con calma un diff prima che l'agente vada avanti, o mandargli un'istruzione in linguaggio naturale per reindirizzarlo. La parte che trovo più utile è il rollback: da qualsiasi checkpoint precedente puoi tornare indietro e lasciare che l'agente provi un approccio diverso. Quelle diramazioni sono esattamente il tipo di dati che serve all'apprendimento delle preferenze.
Non sostituisce l'annotazione di tracce statiche. È una modalità diversa che produce dati di natura diversa. L'annotazione statica vince quando ne vuoi tanta a un costo prevedibile. L'osservazione dal vivo vince quando cerchi dati mirati, quando vuoi capire come fallisce un agente o quando costruisci coppie di preferenza per branching.
Per il riferimento completo della funzionalità, vedi la documentazione sorgente.
L'interfaccia del live coding agent trasmette le azioni dell'agente in tempo reale, mostrando i diff del codice e l'output del terminale mentre l'agente lavora:
Osservazione dal vivo di un coding agent con rendering dei diff e output del terminale in tempo reale
Tre backend
Potato ti dà tre backend per l'osservazione dal vivo. Ognuno esegue un coding agent in una sandbox e trasmette le sue azioni all'interfaccia mentre accadono.
Ollama (tutto in locale)
Il backend Ollama gira interamente sulla tua macchina, senza chiavi API e senza chiamate di rete. È quello da usare quando la codebase è sensibile o quando vuoi solo sperimentare senza far salire il conto dell'API.
Per prima cosa, installa Ollama e scarica un modello capace di usare gli strumenti:
# 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 listConfigura Potato per usare il backend Ollama:
# config.yaml
project_name: "Live Agent Observation - Ollama"
port: 8000
live_coding_agent:
enabled: true
backend: "ollama"
ollama:
model: "qwen2.5-coder:32b"
host: "http://localhost:11434"
temperature: 0.2
max_tokens: 4096
num_ctx: 32768 # Context window size
sandbox:
type: "docker" # "docker" or "local"
image: "python:3.11-slim" # Base image for sandboxed execution
workspace: "./workspace/" # Agent's working directory
timeout: 600 # Max seconds per agent session
streaming:
update_interval_ms: 100 # How often to push updates to the UI
buffer_output: true # Buffer terminal output for smoother rendering
checkpoints:
enabled: true
strategy: "git" # Git-based checkpoints
auto_commit_on_file_change: true
commit_message_prefix: "[potato-checkpoint]"API di Anthropic (Claude con uso di strumenti)
Il backend dell'API di Anthropic si collega ai modelli Claude con l'uso di strumenti. Ottieni ragionamento e generazione di codice migliori di quelli della maggior parte dei modelli locali, e in cambio paghi le chiamate API.
# Set your API key
export ANTHROPIC_API_KEY="sk-ant-..."# config.yaml
project_name: "Live Agent Observation - Claude"
port: 8000
live_coding_agent:
enabled: true
backend: "anthropic"
anthropic:
model: "claude-sonnet-4-20250514"
api_key_env: "ANTHROPIC_API_KEY"
max_tokens: 8192
temperature: 0.1
tools:
- "file_read"
- "file_edit"
- "bash_command"
- "directory_list"
- "file_search"
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.
sandbox:
type: "docker"
image: "python:3.11-slim"
workspace: "./workspace/"
timeout: 900
allowed_commands: # Whitelist for bash commands
- "python"
- "pip"
- "pytest"
- "git"
- "ls"
- "cat"
- "find"
- "grep"
streaming:
update_interval_ms: 50
show_thinking: true # Show Claude's thinking in real time
checkpoints:
enabled: true
strategy: "git"
auto_commit_on_file_change: trueClaude Agent SDK (tutte le capacità di Claude Code)
Il backend Claude Agent SDK è il più capace dei tre, con l'insieme completo degli strumenti di Claude Code e comportamento autonomo. Richiede il pacchetto claude-agent-sdk.
# Install the Claude Agent SDK
pip install claude-agent-sdk# config.yaml
project_name: "Live Agent Observation - Claude Agent SDK"
port: 8000
live_coding_agent:
enabled: true
backend: "claude_agent_sdk"
claude_agent_sdk:
api_key_env: "ANTHROPIC_API_KEY"
model: "claude-sonnet-4-20250514"
max_turns: 50 # Maximum number of agent turns
permission_mode: "auto" # "auto", "ask", or "restricted"
allowed_tools:
- "Read"
- "Edit"
- "Write"
- "Bash"
- "Glob"
- "Grep"
restricted_commands: # Bash commands to block
- "rm -rf /"
- "sudo"
- "curl"
- "wget"
sandbox:
type: "docker"
image: "node:20-slim"
workspace: "./workspace/"
timeout: 1200
mount_volumes:
- "./test-repo:/workspace/repo"
streaming:
update_interval_ms: 50
show_thinking: true
show_tool_inputs: true
checkpoints:
enabled: true
strategy: "git"
auto_commit_on_file_change: true
max_checkpoints: 100Il flusso di annotazione
Una volta avviato il server, una sessione di osservazione dal vivo passa per qualche fase.
Avviare una sessione
L'annotatore apre l'interfaccia di Potato e trova un campo per la descrizione del task. Ci incolla o ci scrive il compito che l'agente deve svolgere, per esempio «Correggi il test che fallisce in tests/test_parser.py a causa del nuovo formato di configurazione» oppure «Aggiungi il supporto alla paginazione all'endpoint /api/users».
# Start the server
potato start config.yaml -p 8000L'annotatore clicca su «Start Agent» e il coding agent si mette al lavoro. Ogni azione compare in tempo reale nel pannello CodingTraceDisplay.
Guardare l'agente lavorare
Mentre l'agente gira, ogni passo compare nel visualizzatore della traccia:
- I passi di ragionamento compaiono come blocchi grigi richiudibili con il ragionamento dell'agente.
- Le letture di file compaiono come blocchi di codice con evidenziazione della sintassi, numeri di riga e percorso del file.
- Le modifiche ai file compaiono come diff unificati con evidenziazione in rosso e verde.
- I comandi da terminale compaiono come blocchi scuri di terminale con comando, output ed exit code.
- L'albero dei file si aggiorna nella sidebar man mano che i file vengono creati, modificati o letti.
In alto un indicatore di avanzamento mostra il numero del passo corrente e il tempo trascorso. Lo stato dell'agente compare come «Thinking...», «Editing file...», «Running command...» e simili.
Controlli di pausa e istruzioni
Mentre l'agente è in esecuzione, l'annotatore può intervenire dalla barra dei controlli:
Pause: blocca l'agente appena il passo corrente è finito. L'agente non passa al successivo finché non riprende. Serve per esaminare con calma un diff o l'output del terminale prima che l'agente vada avanti.
Send Instruction: con l'agente in pausa (o anche in esecuzione), scrivi un messaggio in linguaggio naturale che viene iniettato nel contesto dell'agente. Per esempio: «Non modificare lo schema del database, usa una migrazione» oppure «Controlla il log degli errori in /var/log/app.log prima di fare modifiche».
Resume: riprende l'esecuzione dell'agente dopo una pausa.
Stop: termina del tutto la sessione dell'agente. La traiettoria fino a quel punto viene salvata.
Gli annotatori possono valutare il lavoro dell'agente con l'annotazione PRM affiancata al display della traccia:
Interfaccia di annotazione PRM per etichettare la correttezza passo per passo accanto alla traccia di codice
# Control bar configuration
live_coding_agent:
controls:
pause_enabled: true
instruction_enabled: true
stop_enabled: true
rollback_enabled: true
branch_enabled: true
pause_keyboard_shortcut: "Space"
instruction_keyboard_shortcut: "i"Il sistema di checkpoint su git
Il sistema di checkpoint è ciò che fa funzionare tutto il resto. Rollback, branching ed esportazione delle traiettorie si appoggiano a lui, e lui fa il suo lavoro committando su git dopo ogni modifica ai file fatta dall'agente.
Come funziona
All'avvio di una sessione, Potato inizializza un repository git nella workspace della sandbox, oppure usa quello già presente. Dopo ogni modifica a un file committa in automatico con un messaggio strutturato:
[potato-checkpoint] Step 7: Edit src/parser.py
- Modified lines 45-52
- Agent reasoning: Fix the regex pattern to handle escaped quotes
Ne esce una cronologia di commit lineare che corrisponde uno a uno ai passi della traiettoria. Ogni checkpoint cattura lo stato completo della workspace in quel momento.
# 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 stateRollback
Clicca su «Rollback» e scegli dal menu a tendina un checkpoint precedente qualsiasi. Potato riporta la workspace a quello stato con git checkout e riavvolge di conseguenza la visualizzazione della traiettoria, poi l'agente riparte da lì con il contesto tagliato fino a quel passo.
È la mossa da fare quando vedi l'agente prendere la strada sbagliata. Invece di lasciarlo correre e bruciare tempo, torni all'ultimo stato buono e lo lasci riprovare, magari con un'istruzione che lo spinge in una direzione migliore.
Traiettorie con branching
Il branching è un rollback che tiene entrambi i percorsi. Quando torni indietro e l'agente prende un'altra strada, Potato crea un branch git con un nome e traccia entrambe le traiettorie:
Step 0 → Step 1 → Step 2 → Step 3 → Step 4 (Branch A: original path)
↘
Step 3' → Step 4' → Step 5' (Branch B: after rollback)
Puoi diramare da qualsiasi checkpoint, costruendo un intero albero di traiettorie. Per l'apprendimento delle preferenze è oro colato, perché ogni coppia di branch è già un confronto etichettato: sei tornato indietro proprio perché avevi giudicato sbagliato il branch A, il che rende il branch B il percorso preferito dal punto di diramazione in avanti.
# Branching configuration
live_coding_agent:
branching:
enabled: true
max_branches_per_session: 10
auto_name_branches: true # "branch-A", "branch-B", etc.
require_reason_on_rollback: true # Annotator must explain why they rolled back
compare_branches_view: true # Side-by-side view of branch outcomesFormati di esportazione
Una sessione dal vivo produce dati dettagliati sulla traiettoria, che puoi esportare in forme diverse a seconda di che cosa stai addestrando.
Esportazione di traiettorie lineari
Esporta ogni branch come traiettoria indipendente:
potato export \
--format trajectories \
--project ./output/ \
--output ./training_data/trajectories.jsonl \
--flatten_branches true{
"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"
}Coppie di preferenza dai branch
Esporta le coppie di branch come dati di preferenza per DPO o RLHF:
potato export \
--format branch_preferences \
--project ./output/ \
--output ./training_data/branch_preferences.jsonl{
"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}
]
}Etichette PRM dall'osservazione dal vivo
Puoi affiancare all'osservazione dal vivo l'etichettatura PRM, dato che un punto di rollback di solito coincide con il passo del primo errore:
potato export \
--format prm_from_branches \
--project ./output/ \
--output ./training_data/prm_live.jsonlQui il passo da cui sei tornato indietro viene etichettato come primo errore, e i passi del nuovo branch vengono etichettati come corretti, visto che li hai accettati.
Dataset di code review
Esporta le istruzioni degli annotatori e le motivazioni dei rollback come dati di addestramento per la code review:
potato export \
--format code_review \
--project ./output/ \
--output ./training_data/code_review.jsonlQuick start completo
L'intera sequenza, da zero a una sessione Ollama funzionante:
# 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'
project_name: "Live Agent Observation"
port: 8000
live_coding_agent:
enabled: true
backend: "ollama"
ollama:
model: "qwen2.5-coder:32b"
host: "http://localhost:11434"
temperature: 0.2
num_ctx: 32768
sandbox:
type: "local"
workspace: "./workspace/repo"
timeout: 600
streaming:
update_interval_ms: 100
checkpoints:
enabled: true
strategy: "git"
auto_commit_on_file_change: true
controls:
pause_enabled: true
instruction_enabled: true
rollback_enabled: true
branch_enabled: true
branching:
enabled: true
max_branches_per_session: 5
require_reason_on_rollback: true
annotation_schemes:
- annotation_type: radio
name: outcome
label: "Final outcome"
options:
- value: "resolved"
text: "Task Fully Resolved"
- value: "partial"
text: "Partially Resolved"
- value: "failed"
text: "Failed"
- annotation_type: text_input
name: notes
label: "Session Notes"
placeholder: "Key observations about agent behavior..."
required: false
output:
path: "./output/"
format: "jsonl"
export_formats:
- "trajectories"
- "branch_preferences"
- "prm_from_branches"
annotators:
- username: "observer1"
password: "observer_pw_1"
YAML
# 5. Start Potato
potato start config.yaml -p 8000
# 6. Open http://localhost:8000 in your browserDopo il login, incolla un task come «Aggiungi la validazione dell'input all'endpoint POST /api/users» e clicca su «Start Agent». Guardalo lavorare, metti in pausa quando qualcosa non torna, manda istruzioni per indirizzarlo e torna indietro per provare altri approcci. Alla fine valuta l'esito e prendi qualche nota.
Buone pratiche
Parti da task chiari e ben delimitati. Il punto giusto sono compiti che tengono impegnato l'agente dai 5 ai 15 minuti. Sotto non esce abbastanza traiettoria da valere l'annotazione; molto sopra, l'annotatore si stanca.
In produzione usa la sandbox Docker. La modalità sandbox locale va bene mentre sviluppi, ma Docker impedisce all'agente di toccare il sistema host. Con modelli non fidati usala sempre.
Registra le motivazioni dei rollback. Attiva require_reason_on_rollback così ogni punto di diramazione porta con sé una nota umana su che cosa è andato storto. Quelle note sono già di per sé un segnale utile per l'addestramento, e migliorano i dati di preferenza.
Confronta più backend. Fai girare gli stessi task su Ollama, sull'API di Anthropic e sul Claude Agent SDK per ottenere dati di preferenza tra agenti diversi. Dato che cambia solo la sezione del backend nella configurazione, è facile da impostare.
Esporta presto e spesso. Fai un'esportazione dopo ogni sessione invece di rimandare tutto alla fine. Perdi meno se qualcosa va in crash, e tieni d'occhio la qualità dei dati strada facendo.