Skip to content
Leitfäden11 Min. Lesezeit

Web-Browsing-Agenten annotieren: Von WebArena-Traces zur menschlichen Evaluierung

Wie man mit Potatos Web-Agent-Trace-Anzeige autonome Web-Browsing-Agenten evaluiert, mit schrittweisen Screenshots, SVG-Overlays und Annotationsschemata pro Schritt.

Potato Team

Konvertieren Sie den Trace des Agenten in Potatos Web-Agent-Format, zeigen Sie ihn mit dem Viewer web_agent_trace an, sodass jeder Screenshot ein Overlay trägt, das zeigt, wo der Agent geklickt hat, und bewerten Sie die Schritte mit einem trajectory_eval-Schema.

Ein Web-Browsing-Agent wird nach den Aktionen beurteilt, die er auf einer Seite ausführt. Die Evaluierung braucht deshalb beide Hälften jedes Schritts, den Seitenzustand, den der Agent gesehen hat, und die Aktion, die er darauf ausgeführt hat. Ein Aktionsprotokoll allein trägt das Urteil nicht. „Clicked element product-101“ sagt einem Prüfer nicht, ob das der günstigste Laptop auf der Seite war, und ein Screenshot ohne Markierung lässt ihn raten, welcher von einem Dutzend Links das Ziel war.

Dieser Leitfaden richtet diese Evaluierung für WebArena-Traces ein. Derselbe Weg funktioniert für VisualWebArena, Mind2Web, Protokolle von Anthropic Computer Use und rohe Browser-Aufzeichnungen, da ein einziger Konverter sie alle abdeckt. Die vollständige Konfigurationsreferenz finden Sie in der Quelldokumentation.

Was Sie brauchen

bash
pip install potato-annotation

Außerdem brauchen Sie die Traces selbst, bei WebArena also Screenshots plus ein JSON-Aktionsprotokoll pro Episode. VisualWebArena zeichnet dieselbe Struktur mit zusätzlichen Informationen zur visuellen Verankerung auf, und rohe Browser-Aufzeichnungen enthalten stattdessen Viewport- und Mauspfaddaten.

Was ein roher WebArena-Trace enthält

Eine WebArena-Episode enthält die Aufgabenbeschreibung, die Aktionsfolge und den Pfad zu jedem Screenshot:

json
{
  "trace_id": "wa_001",
  "task": "Find the cheapest laptop on the electronics store and add it to the cart",
  "website": "shopping",
  "steps": [
    {
      "step": 0,
      "url": "http://shop.example.com/",
      "action_type": "click",
      "action_target": "Electronics category link",
      "element_id": "nav-electronics",
      "coordinates": [245, 82],
      "screenshot": "screenshots/wa_001_step_00.png"
    },
    {
      "step": 1,
      "url": "http://shop.example.com/electronics",
      "action_type": "click",
      "action_target": "Laptops subcategory",
      "element_id": "cat-laptops",
      "coordinates": [180, 310],
      "screenshot": "screenshots/wa_001_step_01.png"
    }
  ],
  "success": true
}

Den Trace konvertieren

Potatos Viewer liest ein normalisiertes Schrittformat statt des jeweils eigenen Formats jedes Frameworks, deshalb laufen die rohen Episoden zuerst durch den Konverter:

bash
python -m potato.trace_converter -i traces.json -f web_agent -o data/web_traces.jsonl

Das schreibt eine Instanz pro Episode. Jeder Schritt trägt step_index, screenshot_url, action_type, das Ziel-element und seine Bounding Box, coordinates, einen optionalen mouse_path sowie thought und observation des Agenten, sofern das Quellprotokoll sie aufgezeichnet hat. Ersetzt man -f web_agent durch --auto-detect, erkennt der Konverter das Format selbst. Diese Option ist die richtige, wenn ein Verzeichnis Traces aus mehr als einem Framework enthält.

Die Projektkonfiguration

Der Viewer ist ein Anzeigetyp und kein Annotationstyp. Er gehört daher unter instance_display.fields, und die Annotationsschemata bleiben von ihm getrennt. Die Screenshot-Größe ist die Einstellung, die man zuerst festlegen sollte. Bei 900 Pixeln Breite bleibt eine vollständige Desktop-Seite lesbar, ohne die Annotationssteuerungen unten aus dem Bildschirm zu schieben.

yaml
annotation_task_name: "WebArena Agent Evaluation"
task_dir: "."
 
data_files:
  - "data/web_traces.jsonl"
 
item_properties:
  id_key: id
  text_key: task_description
 
output_annotation_dir: "output/"
export_annotation_format: "jsonl"
 
