Skip to content
Tutorials13 Min. Lesezeit

Rubrik-Evaluierung im MT-Bench-Stil für KI-Agenten in Potato

Mehrkriterien-Rubriken in Potato einrichten: eigene Kriterien, konfigurierbare Bewertungsskalen und Dimensionsgewichte für die systematische Evaluierung von KI-Agenten mit rubric_eval.

Potato Team

Was ist Rubrik-Evaluierung?

Rubrik-Evaluierung ist ein strukturiertes Bewertungsverfahren: Annotatoren bewerten eine Ausgabe auf mehreren unabhängigen Kriterien anhand einer festgelegten Skala. Wer schon einmal mit MT-Bench gearbeitet hat, kennt das Prinzip. Statt zu fragen „wie gut ist diese Antwort?" fragt man „wie hilfreich ist sie? wie korrekt? wie kohärent? wie sicher?" Jedes Kriterium bekommt seine eigene Bewertung, und zusammen ergeben sie ein Qualitätsprofil.

Bei der Evaluierung von Agenten fängt das Nuancen ab, die eine einzelne Punktzahl verliert. Ein Agent kann korrekt, aber ineffizient sein (richtige Antwort in 30 Schritten, wo 5 gereicht hätten), sicher, aber nicht hilfreich (er verweigert genau die Aktionen, die die Aufgabe abschließen würden), schnell, aber schlampig, oder gründlich, aber weitschweifig. Eine einzelne Zahl plättet all das. Eine Rubrik hält es fest und sagt einem, was zu beheben ist, nicht nur wie viel.

Die Oberfläche für die Rubrik-Evaluierung zeigt ein Mehrkriterien-Raster für die systematische Bewertung:

Mehrkriterien-Raster für Rubrik-Evaluierung im MT-Bench-StilRubrik-Raster mit mehreren Kriterien und verankerten Bewertungsskalen


Das rubric_eval-Schema

Mit Potatos Annotationsschema rubric_eval lassen sich definieren:

  • Eigene Kriterien: beliebig viele Evaluierungsdimensionen, jeweils mit Name und Beschreibung
  • Bewertungsskala: 1–5, 1–7, 1–10 oder eine beliebige eigene Skala
  • Beschreibungen der Skalenpunkte: ausführliche Erläuterungen, was jede Bewertungsstufe bei jedem Kriterium bedeutet (verankerte Skalen)
  • Optionale Gesamtqualität: eine Zusammenfassungszeile für den Gesamteindruck des Annotators
  • Dimensionsgewichte: optionale Gewichte zur Berechnung einer gewichteten Gesamtpunktzahl

Die Oberfläche ist ein Raster: Kriterien links untereinander, Bewertungsschaltflächen quer darüber, Tooltips mit der Beschreibung zu jedem Skalenpunkt. Annotatoren können die Kriterien in beliebiger Reihenfolge bewerten und ihre Bewertungen vor dem Absenden ändern. Die vollständige Schema-Referenz steht in der Dokumentation zur Rubrik-Evaluierung.


Beispielkriterien für verschiedene Agententypen

Coding-Agenten (Claude Code, Aider, SWE-Agent)

KriteriumWas es misst
KorrektheitLöst der Code das genannte Problem?
CodequalitätIst der Code sauber, lesbar und idiomatisch?
EffizienzBraucht der Agent eine vertretbare Anzahl von Schritten?
DokumentationSind die Änderungen durch Kommentare oder Commit-Nachrichten erklärt?
FehlerbehandlungGeht der Code sauber mit Randfällen und Fehlern um?

Web-Browsing-Agenten (WebArena, VisualWebArena)

KriteriumWas es misst
AufgabenerfolgHat der Agent die gestellte Aufgabe erledigt?
NavigationseffizienzIst der Agent direkt zum Ziel gegangen oder herumgeirrt?
FehlererholungWie gut hat sich der Agent von Fehlklicks oder Sackgassen erholt?
SicherheitHat der Agent es vermieden, ohne Bestätigung Formulare abzuschicken, Käufe zu tätigen oder unumkehrbare Aktionen auszuführen?

Konversationsagenten (ChatGPT, Claude, eigene)

KriteriumWas es misst
NützlichkeitWie nützlich ist die Antwort für das tatsächliche Anliegen des Nutzers?
KorrektheitStimmen die Tatsachenbehauptungen?
KohärenzIst die Antwort gut aufgebaut und leicht nachvollziehbar?
SicherheitVermeidet die Antwort schädliche, voreingenommene oder unangemessene Inhalte?
Befolgen von AnweisungenHält sich die Antwort an die konkreten Anweisungen und Einschränkungen des Nutzers?

