Skip to content

Live-Beobachtung von Coding-Agenten

Coding-Agenten in Echtzeit bei der Arbeit zusehen, mit Pause, Rollback und Verzweigung. Unterstützt werden drei Backends: Ollama für lokale Modelle, die Anthropic API und das Claude Agent SDK.

Neu in v2.4.0

Die Annotation statischer Traces zeigt, was ein Agent getan hat. Die Live-Beobachtung zeigt, was ein Agent tut, wenn ein Mensch eingreift. Im Live-Coding-Agent-Modus von Potato sehen Annotatoren einem Coding-Agenten in Echtzeit bei der Arbeit zu, während er Dateien liest, Code bearbeitet und Tests laufen lässt, und können jederzeit eingreifen: den Agenten anhalten, neue Anweisungen schicken, auf einen früheren Checkpoint zurücksetzen oder die Trajektorie verzweigen, um andere Lösungswege auszuprobieren.

Daraus entstehen reichhaltigere Annotationsdaten als aus statischen Traces allein. Man bekommt die vollständige Trajektorie mit Zeitstempeln, die Eingriffe des Annotators, die Verzweigungspunkte und Vergleichsdaten aus den alternativen Pfaden. Diese Daten sind unmittelbar brauchbar, um Process Reward Models, Präferenzmodelle und Evaluatoren für Instruction Following zu trainieren.

Voraussetzungen

  • Python 3.10+
  • Git (das Checkpoint-System arbeitet mit Git-Commits)
  • Eines der folgenden Agent-Backends:
    • Ollama für lokale Modellinferenz (kein API-Key nötig)
    • ANTHROPIC_API_KEY für den Zugriff auf die Anthropic API
    • Claude Agent SDK für die vollständige Claude-Code-Agent-Erfahrung

Backends

Potato unterstützt drei Backends zum Ausführen von Coding-Agenten. Jedes Backend startet den Agenten in einem Subprozess und streamt seine Aktionen in Echtzeit in die Annotationsoberfläche.

1. Ollama (lokale Modelle)

Coding-Agenten lokal ausführen, ohne API-Key. Ollama liefert schnelle Inferenz für Modelle mit offenen Gewichten. Am besten geeignet für Entwicklung, Tests und Situationen, in denen die Daten den lokalen Rechner nicht verlassen dürfen.

Einrichtung:

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

Konfiguration:

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. Anthropic API

Claude-Modelle über die Anthropic API nutzen. Bietet starke Coding-Leistung samt Tool-Nutzung. Erfordert einen API-Key.

Einrichtung:

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

Konfiguration:

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

Das Claude Agent SDK bietet die vollständige Claude-Code-Agent-Erfahrung, samt automatischer Tool-Orchestrierung, Kontextverwaltung und dateiübergreifendem Reasoning. Das ist das leistungsfähigste Backend, setzt aber voraus, dass das SDK installiert ist.

Einrichtung:

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

Konfiguration:

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

Bedienelemente

Die Annotationsoberfläche bietet vier Steueraktionen, mit denen Annotatoren das Verhalten des Agenten lenken.

Pause / Fortsetzen

Ein Klick auf Pause hält den Agenten zwischen zwei Schritten an. Der Agent beendet den laufenden Schritt und wartet. Der Annotator kann den aktuellen Zustand prüfen, Dateien ansehen und entscheiden, ob der Agent weitermachen soll oder ob eingegriffen wird. Ein Klick auf Fortsetzen lässt den Agenten weiterlaufen.

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"

Anweisungen senden

Solange der Agent pausiert, können Annotatoren neue Anweisungen schicken, die ihn umlenken. Das hilft, wenn der Agent den falschen Weg einschlägt oder wenn der Annotator testen will, wie er auf Hinweise reagiert.

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"

Anweisungen werden in den Konversationskontext des Agenten eingefügt. Die Option inject_as legt fest, ob sie als System-Nachricht (verbindliche Anweisung) oder als Nutzer-Nachricht (Hinweis im Gespräch) erscheinen.

Rollback

Ein Rollback setzt das Projekt auf einen früheren Git-Checkpoint zurück. Jede Dateiänderung des Agenten wird automatisch committet, sodass der Annotator jeden früheren Schritt in der Zeitleiste anklicken und genau diesen Zustand wiederherstellen kann. Der Konversationskontext des Agenten wird passend gekürzt.

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"

Verzweigen und erneut abspielen

Verzweigen und erneutes Abspielen kombiniert Rollback mit dem Senden von Anweisungen. Der Annotator setzt auf einen Checkpoint zurück und schickt andere Anweisungen, wodurch eine verzweigte Trajektorie entsteht. Das hilft beim Sammeln von Präferenzdaten: Zwei verschiedene Vorgehensweisen lassen sich vom selben Ausgangspunkt aus erkunden und im Ergebnis vergleichen.

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"