instance_display:
  layout:
    direction: vertical
    gap: 16px
  fields:
    - key: task_description
      type: text
      label: "Task"
 
    - key: steps
      type: web_agent_trace
      label: "Agent Browsing Trace"
      display_options:
        show_overlays: true
        show_filmstrip: true
        show_thought: true
        show_observation: true
        show_element_info: true
        screenshot_max_width: 900
        screenshot_max_height: 600
        filmstrip_size: 80
 
annotation_schemes:
  - annotation_type: radio
    name: task_success
    description: "Did the agent complete the task?"
    labels:
      - "Success"
      - "Partial success"
      - "Failure"
    label_requirement:
      required: true
 
  - annotation_type: radio
    name: task_efficiency
    description: "Was the agent's path to the goal efficient?"
    labels:
      - "Optimal path"
      - "Reasonable but not optimal"
      - "Inefficient, unnecessary steps"
      - "Completely wrong direction"
    label_requirement:
      required: true
 
  - annotation_type: trajectory_eval
    name: step_evaluation
    description: "Judge each action against the task"
    steps_key: steps
    step_text_key: action_type
    correctness_options:
      - correct
      - acceptable
      - incorrect
      - unnecessary
    error_types:
      - name: wrong_element_clicked
      - name: wrong_page_navigated_to
      - name: missed_better_option
      - name: incorrect_form_input
      - name: premature_completion
      - name: unnecessary_navigation
      - name: failed_to_scroll
      - name: wrong_page_section
      - name: other
    severities:
      - name: minor
        weight: -1
      - name: major
        weight: -5
      - name: critical
        weight: -10
    show_score: true
    max_score: 100
 
user_config:
  allow_all_users: true

Ein einziges trajectory_eval-Schema deckt den gesamten Durchgang pro Schritt ab. Es stellt jeden Schritt als Karte dar und erfasst auf jeder die Korrektheit, einen Fehlertyp, einen Schweregrad und eine schriftliche Begründung. Anschließend berechnet es aus den Schweregrad-Gewichten einen Qualitätswert für den ganzen Trace. Mit den obigen Gewichten kostet ein schwerer Fehler den Trace fünf Punkte und ein kritischer zehn. Legen Sie sie bewusst fest, denn sie entscheiden, wie ein Trace mit einem ernsten Fehler gegenüber einem Trace mit vier kleinen eingestuft wird.

Was der Annotator sieht

Web-Agent-Trace-Viewer in Potato

Der Screenshot des aktuellen Schritts füllt das Hauptfenster, darüber sind SVG-Overlays gezeichnet. Jedes Overlay markiert einen anderen Teil des Schritts, und ihre Farben sind fest:

OverlayMarkiert
Roter Kreis mit FadenkreuzDie Klickkoordinaten
Gelbe HervorhebungDas Feld, in das der Agent getippt hat
Grüner PfeilRichtung und Ausmaß eines Scrollvorgangs
Blaues gestricheltes RechteckDie Bounding Box des Zielelements
Orangefarbene KurveDer Mauspfad zum Ziel

Am unteren Rand verläuft ein Filmstreifen mit Miniaturansichten, und ein Klick auf eine davon springt zu diesem Schritt. Bei Traces mit mehr als etwa zehn Schritten macht der Filmstreifen den Unterschied zwischen einem Prüfer, der die Gestalt des Durchlaufs sieht, und einem, der blind scrollt. Das Detailfenster des Schritts zeigt die Elementinformationen, die eigene Überlegung des Agenten und die von ihm aufgezeichnete Beobachtung. Jedes davon lässt sich in display_options abschalten, wenn das Quellprotokoll dort nichts Brauchbares enthält.

Eine Reihe von Kontrollkästchen unter dem Viewer schaltet die Overlays ein und aus:

SteuerungOverlay
ClicksDas rote Klick-Fadenkreuz
Bounding BoxesDas blaue gestrichelte Rechteck
Mouse PathDie orangefarbene Kurve
ScrollDer grüne Scrollpfeil

Overlays abzuschalten ist auf dichten Seiten wichtig, wo eine Klickmarkierung genau auf dem Text liegen kann, der verrät, ob der Klick richtig war. Beachten Sie, dass die gelbe Eingabe-Hervorhebung keine eigene Steuerung hat. Vier der fünf Overlays lassen sich einzeln schalten, die Hervorhebung des Eingabefelds wird immer gezeichnet. Dieser Viewer hat keine Tastenkürzel, die Navigation zwischen Schritten läuft also über den Filmstreifen und die Schrittsteuerung.

Der Annotationsdurchgang