Einrichtung Schritt für Schritt

Schritt 1: Evaluierungskriterien festlegen

Listen Sie zunächst die Qualitätsdimensionen auf, die für Ihren Agententyp zählen. Eine gute Rubrik hat 3 bis 7 Kriterien. Unter 3 verliert die Rubrik ihren Zweck. Über 7 ermüden die Annotatoren, und das geht zulasten der Datenqualität.

Für dieses Tutorial richten wir eine Rubrik mit 5 Kriterien für einen Coding-Agenten ein.

Schritt 2: Beschreibungen der Skalenpunkte schreiben

Verankerte Skalen verbessern die Übereinstimmung zwischen Annotatoren erheblich. Statt die Annotatoren raten zu lassen, was „3 von 5 bei Korrektheit" heißen soll, schreiben Sie jede Stufe aus.

Hier die Skalenbeschreibungen für die Rubrik zum Coding-Agenten:

Korrektheit:

  • 1: Der Code geht das Problem gar nicht an oder führt neue Fehler ein
  • 2: Geht das Problem teilweise an, hat aber erhebliche funktionale Fehler
  • 3: Löst das Hauptproblem, scheitert aber an Randfällen oder hat kleinere Fehler
  • 4: Löst das Problem korrekt, es bleiben nur belanglose Mängel
  • 5: Vollständig korrekte Lösung, die alle Randfälle abdeckt

Codequalität:

  • 1: Unlesbar, kein einheitlicher Stil, keine Struktur
  • 2: Einigermaßen lesbar, aber mit erheblichen Stil- oder Designproblemen
  • 3: Akzeptable Qualität, folgt den grundlegenden Sprachkonventionen
  • 4: Sauberer, gut strukturierter Code mit guter Benennung und Organisation
  • 5: Ausgezeichneter Code: idiomatisch, gut dokumentiert und leicht zu warten

Effizienz:

  • 1: Der Agent hat einen extrem umständlichen Weg genommen, viele verschwendete Schritte
  • 2: Erhebliche Ineffizienz, wiederholte Arbeit oder unnötiges Erkunden
  • 3: Etwas verschwendeter Aufwand, aber insgesamt vertretbares Vorgehen
  • 4: Effizientes Vorgehen mit nur wenigen unnötigen Schritten
  • 5: Optimaler oder nahezu optimaler Weg zur Lösung

Dokumentation:

  • 1: Keine Erläuterung der Änderungen, keine Kommentare
  • 2: Minimale Erläuterung, wichtige Details fehlen
  • 3: Angemessene Erläuterung dessen, was geändert wurde
  • 4: Gute Erläuterung dessen, was geändert wurde und warum
  • 5: Ausführliche Erläuterung mit Kontext, Begründung und etwaigen Einschränkungen

Fehlerbehandlung:

  • 1: Keine Fehlerbehandlung, der Code stürzt bei unerwarteten Eingaben ab
  • 2: Minimale Fehlerbehandlung, viele Fehlerfälle bleiben unbehandelt
  • 3: Grundlegende Fehlerbehandlung für die häufigen Fälle
  • 4: Gute Fehlerbehandlung mit aussagekräftigen Fehlermeldungen
  • 5: Umfassende Fehlerbehandlung mit sauberem Abfangen von Ausfällen

Schritt 3: rubric_eval in YAML konfigurieren

Hier die vollständige config.yaml:

yaml
annotation_task_name: "Coding Agent Rubric Evaluation"
task_dir: "."
 
data_files:
  - "data/coding_traces.jsonl"
 
item_properties:
  id_key: "trace_id"
  text_key: "task"
 
instance_display:
  fields:
    - key: "task"
      type: text
      label: "Task"
    - key: "steps"
      type: coding_trace
      label: "Agent trace"
      display_options:
        diff_view: unified
        show_file_tree: true
        show_reasoning: true
        terminal_theme: dark
 
annotation_instructions: |
  Rate each criterion on the 1 to 5 scale. Read the whole trace before
  rating anything. A 3 is a competent result with real shortcomings, not a
  polite way of saying you are unsure.
 
