Constraint Decay: Die Verwundbarkeit von LLM-Agenten bei der Generierung von Backend-Code
(arxiv.org)- LLM-Agenten sind stark bei der Codegenerierung mit lockeren Spezifikationen, bleiben jedoch anfällig, wenn es um die Einhaltung von API-Verträgen, Architektur-, DB- und ORM-Vorgaben geht, wie sie produktionsreife Backends erfordern
- Bei identischen OpenAPI-Spezifikationen wurden funktionale Anforderungen fixiert und dieselben Verhaltenstests auf 80 Greenfield-Aufgaben und 20 Feature-Implementierungsaufgaben in 8 Web-Frameworks angewendet
- Nichtfunktionale Einschränkungen wurden in vier Dimensionen aufgeteilt: Framework-Auswahl, Architekturmuster, Datenbank-Backend und ORM-Integration, um den Einfluss struktureller Komplexität isoliert zu messen
- Constraint Decay bezeichnet das Phänomen, dass die Leistung mit jeder zusätzlichen strukturellen Anforderung stark einbricht; bei vollständig spezifizierten Aufgaben mit hoher Konfiguration sank die Assertion-Pass-Rate im Schnitt um 30 Punkte
- Der Kern der Fehlschläge sind Defekte in der Datenschicht; fehlerhafte Query-Konstruktionen und ORM-Laufzeitverletzungen machen rund 45 % der Logikfehler der Agenten aus
Zentrales Problem und Evaluationsaufbau
- LLM-Agenten sind stark bei autonomer Codegenerierung mit lockeren Spezifikationen, aber ihre Fähigkeit, die für produktionsreife Backend-Software nötigen strukturellen Einschränkungen strikt einzuhalten, wurde bislang nicht ausreichend bewertet
- Produktionsreife Backends müssen nicht nur Endpunkte bereitstellen, die dem API-Vertrag folgen, sondern auch nichtfunktionale Anforderungen wie Architekturmuster, Datenbankintegration und eine vorgegebene ORM-Schicht erfüllen
- Bestehende Benchmarks belohnen oft auch Lösungen, die funktional korrekt, strukturell aber beliebig sind, und erfassen daher die Schwierigkeit constraintbehafteter Backend-Entwicklung über mehrere Dateien hinweg nur unzureichend
- Frühere Forschung konzentrierte sich vor allem auf das Beheben konkreter Probleme in bestehenden Codebasen, ungebundene Generierung auf Basis von Natural-Language-Prompts, Ein-Datei-Lösungen oder das Vervollständigen von Skeleton-Code und behandelte nicht systematisch die Wirkung unterschiedlich starker struktureller Einschränkungen
- Die funktionalen Anforderungen wurden über dieselbe OpenAPI-Spezifikation fixiert, und auf alle Bedingungen wurden identische End-to-End-Verhaltenstests angewendet, um den Einfluss struktureller Komplexität zu isolieren
- Das Experiment umfasst 80 Greenfield-Generierungsaufgaben und 20 Feature-Implementierungsaufgaben über 8 Web-Frameworks hinweg
- Nichtfunktionale Einschränkungen sind in vier Dimensionen gegliedert: Framework-Auswahl, Architekturmuster, Datenbank-Backend und ORM-Integration
- In der Baseline wird nur dieselbe API-Spezifikation vorgegeben; unter Constraint-Bedingungen kommen Anforderungen wie Clean Architecture, PostgreSQL und SQLAlchemy hinzu
- Für die Bewertung werden End-to-End-Verhaltenstests und statische Validatoren gemeinsam eingesetzt, um funktionale Korrektheit und strukturelle Konformität getrennt zu messen
Zentrale Ergebnisse und Bedeutung
- Constraint Decay wurde als Phänomen bestätigt, bei dem die Leistung von Agenten deutlich sinkt, je mehr strukturelle Anforderungen sich ansammeln
- Selbst leistungsstarke Konfigurationen verloren beim Übergang von der Baseline zu vollständig spezifizierten Aufgaben im Mittel 30 Punkte bei der Assertion-Pass-Rate; einige schwächere Konfigurationen fielen fast auf 0
- Trotz identischem API-Vertrag unterschieden sich die Erfolgsraten je nach Framework stark; die Agenten funktionierten besser mit leichten und expliziten Frameworks wie Flask
- In stärker konventionsgeprägten Umgebungen wie FastAPI und Django lag die durchschnittliche Leistung deutlich niedriger
- Die Fehleranalyse zeigte, dass Defekte in der Datenschicht die Hauptursache sind, insbesondere fehlerhafte Query-Konstruktionen und ORM-Laufzeitverletzungen
- Defekte in der Datenschicht wurden als zentrale Ursache für etwa 45 % der Logikfehler der Agenten eingestuft
- Funktionale und strukturelle Anforderungen gleichzeitig zu erfüllen, bleibt für Coding-Agenten eine wichtige ungelöste Aufgabe
- Evaluationspipeline, Aufgabensammlung, Agenten-Ausführungstrajektorien und Analyseskripte sind unter constraint-decay veröffentlicht
1 Kommentare
Hacker-News-Kommentare
Ich war bei LLM-Codegenerierung völlig skeptisch, aber inzwischen sind über 80 % des Codes, den ich beruflich nutze, generierter Code
Allerdings sind die Grenzen inzwischen ziemlich klar geworden, sie zeigen sich in einigen Projekten bereits deutlich, und dieser Artikel scheint meinen Verdacht zu bestätigen
Je komplexer die Aufgabe, desto mehr fügt man fortlaufend Einschränkungen in Markdown-Spezifikationen, Regeln, Skills, Styleguides, Randbedingungen, Fehlerbehandlung und Optimierungsrichtlinien hinzu
Irgendwann wirkt es so, als würde man die Komplexität aus der formelleren und deterministischeren Welt der Programmiersprachen in die informelle und nichtdeterministische Welt der natürlichen Sprache verlagern
Der Geschwindigkeitsgewinn beim Schreiben ist enorm, und Unternehmen sehen das natürlich als Produktivitätssteigerung, aber der Preis dafür ist offensichtlich und wird von vielen anscheinend ignoriert
Niemand prüft das zu 100 %, und selbst wenn es geprüft wird, ist das sehr subjektiv
Es ist unklar, worin genau der Unterschied liegt zwischen „folge einem RESTful-Ansatz“, „wir nutzen REST und kein GraphQL“ und „90 % der Endpunkte sind ressourcenorientiert, aber einige sehen wie RPC aus, also ignoriere das“
Das alles wirkt ziemlich dämlich
Praktisch kompiliert man Programme voller undefiniertem Verhalten, die aber meistens „so aussehen, als würden sie funktionieren“
Dass Unternehmen das als Produktivitätssteigerung sehen, fühlt sich letztlich an wie eine Rückkehr zu einer Zeit, in der man „Produktivität“ wieder in Codezeilen pro Sekunde misst
Sobald die Codebasis nicht mehr in die ersten 20 % des Kontextfensters passt und damit ein vollständig reproduzierbares Niveau in einem einzigen Inferenzlauf verlässt, werden Ausführungs-Harnesses und Code-Patching-Techniken viel wichtiger
Der von OAI für Modelle verfeinerte apply_patch-Ansatz scheint für extrem große Codebasen die beste Vorgehensweise zu sein
Ansätze auf Basis von Zeilenbereichen oder einfachem Suchen-und-Ersetzen brechen an den Rändern zusammen, und um knifflige Fälle wie cshtml-Dateien zu handhaben, braucht man mehrere räumliche Anker
Prepare/Commit-Verhalten ist ideal, um mehrdeutigen Kontext über viele große Dateien hinweg zu iterieren und dabei die Anker zu verfeinern
LLMs können nichts wirklich Neues hervorbringen
„Systematische Forschung zeigt das Phänomen des Constraint Decay bei LLM-basierten Coding-Agenten. Aktuelle Modelle sind hervorragend in uneingeschränkter Generierung, lassen aber in ihrer Leistung nach, wenn sie explizite Architekturregeln befolgen müssen. Für Endnutzer bedeutet diese Dichotomie, dass Agenten für schnelles Prototyping verlässlich sein können, für produktionsreife Backend-Entwicklung aber weiterhin schwer vertrauenswürdig bleiben.“
Die große Schwäche dieser Studie ist, dass sie aus Kostengründen Frontline-Modelle nicht ausreichend getestet hat, deshalb sollte man die konkreten Leistungswerte mit Vorsicht betrachten
Trotzdem ist die Schlussfolgerung interessant und weiter beobachtenswert, dass die Modellleistung sinkt, wenn sowohl Verhalten als auch Architektur stimmen müssen
Wenn nur funktionale Anforderungen existieren, betreibt man gewissermaßen Programmsynthese, und Reinforcement Learning kann das sehr stark optimieren
Wenn funktionale und nichtfunktionale Anforderungen vermischt werden, gibt man dem Modell faktisch eine unvollständige Spezifikation, und das Modell muss die Absicht des Nutzers bis zu einem gewissen Grad erraten, um die Lücken zu füllen
Das ist auch der Grund, warum Beispiele für den gewünschten Coding-Stil im Prompt so außerordentlich wirkungsvoll sind
Je mehr Material zum Referenzieren vorhanden ist, desto stärker stützt es sich darauf, frühere Inhalte zu wiederholen
Es ist auch möglich, dass Autoren bei späteren Kapiteln weniger aufmerksam sind und weniger Mühe in die Bearbeitung stecken
Auf Amazon gibt es zwar riesige Mengen davon, aber LLMs sind noch nicht an dem Punkt, an dem sie gut schreiben
Wenn es inkompatible Lösungen vorschlägt und man zusätzlichen Kontext und Anforderungen hinzufügt, neigt es dazu, sich auf die ursprüngliche Architektur zu fixieren und hat Schwierigkeiten, sich anzupassen
Manchmal versucht es sogar, Änderungen für den ursprünglichen Plan heimlich hineinzuschmuggeln
Es scheint, als würden große Teile des möglichen Lösungsraums unerreichbar werden
Wenn man zum Beispiel vor etwa einem Jahr Guardrails auf Bildgeneratoren angewandt hat, sahen plötzlich alle Menschen ähnlich aus, und Story-Generatoren begannen nur noch einige wenige Standardnamen zu verwenden
Ich frage mich, ob das selbst bei Frontline-Modellen noch passiert
An der Analyse solcher Modellschwächen habe ich kein allzu großes Interesse. Meiner Erfahrung nach verschwinden viele Schwächen vollständig, wenn die Modelle stärker werden und man den Inferenzaufwand erhöht
Das gilt besonders dann, wenn man das gewünschte Verhalten klar formuliert, und es ist nicht überraschend, dass die Ausfallrate steigt, wenn die Zahl der Akzeptanzkriterien zunimmt
Die Lage ist noch schlimmer. Agenten haben nicht nur mehr Probleme unter „strukturellen Einschränkungen“, sondern sind noch schlechter, wenn diese strukturellen Einschränkungen selbst geändert werden müssen
Beim Entwurf von Systemen oder Komponenten entwickeln wir Ideen, die zu Invarianten werden
Manche dieser Invarianten sind groß, etwa die Gesamtarchitektur, andere klein, etwa die Wahl einer Datenstruktur
Irgendwann kommt dann aber der Moment, in dem man eine Funktion hinzufügen möchte, die mit diesen Invarianten kollidiert
Dann gibt es gewöhnlich drei Optionen: die Funktion nicht hinzufügen, sie ungeschickt oder ineffizient auf die Invarianten aufsetzen oder zurückgehen und die Invarianten ändern
Meistens ist nur eine davon richtig, und mindestens eine ist massiv falsch und führt zu schlechten Ergebnissen
Agenten sind selbst dann, wenn sie Einschränkungen befolgen können, sehr schlecht darin zu erkennen, wann die Einschränkungen geändert werden müssen
Das ist eine der Grenzlinien zwischen Mustererkennung und Schlussfolgern, und entgegen den Marketingbehauptungen über Denkprozesse schlussfolgern LLMs überhaupt nicht
Jeder Versuch, den Eindruck von Schlussfolgern zu erzeugen, ist für mich eher eine rekursive Eindämmungsanstrengung des Harnesses, die versucht, einen Blitz in einer Flasche einzufangen
Das erinnert mich an eine aktuelle Arbeit, in der verschiedene Dokumentenbearbeitungsaufgaben an LLMs delegiert wurden https://arxiv.org/abs/2604.15597
In dieser Arbeit wurde argumentiert, dass Programmierung der einzige Bereich sei, in dem die meisten LLMs langfristige Aufgaben ausführen können, ohne Fehler anzuhäufen und Dokumente zu ruinieren
Ich habe bei dieser Arbeit erst das Abstract gelesen, aber sie scheint die Programmierung genauer zu betrachten und ein ähnliches Phänomen zu zeigen
Allerdings wirkt es weniger wie eine langfristige Aufgabe als eher wie ein „langer Stil-Horizont“ in Bezug auf ein größeres Bündel struktureller Einschränkungen
Verwandte Diskussion: https://news.ycombinator.com/item?id=48073246
Sehr interessante Arbeit, und ich stimme voll zu, aber ich halte das nicht für wirklich neu
Schon die anfängliche Erwartung, man könne irgendeine agentische Coding-Lösung in ein Projekt werfen, ihr eine Aufgabenliste geben, und sie würde dann auf magische Weise die vordefinierten Einschränkungen des Projekts einhalten, geht etwas am Ziel vorbei
Ich glaube nicht, dass irgendein agentischer Coding-Stack das im Auslieferungszustand leisten kann
Damit ein Agent Kontext, Einschränkungen und Ziele zuverlässig versteht, braucht es weiterhin geeignete Mechanismen, und dass die großen AI-Labore ihre Tools, Skills und Prozesse laufend aktualisieren, zeigt, dass dieser Bereich noch in Arbeit ist
Diese zusätzliche Schicht könnte viel profitabler sein als das reine Modell und der Token-Verbrauch
Selbst offene Modelle wie die hier getesteten können meiner Ansicht nach bereits Produktionscode erzeugen, der die gewünschten Einschränkungen einhält, wenn man sie richtig betreibt
Ich frage mich, wie euer Produktionscode in den letzten Monaten aussah
Ich habe ziemlich viel mit agentischem Coding über lange Horizonte experimentiert https://medium.com/@vishvananda/i-spent-2-billion-tokens-wri... und dabei auch gesehen, dass die Leistung des Agenten schlechter wird, wenn man bestimmte Architekturmuster erzwingt
Es wird etwas besser, wenn man die Einschränkungen während des Fortschritts einführt, statt sie später hinzuzufügen
Es gibt einen Nebeneffekt, den ich Verkalkung nenne: Sobald ein bestimmtes Muster in der Codebasis auftaucht, folgt der Agent diesem Muster weiter, bis es den Kontext dominiert und sich selbst verstärkt
In einer bestehenden Codebasis kann das je nach Codequalität eine Stärke oder eine Schwäche sein
Wenn Durchläufe auf einer neuen Codebasis inklusive Architekturleitlinien von Anfang an abgeschlossen sind, wird es wohl mehr Einsichten geben
Außerdem modularisieren Modelle einigermaßen gut, wenn sie Raum haben, die Implementierung zu „planen“, aber sie kommen nur selten selbst darauf, dass spätere Abstraktion hilfreich wäre
Das gilt besonders nach mehreren Iterationen in einer neuen Codebasis oder wenn sie in eine Legacy-Codebasis geworfen werden, und führt oft zu riesigen Dateien
Wenn ein Nutzer sie darauf hinweist, kritisieren die Modelle das korrekt, was ziemlich komisch ist, wenn es um Code geht, den sie selbst geschrieben haben
Klingt wie eine weitere Variante von „je länger der Chat wird, desto mehr verschwimmen die Guardrails“
Der Grund, warum man das gesamte Kontextfenster nicht nutzen kann, ist, dass die Ausgabe gegen Ende die Einschränkungen oder Guardrails nicht mehr einhält
Um stabil produktionsreifen Code zu erzeugen, muss das Modell aber ein breites Bewusstsein haben, und das füllt das Kontextfenster schnell
Es ist ähnlich wie zu sagen: „Nimm bei dieser Änderung alles in diesen 6 Verzeichnissen mit in den Blick“ — aber schon allein dieses Alles-im-Blick-Behalten füllt das Kontextfenster und nimmt dem Modell die Fähigkeit, die Einschränkungen einzuhalten
Dann würde sich das Fehlverhalten aber vermutlich dahin verschieben, dass das Modell sich darauf fokussiert, den Linter zufriedenzustellen, und die Anforderungen zunehmend vergisst
Wiederholte Versuche und Fehlschläge wären für den Kontext ebenfalls überhaupt nicht gut
In der Forschung wurden dynamisch typisierte Sprachen wie Python und JS verwendet
Meiner Erfahrung nach sind statisch typisierte Codebasen auch für Menschen leichter wartbar, also könnte das auch für Agenten gelten
Ich habe unzählige Male gesehen, wie ein Agent mit Codex oder Claude Code in Go Änderungen vornimmt, den Build ausführt, Fehler findet und sie dann wieder behebt
Die Modelle kommen mit Python-Typen heutzutage ziemlich gut klar
In Python ist starkes statisches Typisieren seit Jahren eine Option, und es sollte einfach der Standard sein
Es ist von „Aufgaben über 8 Web-Frameworks hinweg“ die Rede; ich frage mich, ob jemand die Erfahrung gemacht hat, dass LLMs mit reinem HTML+CSS+JS besser arbeiten als mit bestehenden Frameworks
Die beeindruckendste Kombination, die ich zuletzt gesehen habe, ist Razor Pages mit schrittweiser Verbesserung durch JavaScript
In dieser Konfiguration entscheiden aktuelle Modelle ziemlich gut, was serverseitig (
cshtml) passieren sollte und was clientseitig (js)Ich würde empfehlen, etwas Zeit darauf zu verwenden, einige Teile der Codebasis zuerst in eine idiomatische Form zu bringen und diese Dateien dann per @ als Beispieldateien zu markieren
Das funktioniert viel besser, als zu versuchen, das Ganze mit Markdown zu steuern
Bei FastAPI klappt das ganz gut, aber JavaScript wirkt am schlimmsten
Selbst mit Vorgaben und Beispielen neigt es dazu, massenhaft unnötigen Code zu inlinen, statt die vorgegebene API zu verwenden