Eval für KI-Coding-Agenten: Warum ein grüner string-contains-Check wenig beweist

Satellitenschuessel und Antennenanlage als Silhouette vor tiefblauem Abendhimmel
Deine Reaktion:

Ein Grader durchsucht die generierten Dateien nach der Zeichenkette Azure, findet sie in einer Zeile und meldet einen Treffer. Der Lauf ist grün, der Pull Request geht durch, und im Dashboard steht eine weitere bestandene Evaluierung.

Dass dieser Treffer fast nichts darüber aussagt, ob der Agent Azure tatsächlich verwendet, ist das Thema eines englischsprachigen Beitrags mit dem Titel „Is your eval lying to you?“. Der Autor beschreibt darin, wie leicht man sich mit billigen, deterministischen Checks selbst täuscht. Seine Kernthese: Ein Grader kann vollkommen korrekt arbeiten und trotzdem nichts von dem belegen, was wir aus seinem Ergebnis ableiten. Deshalb lohnt es sich, den eigenen Eval für KI-Coding-Agenten auf den Prüfstand zu stellen.

Warum string contains bei Evals für KI-Coding-Agenten so attraktiv ist

string contains ist schnell, deterministisch und kostet praktisch nichts. Man kann den Check auf jedem Commit in der CI laufen lassen, ohne über Inferenzkosten oder Latenz nachzudenken. Willst du wissen, ob der Agent Azure verwendet hat, suchst du nach Azure. Willst du wissen, ob eine bestimmte API genutzt wurde, suchst du den API-Namen. Willst du wissen, ob die richtige Konfiguration entstanden ist, prüfst du, ob die erwartete Zeichenkette in der Datei steht. Bestanden, ausliefern.

Man kann sich einen solchen Grader wie einen Zeugen vor Gericht vorstellen. Er berichtet nur, was er tatsächlich wahrgenommen hat, und je enger seine Aussage gefasst ist, desto schwerer lässt sie sich erschüttern. Nur deckt sie dann eben auch weniger ab, und hier beginnt das Problem. Der Autor vergleicht das Vorgehen mit einer Aussage, die man im Verhör so lange dehnt, bis sie das zu belegen scheint, was man hören wollte.

Was ein grüner string-contains-Check wirklich beweist

Nehmen wir das Beispiel aus dem Beitrag: Der Eval verlangt, dass die generierte Lösung Azure verwendet, und der Grader prüft, ob die erzeugten Dateien die Zeichenkette Azure enthalten. Der Grader besteht. Was weiß man danach? Zunächst nur, dass die Zeichenkette irgendwo in den generierten Dateien vorkommt, und dafür genügt eine einzige Zeile. Schon ein Kommentar wie // Don't use Azure here. besteht den Check. Dasselbe gilt für toten Code, eine ungenutzte Abhängigkeit, Dokumentation oder ein Test-Fixture.

Auch eine Konfigurationsdatei kann die Zeichenkette enthalten, obwohl die Anwendung diese Datei nie lädt. Der Grader findet dann genau das, wonach er sucht, während das Verhalten, das dich eigentlich interessiert, vollständig fehlt. In allen diesen Fällen ist der Grader nicht kaputt. Er beantwortet nur eine andere Frage als die, die du dir gestellt hast.

Umgekehrt gilt dasselbe. Fehlt die Zeichenkette, folgt daraus nicht, dass die Lösung Azure nicht verwendet. Der Agent könnte ein SDK nutzen, ohne Azure explizit zu erwähnen, sich nur auf einen Paket- oder Klassennamen beziehen oder dieselbe Absicht mit Wörtern ausdrücken, die du beim Schreiben des Evals nicht vorgesehen hast. Natürliche Sprache verschärft das, weil der Unterschied zwischen getan und nicht getan in einem einzigen Wort liegen kann, während das Schlüsselwort exakt gleich bleibt. Ein deterministischer Grader liefert eine deterministische Antwort, aber diese Antwort bedeutet nur so viel, wie der Check tatsächlich feststellt.