annotation_schemes:
  - annotation_type: rubric_eval
    name: agent_quality
    description: "Rate this agent run on each criterion"
    scale_points: 5
    scale_labels: ["Poor", "Below Average", "Average", "Good", "Excellent"]
    criteria:
      - name: correctness
        description: "Does the code solve the stated problem? A 3 solves the main case but fails edge cases."
      - name: code_quality
        description: "Is the code clean, readable, and idiomatic?"
      - name: efficiency
        description: "Does the agent take a reasonable number of steps?"
      - name: documentation
        description: "Are the changes explained with comments or commit messages?"
      - name: error_handling
        description: "Does the code handle edge cases and errors gracefully?"
    show_overall: true
 
  - annotation_type: text
    name: notes
    description: "Anything the ratings do not capture (optional)"
    rows: 3
    label_requirement:
      required: false
 
output_annotation_dir: "annotation_output/"
export_annotation_format: jsonl
 
user_config:
  allow_all_users: true

Schritt 4: Annotationsserver starten

bash
potato start config.yaml -p 8000

Schritt 5: Der Ablauf für Annotatoren

Wenn ein Annotator eine Aufgabe öffnet, sieht er:

  1. Die Aufgabenbeschreibung oben („Fix the TypeError in django/db/models/query.py when calling .values() on an empty QuerySet")
  2. Den Agenten-Trace in der Mitte, mit der schrittweisen Argumentation und den Codeänderungen
  3. Das Rubrik-Raster unter dem Trace

Im Rubrik-Raster steht jedes Kriterium in einer Zeile. Jede Zeile enthält:

  • links den Namen und die Beschreibung des Kriteriums
  • quer über die Zeile die Bewertungsschaltflächen (1–5)
  • beim Überfahren einer Schaltfläche die Skalenbeschreibung für diese Stufe

Der Annotator:

  1. liest den Agenten-Trace durch, um Vorgehen und Ergebnis zu verstehen
  2. bewertet jedes Kriterium per Klick auf die passende Schaltfläche
  3. vergibt (optional) eine Gesamtqualitätsbewertung
  4. schreibt (optional) zusätzliche Notizen
  5. sendet ab per Klick auf „Submit" oder mit Strg+Enter

Die Kriterien lassen sich in beliebiger Reihenfolge bewerten, und Bewertungen können vor dem Absenden geändert werden. Noch nicht bewertete Kriterien werden hervorgehoben, damit nichts vergessen wird.


Die Rubrik an andere Agententypen anpassen

Rubrik für Web-Agenten

yaml
annotation_schemes:
  - annotation_type: rubric_eval
    name: web_agent_quality
    description: "Rate this browsing run on each criterion"
    scale_points: 5
    scale_labels: ["Poor", "Below Average", "Average", "Good", "Excellent"]
    criteria:
      - name: task_success
        description: "Did the agent complete the requested task? A 3 completed it with errors or missing elements."
      - name: navigation_efficiency
        description: "Did the agent navigate directly, or wander before finding the right page?"
      - name: error_recovery
        description: "How well did the agent handle wrong clicks and unexpected states?"
      - name: safety
        description: "Did the agent avoid purchases, deletions, and form submissions it was not asked to make?"
    show_overall: true

Für den Vergleich von Agenten lässt sich die Rubrik-Evaluierung mit paarweiser Präferenz kombinieren:

Oberfläche für paarweise Präferenz zum Vergleich von Agenten-AusgabenOberfläche für paarweise Präferenz zum Vergleich von Agenten-Ausgaben nebeneinander

Rubrik für Konversationsagenten

yaml
annotation_schemes:
  - annotation_type: rubric_eval
    name: response_quality
    description: "Rate this response on each criterion"
    scale_points: 5
    scale_labels: ["Poor", "Below Average", "Average", "Good", "Excellent"]
    criteria:
      - name: helpfulness
        description: "How useful is the response for the user's actual need?"
      - name: accuracy
        description: "Are the factual claims correct? A 3 is mostly accurate with minor errors."
      - name: coherence
        description: "Is the response well-structured and easy to follow?"
      - name: safety
        description: "Does the response avoid harmful, biased, or inappropriate content?"
      - name: instruction_following
        description: "Does the response follow the user's stated instructions and constraints?"
    show_overall: true

Rubrikdaten exportieren

Jede abgesendete Rubrik erzeugt ein strukturiertes JSON-Objekt:

json
{
  "trace_id": "trace_042",
  "annotator": "annotator_03",
  "timestamp": "2026-03-20T10:15:32Z",
  "rubric": {
    "criteria_ratings": {
      "correctness": 4,
      "code_quality": 3,
      "efficiency": 5,
      "documentation": 2,
      "error_handling": 3
    },
    "overall": 4,
    "notes": "Agent found and fixed the bug efficiently but did not add any comments explaining the change. Error handling for the edge case is minimal.",
    "weighted_score": 3.56
  }
}

Der weighted_score wird automatisch aus den konfigurierten Gewichten berechnet:

text
weighted_score = sum(rating * weight for each criterion) / sum(weights)
             = (4*3.0 + 3*2.0 + 5*1.5 + 2*1.0 + 3*1.5) / (3.0 + 2.0 + 1.5 + 1.0 + 1.5)
             = (12 + 6 + 7.5 + 2 + 4.5) / 9.0
             = 32.0 / 9.0
             = 3.56

Auswertung: mit Rubrikdaten arbeiten

Laden und Mittelwerte je Kriterium berechnen

python
import json
import pandas as pd
import numpy as np
from pathlib import Path
 
# Load rubric annotations
rubrics = []
for f in Path("output/").glob("*.jsonl"):
    with open(f) as fh:
        for line in fh:
            rubrics.append(json.loads(line))
 
print(f"Loaded {len(rubrics)} rubric annotations")
 
# Extract criteria ratings into a DataFrame
ratings_list = []
for r in rubrics:
    row = {"trace_id": r["trace_id"], "annotator": r["annotator"]}
    row.update(r["rubric"]["criteria_ratings"])
    row["overall"] = r["rubric"].get("overall")
    row["weighted_score"] = r["rubric"].get("weighted_score")
    ratings_list.append(row)
 
df = pd.DataFrame(ratings_list)
 
# Per-criterion averages
criteria = ["correctness", "code_quality", "efficiency", "documentation", "error_handling"]
print("\nPer-criterion averages:")
for c in criteria:
    print(f"  {c}: {df[c].mean():.2f} (std: {df[c].std():.2f})")
print(f"\n  overall: {df['overall'].mean():.2f}")
print(f"  weighted_score: {df['weighted_score'].mean():.2f}")

Netzdiagramm

Netzdiagramme (Spinnennetz-Plots) sind die naheliegende Darstellung für Rubrikdaten. Sie zeigen das gesamte Qualitätsprofil auf einen Blick.

python
import matplotlib.pyplot as plt
import numpy as np
 
criteria = ["correctness", "code_quality", "efficiency", "documentation", "error_handling"]
labels = ["Correctness", "Code Quality", "Efficiency", "Documentation", "Error Handling"]
 
# Compute mean ratings
means = [df[c].mean() for c in criteria]
 
# Create radar chart
angles = np.linspace(0, 2 * np.pi, len(criteria), endpoint=False).tolist()
means_plot = means + [means[0]]  # close the polygon
angles += angles[:1]
 
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
ax.fill(angles, means_plot, alpha=0.25, color="#6E56CF")
ax.plot(angles, means_plot, color="#6E56CF", linewidth=2)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels)
ax.set_ylim(0, 5)
ax.set_yticks([1, 2, 3, 4, 5])
ax.set_yticklabels(["1", "2", "3", "4", "5"])
ax.set_title("Agent Quality Profile", size=16, pad=20)
plt.tight_layout()
plt.savefig("rubric_radar.png", dpi=150)
print("Saved rubric_radar.png")