Ein Prüfer bearbeitet einen Trace in fünf Schritten:

  1. Die Aufgabenbeschreibung lesen. Alles Weitere ist ein Urteil im Verhältnis zu ihr.
  2. Den Filmstreifen überfliegen. Die Gestalt des Durchlaufs erfassen, bevor irgendetwas bewertet wird, damit ein früher Schritt nicht auf Grundlage von Hinweisen als korrekt markiert wird, die erst später auftauchen.
  3. Die Schritte durchgehen. Für jeden Schritt den Seitenzustand lesen, am Overlay prüfen, worauf der Agent eingewirkt hat, und die Aktion bewerten. Ist sie falsch, Fehlertyp und Schweregrad wählen und in der Begründung angeben, was der Agent stattdessen hätte tun sollen.
  4. Den Trace bewerten. Gesamterfolg und Effizienz beurteilen, sobald alle Schritte gesehen wurden.
  5. Absenden und weitermachen.

Die vier Korrektheitsoptionen teilen die Schritte entlang der Linie, die für Trainingsdaten zählt. Korrekte Aktionen bewegen sich auf die erwartete Weise auf das Ziel zu. Akzeptable Aktionen kommen auf einem langsameren Weg voran, etwa über eine Kategorieseite statt über das Suchfeld. Inkorrekte Aktionen sind Fehler, etwa ein falsches Element, eine irrelevante Seite oder falscher Text in einem Formular. Unnötige Aktionen helfen weder noch schaden sie, etwa ein Klick, auf den sofort eine Zurück-Navigation folgt. Es lohnt sich, sie von Fehlern zu trennen, denn ein Agent, der umherirrt, ist ein anderes Problem als ein Agent, der falsch liegt.

Die Fehlertaxonomie

Fehlertypen machen aus einem Haufen gescheiterter Traces etwas, woraus ein Agentenentwickler Konsequenzen ziehen kann. Die Kategorien sollten deshalb unterscheidbaren Ursachen entsprechen und nicht Graden der Falschheit:

FehlertypBedeutungBeispiel
Falsches Element angeklicktDer Agent hat auf das falsche UI-Element eingewirkt„Tablets“ statt „Laptops“ angeklickt
Zur falschen Seite navigiertDer Agent ist an einer irrelevanten Stelle gelandetZu „About Us“ statt zur Produktliste navigiert
Bessere Option verpasstEine bessere Aktion war verfügbarKategorien durchsucht, obwohl das Suchfeld direkt da war
Falsche FormulareingabeDer Agent hat den falschen Text eingegebenNach „labtop“ statt „laptop“ gesucht
Vorzeitiger AbschlussDer Agent hat zu früh Erfolg gemeldetDen falschen Artikel in den Warenkorb gelegt und aufgehört
Unnötige NavigationDer Schritt trägt nicht zum Ziel beiZwischen zwei Kategorieseiten die Startseite besucht
Nicht gescrolltDas Ziel lag unterhalb des ViewportsDas Element war nie sichtbar, und der Agent hat nie gescrollt
Falscher SeitenbereichRichtige Seite, falscher BereichDie Kopfzeile statt des Hauptinhalts angeklickt

Schwierige Traces bearbeiten

Bei einem Trace mit mehr als fünfzehn Schritten verbraucht es den Großteil der Mühe für offensichtlich unproblematische Schritte, wenn man jeden Schritt gleich gründlich bewertet. Überfliegen Sie den Filmstreifen nach den drei Mustern, die auf ein Problem hinweisen, und konzentrieren Sie die Mühe dort. Diese Muster sind eine URL, die sich unerwartet ändert, ein Schritt, in dem der Agent zurückgeht, und eine Folge nahezu identischer Screenshots, was meist bedeutet, dass der Agent in einer Schleife feststeckt.

Bei einem gescheiterten Trace ist der erste inkorrekte Schritt die Annotation, die stimmen muss. Alles danach geschieht in einem Zustand, den der Agent nie hätte erreichen dürfen, daher beschreiben die späteren Fehler die Folgen und nicht die Ursache.

Manche Aktionen lassen sich nicht allein anhand des Screenshots beurteilen, meist dann, wenn sich am Klickpunkt mehrere Elemente überlagern. Die Elementinformationen im Schrittfenster liefern Tag, Text und Bounding Box des Ziels, was normalerweise reicht, um zu klären, was tatsächlich angeklickt wurde; show_element_info hält dieses Fenster sichtbar.

VisualWebArena