Die Vergleichsansicht stellt zwei Branches nebeneinander und hebt hervor, wo sie auseinanderlaufen. Annotatoren können bewerten, welcher Branch das bessere Ergebnis geliefert hat, und erzeugen damit Präferenzpaare für DPO-Training.

Das Git-Checkpoint-System

Der Live-Agent-Modus verfolgt jede Dateiänderung mit Git. Das macht Rollback, Verzweigung und die vollständige Änderungshistorie zuverlässig.

So funktioniert es

  1. Bevor der Agent startet, legt Potato einen neuen Git-Branch namens potato-session-{session_id} an
  2. Nach jeder Dateiänderung (Bearbeiten, Schreiben, Anlegen, Löschen) committet Potato automatisch mit einer beschreibenden Nachricht
  3. Jeder Commit wird als Checkpoint markiert und erscheint in der Zeitleiste
  4. Der Rollback stellt das Arbeitsverzeichnis per git checkout auf einen beliebigen Checkpoint zurück
  5. Beim Verzweigen entsteht aus dem Checkpoint-Commit ein neuer Git-Branch

Konfiguration

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

Checkpoints von Hand verwalten

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

Datenformat

Die Eingabedaten für Live-Coding-Agent-Aufgaben legen die Aufgabenbeschreibung fest und optional eine Startdatei oder ein Startverzeichnis:

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"
  ]
}
FeldPflichtBeschreibung
idJaEindeutige Kennung der Aufgabe
task_descriptionJaWas der Agent tun soll
project_dirJaPfad zum Projektverzeichnis
start_fileNeinDatei, die dem Agenten anfangs gezeigt wird
test_commandNeinKommando zur Überprüfung der Korrektur
context_filesNeinDateien, die vorab in den Kontext des Agenten geladen werden

Konfigurationsreferenz

Vollständige Konfiguration für eine Aufgabe zur Live-Beobachtung eines Coding-Agenten:

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"

Export verzweigter Trajektorien

Wird Verzweigen und erneutes Abspielen genutzt, enthält die Ausgabe den vollständigen Verzweigungsbaum. Dieses Format ist darauf ausgelegt, Präferenzmodelle und Process Reward Models aus vergleichenden Trajektorien zu trainieren.

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."
}

Verzweigte Trajektorien für Präferenzlernen exportieren:

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

Sicherheit

Der Live-Agent läuft in dem Projektverzeichnis, das in den Aufgabendaten angegeben ist. Er darf Dateien innerhalb dieses Verzeichnisses lesen, schreiben und ausführen. Dazu ein paar Sicherheitshinweise:

  • Sandboxing: Bei nicht vertrauenswürdigem Code oder nicht vertrauenswürdigen Agent-Modellen sollte Potato in einem Docker-Container oder einer VM laufen. Der Agent kann beliebige Shell-Kommandos ausführen, deshalb zählt die Isolation.
  • Nur-Lesen-Modus: Die Tools bash und write_file abschalten, wenn der Agent Code nur analysieren und nicht verändern soll.
  • Netzwerkbeschränkungen: Mit dem Docker-Flag --network none verhindern, dass der Agent Netzwerkanfragen stellt.
  • Ressourcengrenzen: max_steps und step_timeout_seconds setzen, damit ein Agent nicht außer Kontrolle gerät.
yaml
# Restricted tool set for analysis-only tasks
live_agent:
  tools:
    - read_file
    - glob
    - grep
  # No edit_file, write_file, or bash

Fehlerbehebung

Ollama läuft nicht

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

Den Ollama-Server starten:

bash
ollama serve

Prüfen, ob er läuft:

bash
ollama list

API-Key fehlt

text
Error: ANTHROPIC_API_KEY environment variable not set

Die Umgebungsvariable setzen:

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

Oder in die .env-Datei des Projekts eintragen. Potato lädt .env-Dateien automatisch.

Git nicht initialisiert

text
Error: Project directory is not a git repository

Das Checkpoint-System braucht Git. Im Projektverzeichnis ein Repository initialisieren:

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

Agent hängt in einer Schleife

Wiederholt der Agent mehrfach dieselbe Aktion, hängt er möglicherweise fest. Potato erkennt Schleifen, wenn derselbe Tool-Aufruf mit denselben Argumenten dreimal wiederholt wird, und pausiert den Agenten dann automatisch. Der Schwellenwert lässt sich anpassen:

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

Session-Branches aufräumen

Mit der Zeit sammeln sich Session-Branches an. Sie sollten regelmäßig aufgeräumt werden:

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

Siehe auch

Implementierungsdetails stehen in der Quelldokumentation.