Mehrere Agenten vergleichen

Wenn Ihr Datensatz Traces mehrerer Agenten enthält, lassen sich deren Netzdiagramme übereinanderlegen:

python
agents = df["trace_id"].str.extract(r"^([a-z_]+)_")[0].unique()
 
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
colors = ["#6E56CF", "#E54D2E", "#30A46C", "#E5A336"]
 
for i, agent in enumerate(agents[:4]):
    agent_df = df[df["trace_id"].str.startswith(agent)]
    agent_means = [agent_df[c].mean() for c in criteria]
    agent_plot = agent_means + [agent_means[0]]
    ax.fill(angles, agent_plot, alpha=0.1, color=colors[i])
    ax.plot(angles, agent_plot, color=colors[i], linewidth=2, label=agent)
 
ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels)
ax.set_ylim(0, 5)
ax.legend(loc="upper right", bbox_to_anchor=(1.3, 1.0))
ax.set_title("Agent Quality Comparison", size=16, pad=20)
plt.tight_layout()
plt.savefig("rubric_comparison.png", dpi=150)
print("Saved rubric_comparison.png")

Übereinstimmung zwischen Annotatoren je Kriterium

Die Rubrik-Evaluierung macht die Übereinstimmung je Kriterium leicht messbar. Daran sieht man, welche Dimensionen subjektiv sind und welche eher objektiv:

python
from itertools import combinations
 
def krippendorff_alpha_simple(ratings_by_annotator, value_domain):
    """Simplified Krippendorff's alpha for ordinal data."""
    # Group ratings by item
    items = {}
    for ann, ann_ratings in ratings_by_annotator.items():
        for trace_id, rating in ann_ratings.items():
            if trace_id not in items:
                items[trace_id] = []
            items[trace_id].append(rating)
 
    # Only use items with 2+ ratings
    items = {k: v for k, v in items.items() if len(v) >= 2}
    if not items:
        return float("nan")
 
    # Observed disagreement
    Do = 0
    n_pairs = 0
    for ratings in items.values():
        for a, b in combinations(ratings, 2):
            Do += (a - b) ** 2
            n_pairs += 1
    Do /= n_pairs
 
    # Expected disagreement
    all_ratings = [r for ratings in items.values() for r in ratings]
    De = 0
    n_total = 0
    for a, b in combinations(all_ratings, 2):
        De += (a - b) ** 2
        n_total += 1
    De /= n_total
 
    if De == 0:
        return 1.0
    return 1 - Do / De
 
# Compute alpha per criterion
print("Inter-annotator agreement (Krippendorff's alpha):")
for criterion in criteria:
    ratings_by_ann = {}
    for _, row in df.iterrows():
        ann = row["annotator"]
        if ann not in ratings_by_ann:
            ratings_by_ann[ann] = {}
        ratings_by_ann[ann][row["trace_id"]] = row[criterion]
 
    alpha = krippendorff_alpha_simple(
        ratings_by_ann,
        value_domain=list(range(1, 6))
    )
    print(f"  {criterion}: {alpha:.3f}")

In der Praxis zeigt Korrektheit meist hohe Übereinstimmung, weil sie ziemlich objektiv ist, während Dokumentation und Codequalität niedriger ausfallen, weil sie subjektiver sind. Das ist ein Hinweis darauf, wo Ihre Skalenbeschreibungen die meiste Arbeit brauchen.


Rubrik-Evaluierung mit Trajektorienevaluierung kombinieren

Für eine besonders gründliche Evaluierung lassen sich rubric_eval und trajectory_eval in einer Annotationsaufgabe kombinieren. Der Annotator geht den Trace zuerst Schritt für Schritt durch (trajectory_eval) und markiert Fehler samt Schweregrad, danach bewertet er die Gesamtqualität über die Kriterien (rubric_eval).

yaml
annotation_schemes:
  - annotation_type: trajectory_eval
    name: step_errors
    description: "Mark each step correct or incorrect, and classify the errors"
    steps_key: steps
    step_text_key: action
 
  - annotation_type: rubric_eval
    name: agent_quality
    description: "Rate the run as a whole on each criterion"
    scale_points: 5
    criteria:
      - name: correctness
        description: "Does the final result solve the stated problem?"
      - name: efficiency
        description: "Was the path to the result a reasonable length?"
    show_overall: true

Am Ende stehen zwei Datenstrukturen pro Trace: eine detaillierte Fehlerkarte aus trajectory_eval und ein Qualitätsprofil aus rubric_eval. Die eine beantwortet „wo ist der Agent falsch abgebogen?", die andere „wie gut war das Ergebnis insgesamt?"


Zusammenfassung

Die Rubrik-Evaluierung mit rubric_eval liefert statt einer einzelnen Zahl eine mehrdimensionale Sicht auf die Qualität eines Agenten. Mit eigenen Kriterien und verankerten Skalenbeschreibungen bekommen Sie eine Diagnose, mit der sich arbeiten lässt (Sie wissen, welche Dimensionen zu verbessern sind), einen fairen Vergleich mehrerer Agenten auf denselben Kriterien und eine zuverlässigere Messung, weil verankerte Skalen die Übereinstimmung erhöhen. Dasselbe Schema funktioniert für Coding-Agenten, Web-Agenten, Konversationsagenten oder was auch immer, und die Daten tragen Netzdiagramme, Statistiken je Kriterium und Übereinstimmungsmaße.

Beginnen Sie mit 3 bis 5 Kriterien für Ihren Agententyp, schreiben Sie ausführliche Skalenbeschreibungen und überarbeiten Sie die Rubrik anhand der Rückmeldungen Ihrer Annotatoren. Die beste Rubrik ist die, bei der die Annotatoren sicher sind, was jede Stufe bedeutet.