VisualWebArena-Traces laufen durch denselben Konverter, der beide Formate an den Feldern action_type und element in ihren Aktionsschritten erkennt. Die Verankerungsinformationen dieser Traces erscheinen als Bounding-Box-Overlay. Ein Durchgang mit Fokus auf die Verankerung hängt also davon ab, was die Annotatoren auf dem Bildschirm lassen, und nicht von einer Änderung der Konfiguration. Lässt man Bounding Boxes angehakt und entfernt den Haken bei Clicks, zeigt die Ansicht, ob der Agent das richtige Element getroffen hat und nicht bloß das richtige Pixel.

Die Ergebnisse lesen

Fehler von Web-Agenten häufen sich tendenziell an bestimmten Stellen eines Traces, und die Fehlerrate nach Schrittposition zeigt am schnellsten, wo. Jede trajectory_eval-Annotation speichert eine Liste von Datensätzen pro Schritt, jeweils mit step_index und correctness:

python
import json
 
annotations = []
with open("output/exports/jsonl/annotations.jsonl") as f:
    for line in f:
        annotations.append(json.loads(line))
 
step_counts = {}
for ann in annotations:
    evaluation = ann["labels"].get("step_evaluation", {})
    for step in evaluation.get("steps", []):
        pos = step["step_index"]
        counts = step_counts.setdefault(pos, {})
        label = step.get("correctness", "unrated")
        counts[label] = counts.get(label, 0) + 1
 
print("Error rate by step position:")
for pos in sorted(step_counts):
    counts = step_counts[pos]
    total = sum(counts.values())
    errors = counts.get("incorrect", 0) + counts.get("unnecessary", 0)
    print(f"  Step {pos}: {errors / total:.1%} error rate ({total} observations)")

Die Verteilung der Fehlertypen beantwortet die andere Frage, nämlich was der Agent falsch macht und nicht wann:

python
error_counts = {}
for ann in annotations:
    evaluation = ann["labels"].get("step_evaluation", {})
    for step in evaluation.get("steps", []):
        error = step.get("error_type")
        if error:
            error_counts[error] = error_counts.get(error, 0) + 1
 
for error, count in sorted(error_counts.items(), key=lambda x: -x[1]):
    print(f"  {error}: {count}")

Die Evaluierung skalieren

Für ein Ergebnis, das Sie veröffentlichen wollen, reicht ein Prüfer pro Trace nicht, denn die Urteile pro Schritt tragen genau die Art von Mehrdeutigkeit, für deren Messung es Übereinstimmungsstatistiken gibt. Legen Sie das Abdeckungsziel und die Zuweisungsreihenfolge auf der obersten Ebene der Konfiguration fest:

yaml
num_annotators_per_item: 3
assignment_strategy: random

Vergleichen Sie dann die Annotatoren beim Label auf Trace-Ebene, bei dem eine Abweichung eindeutig ist. Exportieren Sie zuerst nach Parquet, damit der Vergleich über Spalten statt über geparstes JSON läuft:

bash
python -m potato.export -c config.yaml -f parquet -o ./parquet_export/
python
from sklearn.metrics import cohen_kappa_score
import pandas as pd
 
df = pd.read_parquet("parquet_export/annotations.parquet")
success = df[df["schema_name"] == "task_success"]
pivot = success.pivot(index="instance_id", columns="annotator", values="value")
 
annotators = pivot.columns.tolist()
for i in range(len(annotators)):
    for j in range(i + 1, len(annotators)):
        pair = pivot[[annotators[i], annotators[j]]].dropna()
        kappa = cohen_kappa_score(pair[annotators[i]], pair[annotators[j]])
        print(f"Kappa ({annotators[i]} vs {annotators[j]}): {kappa:.3f}")

Bei Evaluierungen mit Hunderten von Traces stellt Solo Mode ein Modell in dieselbe Warteschlange wie den menschlichen Prüfer. Das Modell schlägt Labels vor, und der Mensch korrigiert sie, bis beide oft genug übereinstimmen, damit das Modell den Rest übernehmen kann:

yaml
solo_mode:
  enabled: true
  labeling_models:
    - endpoint_type: "anthropic"
      model: "claude-sonnet-4-20250514"
      api_key: "${ANTHROPIC_API_KEY}"
  thresholds:
    end_human_annotation_agreement: 0.90
    minimum_validation_sample: 50

Über den Übereinstimmungsschwellenwert sollte man nachdenken, nicht über die Modellwahl. Bei 0,90 annotiert der Mensch weiter, bis neun von zehn Labels des Modells mit seinen übereinstimmen, gemessen über mindestens fünfzig Vergleiche. Ein niedrigerer Wert tauscht Labelqualität gegen Prüfstunden, und zwar auf eine Weise, die sich im Nachhinein schwer erkennen lässt.

Weiterführende Literatur