Der Zwei-Satz-Test: „Wenn dieser Grader besteht, weiß ich, dass …“

Der Autor beschreibt dafür einen einfachen Test für Eval-Kriterien. Vervollständige zwei Sätze, einen für ein bestandenes Ergebnis und einen für ein fehlgeschlagenes, und formuliere dabei bewusst wörtlich: „Wenn dieser Grader besteht, weiß ich jetzt, dass …“ und „Wenn dieser Grader fehlschlägt, weiß ich jetzt, dass …“. Bei einem string contains "Azure"-Check fallen die Antworten sehr schmal aus. Bestanden bedeutet dann nur, dass die Zeichenkette im geprüften Inhalt vorkommt, und fehlgeschlagen bedeutet nur, dass sie dort nicht vorkommt.

Wenn genau das die Eigenschaft ist, die du messen wolltest, ist alles in Ordnung. Vervollständigst du den ersten Satz dagegen mit „der Agent hat Azure korrekt verwendet“, hast du einen Sprung gemacht, den deine Evidenz nicht trägt. Der Grader ist deshalb nicht zwangsläufig ungenau. Er kann in dem, was er tut, präzise sein, während wir ihn etwas beweisen lassen, wozu er nicht in der Lage ist. Man kann sich das wie ein Kreuzverhör vorstellen: Die Frage muss so gestellt sein, dass die Antwort überhaupt etwas tragen kann.

Bequeme Evidenz und falsche Sicherheit in der KI-Coding-Agenten-Evaluierung

Einfache deterministische Grader sind aus gutem Grund verbreitet. Agentische Evals kosten Geld und laufen lange, LLM-Judges bringen zusätzliche Inferenzkosten und Latenz mit, und das Bauen, Ausführen oder Deployen generierter Anwendungen bedeutet Infrastruktur und Komplexität. string contains braucht dagegen Millisekunden, was es für die CI ideal macht und als Beweismittel potenziell furchtbar. Man optimiert dann den Eval um das, was bequem zu messen ist, statt um das, was man wissen muss.

Das Ergebnis kann eine schnelle, reproduzierbare Evaluierungspipeline sein, die bei jedem Lauf falsche Sicherheit produziert. Der Autor sagt dazu klar: Er würde lieber wenige Evals laufen lassen, die aussagekräftige Evidenz liefern, als kontinuierlich solche auszuführen, die zuverlässig sehr wenig mitteilen. Den Wert eines Checks misst man also nicht an seiner Laufzeit, sondern an der Frage, die er tatsächlich beantwortet.

Den Compiler fragen statt das LLM raten lassen

Wenn du wissen willst, ob generierter Code baut, dann baue ihn. Im Beitrag findet sich dazu eine Beobachtung: Lösungen erhielten perfekte Bewertungen von einem LLM-Judge und scheiterten anschließend an der Kompilierung. Der Judge konnte einschätzen, ob die Implementierung korrekt aussah, doch nur der Compiler konnte das verifizieren. Dasselbe Prinzip gilt für Abhängigkeiten, die sich wiederherstellen lassen sollen, für ein JSON-Datei, die einem Schema folgen muss, für Tests, die bestehen sollen, und für die Anwendung selbst, die laufen soll. Deterministische Grader funktionieren hier, weil der Check direkt die Eigenschaft feststellt, um die es geht. Ein LLM zu fragen, ob ein Projekt kompilieren wird, ergibt wenig Sinn, wenn der Compiler diese Frage autoritativ beantwortet.

Nur: Generierte Anwendungen laufen zu lassen ist deutlich schwerer, als sie zu bauen. Reale Anwendungen brauchen Zugangsdaten und Konfiguration, dazu Daten, Infrastruktur und Zugriff auf externe Dienste, und ein Deployment legt noch eine weitere Schicht obendrauf. Coding-Agenten tun sich an genau diesen Grenzen schwer, was es verlockend macht, stattdessen etwas Einfacheres zu überprüfen. Man prüft also Artefakte oder Wörter in der Ausgabe, ein LLM-Judge hält die Implementierung für plausibel, und diese Beobachtungen werden dann als Beleg dafür behandelt, dass die Integration funktioniert, obwohl kein einziger Check sie tatsächlich ausgeführt hat. Manchmal ist ein vollständiger Lauf praktisch nicht machbar, und das ist in Ordnung. Ein Eval muss nicht alles beweisen, aber sein Bericht sollte klar ausweisen, was er festgestellt hat und was nicht.

LLM-Judge für semantische Fragen, agentische Evals als Integrationstests

Semantische Kriterien liegen anders. Ein LLM-Judge kann zwischen „Azure zum Speichern der Daten verwenden“ und „Azure nicht zum Speichern der Daten verwenden“ unterscheiden, er kann den umgebenden Code betrachten, Beziehungen zwischen Komponenten bewerten und Implementierungen erkennen, die das Vokabular deines Evals gar nicht verwenden. Damit beseitigt er aber nicht das Evidenzproblem, denn er kann das Bauen und Ausführen der Software nicht verlässlich ersetzen. Selbst wenn er jeden relevanten Compiler, Paketmanager, Testrunner oder Laufzeitcheck nachbilden könnte, wäre die naheliegende Frage: Warum sollte man ihn damit beauftragen, wo es diese Werkzeuge bereits gibt?

Für den Autor liegt die sinnvolle Denkweise deshalb näher an Integrationstests als an Unit-Tests. Wer einen MCP-Server, ein Skill oder eine Extension für einen Coding-Agenten bewertet, will wissen, ob der Agent die Aufgabe erfolgreich abschließen kann, und ein bestimmtes Implementierungsdetail in der Ausgabe sagt darüber deutlich weniger aus. In den beschriebenen Evals sind Bauen, Testen, Ausführen und Deployen getrennte Gates, daneben bewerten LLM-Judges die semantischen Eigenschaften des jeweiligen Szenarios. Diese Trennung zeigt dir, ob die Wiederherstellung der Abhängigkeiten scheiterte, ob die Kompilierung brach oder ob eine baubare Implementierung eine wichtige Anforderung verfehlte. Ein einzelner breiter Proxy sollte nicht alle diese Fragen gleichzeitig beantworten müssen.

Deterministische Grader sind hervorragend, solange die gemessene Eigenschaft deterministisch ist. Das Problem beginnt in dem Moment, in dem man ein bequemes Signal auswählt und die daraus abgeleitete Behauptung still und leise erweitert. Hier lohnt sich der Zwei-Satz-Test, bevor du deinen nächsten Grader in einen agentischen Eval einbaust: Vervollständige beide Sätze und vergleiche die Antworten mit dem, was du über deinen Agenten, dein Skill, deinen MCP-Server oder deine Extension tatsächlich behaupten willst. Passen sie nicht zusammen, brauchst du stärkere Evidenz. Ein Eval wird nicht dadurch vertrauenswürdig, dass es bei jedem Commit läuft. Es wird vertrauenswürdig, wenn seine Evidenz die Aussagen trägt, die du daraus ableitest.

Quelle: blog.mastykarz.nl

Deine Reaktion:
Artikel teilen:
Krötzsch-Check0 — 100
Fakten 70
Relevanz 80
Hype 18
Einschätzung 78
Redaktion 50 Stand 50 · noch keine Stimmen
Ist das Hype?
Sebastian Krötzsch
Autor

Sebastian Krötzsch

Sebastian Krötzsch schreibt auf sebask.de über Künstliche Intelligenz, Automatisierung, digitale Systeme und die Frage, was davon im Alltag wirklich nützlich ist. Ohne Buzzword-Nebel, dafür mit klarem Blick auf Praxis, Tools und echte Wirkung.