- Beim edit-Tool von Pi fügten Claude Opus 4.8 und Sonnet 5 innerhalb von
edits[] Felder hinzu, die nicht im Schema stehen; die Aufrufe wurden abgelehnt, und es zeigte sich, dass neuere Modelle bestimmte Tool-Schemata schlechter einhalten als ältere
- Tool-Aufrufe sind ein Prozess, bei dem das Modell Text erzeugt – in Form spezieller Marker und JSON –, sodass bei uneingeschränktem Sampling gelernte Konventionen Vorrang vor dem Schema bekommen können
- In den Fehlfällen waren
oldText und newText selbst korrekt, dennoch wurden falsche Keys wie requireUnique, oldText2, matchCase oder in_file angehängt; die Reproduzierbarkeit variierte je nach Agentenverlauf und danach, ob Thinking Blocks enthalten waren
- Claude Code ist zwar ein geschlossenes Harness, führt aber viel lockere Korrektur durch, etwa erneute Versuche bei fehlerhaften Aufrufen, Parameter-Aliasse, Typkorrekturen, Unicode-Reparaturen und das Filtern unbekannter Keys; der
strict-Modus wird nicht genutzt
- Anthropics
strict-Tool-Aufrufe beseitigten dieses Problem; wenn bessere Modellleistung alternative Tool-Schemata benachteiligen kann, braucht das Harness stärkere Garantien wie grammatische Constraints
Regression beim edit-Tool von Pi
- Beim Verfolgen eines Pi-Issues wurde entdeckt, dass die neuesten Claude-Modelle beim Aufruf des edit-Tools von Pi im Array
edits[] nicht existierende Felder hinzufügen
- Das trat nicht bei einem kleinen Modell auf, sondern bei Opus 4.8; dasselbe Verhalten wurde auch bei Sonnet 5 bestätigt
- Bei früheren Anthropic-Modellen war dasselbe Problem nicht zu sehen, sodass die neuesten leistungsstarken Modelle bei genau diesem Tool-Schema schlechter arbeiten
- Fable wurde nicht getestet, weil ein Klassifikator Anfragen möglicherweise stillschweigend auf Opus herabstuft
Tool-Aufrufe ähneln Texterzeugung
- LLM-Tool-Aufrufe funktionieren so, dass das Modell den Gesprächsverlauf, den System-Prompt und die Liste verfügbarer Tools erhält und dann innerhalb eines großen Prompts mit speziellen Markern das Aufrufformat erzeugt
- Die vorgesehenen Argumente eines Datei-Editier-Tools können wie folgt
path und ein Array edits enthalten
{
"path": "some/file.py",
"edits": [
{
"oldText": "text to replace",
"newText": "replacement text"
}
]
}
- Das Harness validiert die Argumente, führt die Bearbeitung aus und gibt das Ergebnis wieder an das Modell zurück; bei fehlgeschlagener Validierung sieht das Modell den Fehler und versucht es normalerweise erneut
- Das interne Format von Anthropic-Modellen ist nicht öffentlich, aber
ANTML-Marker sind schon geleakt oder in öffentlicher Kommunikation aufgetaucht
- Dieses Format sieht zwar wie XML aus, ist aber weniger echtes XML als vielmehr ein In-Band-Signal, das für Tokenisierung und Training günstig ist
- Top-Level-Stringparameter können inline eingefügt werden
- Arrays von Objekten scheinen in JSON-serialisierter Form eingefügt zu werden
Uneingeschränkte Erzeugung und grammatikbeschränkte Erzeugung
- Für strukturierte Ausgaben gibt es grob zwei Wege
- Man fordert das Modell auf, JSON gemäß einem Schema zu erzeugen, und validiert danach
- Der Sampler verhindert von Anfang an, dass ungültiges JSON oder eine ungültige Schemaform gesampelt wird
- Der zweite Ansatz wird grammatikbewusstes Decoding oder constrained decoding genannt und maskiert Tokens, die die Grammatik verletzen würden
- Wenn ein Schema nur
oldText und newText erlaubt, kann der Sampler die Erzeugung von Keys wie "in_file" oder "type" verhindern
- Ohne solche Constraints erzeugt das Modell eher gemäß gelernter Konventionen, statt den abstrakten Vertrag strikt einzuhalten
Tatsächliche Fehlermuster
- Pis edit-Tool nutzt ein Array
edits, weil es mehrere exakte String-Ersetzungen in einem einzigen Aufruf unterstützt
- In fehlerhaften Aufrufen wurden wie folgt unerlaubte Felder angehängt
{
"oldText": "...",
"newText": "...",
"requireUnique": true
}
{
"oldText": "...",
"newText": "...",
"oldText2": "",
"newText2": ""
}
- Die in wiederholten Experimenten aufgetretenen falschen Keys waren vielfältig:
type, id, kind, unique, requireUnique, matchCase, in_file, forceMatchCount, children, notes, cost, oldText2, newText2, oldText_2, newText_2, event.0.additionalProperties und andere
- Bei den bestätigten fehlerhaften Aufrufen waren die eigentlichen Payloads
oldText und newText bytegenau korrekt, aber am Ende des Objekts wurden unsinnige Keys angehängt, wodurch der Aufruf abgelehnt wurde
- Die Reproduktion hängt stark vom Kontext ab
- Bei einem neuen Single-Turn-Prompt „edit this file“ ließ es sich nicht reproduzieren
- Es trat in einem Agentenverlauf auf, in dem das Modell eine Datei gelesen, das Problem diagnostiziert und anschließend eine mehrzeilige Bearbeitung zusammengestellt hatte
- Zur Reproduktion war das Transkript von Petr Baudis nötig
- Bei Fortsetzung dieser Nutzersitzung scheiterte Opus 4.8 mit etwa 20 % Wahrscheinlichkeit
- Entfernte man die Thinking Blocks aus dem Verlauf, halbierte sich die Fehlerrate
- Mit aktivierten
strict-Tool-Aufrufen verschwand das Problem in diesem Lauf
Warum wurde es schlechter?
- Die stärkste Hypothese ist, dass es sich nicht um zufällige Leistungsverschlechterung handelt, sondern um ein Trainingsartefakt
- Frühere Anthropic-Modelle wurden zwar mit einigen Tools trainiert, aber bevor vom Nutzer bereitgestellte Harnesses wie Claude Code ein klares Ziel darstellten
- Neueste Anthropic-Modelle wurden sehr wahrscheinlich mit Nachtraining trainiert, das Claude Code oder ein sehr ähnliches Harness einschloss, und könnten in dieser Umgebung sowohl erfolgreiche Tool-Aufrufe als auch tolerierte Fehler gelernt haben
- Das edit-Tool von Claude Code hat nicht Pis verschachtelte
edits[]-Struktur, sondern eher eine flache Struktur mit file_path, old_string, new_string und optionalem replace_all
- Der Claude-Code-Client korrigiert viele Fehler, darunter erneute Versuche bei falscher Tool-Nutzung, Parameter-Aliasse, Typumwandlungen, Unicode-Reparaturen und das Filtern unbekannter Keys
- Wenn Reinforcement Learning in einem solchen Harness oder dessen Simulation stattfindet, können auch leicht falsche Tool-Aufrufe die Aufgabe abschließen und eine Belohnung erhalten
- Wenn ein anderes Harness ein semantisch gleiches Editier-Tool mit einem anderen Schema bereitstellt, kann es aus Sicht des Modells zunehmend zu einem Tool außerhalb der Verteilung werden
- Zum Zeitpunkt der Veröffentlichung von Opus 4.5 passte es sich sehr gut an andere edit-Tools an; die nun beobachtete Richtung zeigt jedoch, dass alternative Tool-Schemata in einem bestimmten großzügigen Tool-Ökosystem benachteiligt werden können
- Es gibt zwar ein dokumentiertes text editor tool, aber Claude Code folgt diesem Format nicht exakt, und die internen Abläufe von Claude Code sind als geschlossenes Harness nicht sichtbar
Das lockere Harness von Claude Code
- Claude Code ist Closed Source, aber ein Blick auf den minifizierten Code zeigt, dass es eingehende Daten sehr tolerant behandelt
- Es prüft, ob
<invoke-Markup in den sichtbaren Text des Modells durchgesickert ist; in diesem Fall sendet es Telemetrie und versucht den fehlerhaften Aufruf mit einer eigenen Zustandsmaschine erneut
- Es gibt eine Unicode-Escape-Reparatur für beschädigte
\uXXXX-Sequenzen und lone surrogates in Stringwerten
- Außerdem gibt es tool-spezifische Parameter-Aliasse
Edit akzeptiert old_str, old_string, new_str, new_string
path wird als Alias für file_path akzeptiert
- Unerwartete Keys werden stillschweigend herausgefiltert
- Der
strict-Modus wird nicht verwendet
- Anthropic erzwingt im
strict-Modus Begrenzungen der Komplexität von Tool-Definitionen, wodurch API-Anfragen fehlschlagen können
- Das scheint ein Grund zu sein, warum Claude Code den
strict-Modus nicht versucht
strict-Modus und andere Ökosysteme
- Da sowohl Anthropic-Modelle als auch Harnesses geschlossen sind, ist schwer zu beurteilen, ob dasselbe Problem auch bei anderen Harnesses weiterbesteht
- Codex-Modelle sind ebenfalls geschlossen, das Harness jedoch nicht
- gpt-oss wurde explizit darauf trainiert, OpenAIs harmony-Antwortformat zu nutzen, und es gibt viele Dokumente, die OpenAIs Denkweise zeigen
- harmony macht Kanäle und Content-Typen für Tool-Aufrufe zu einem Teil des Prompt-Formats und kann im Body eines Tool-Aufrufs Marker wie
<|constrain|>json enthalten
<|start|>assistant<|channel|>commentary to=functions.get_weather
<|constrain|>json<|message|>{"location":"San Francisco"}<|call|>
<|constrain|>json macht es für den Inferenz-Stack leicht, die Grenze zu finden, an der er im Body des Tool-Aufrufs auf JSON-beschränktes Sampling umschalten soll
- Bei gehosteten GPT-Modellen gibt es auch die Option, für die Grammatik, der Nutzertools folgen sollen, eine LARK-Grammatik bereitzustellen
- Anthropic scheint im
strict-Modus ebenfalls etwas Ähnliches zu tun, doch bei verschachtelten Array-Parametern muss das Modell lange mehrzeilige Dateiinhalte als JSON mit Escapes innerhalb von Stringliteralen erzeugen
- Die falschen Keys erscheinen direkt nach dem Schließen eines mehrere Hundert Tokens langen
newText-Strings, an einem hoch entropischen Punkt, an dem das Modell zwischen } und , "..." wählen muss
- Opus 4.8 und Sonnet 5 scheinen eine stärkere Prior-Verteilung für die Form von edit-Tool-Aufrufen zu haben, und diese Prior-Verteilung liegt näher am flachen edit-Schema von Claude Code
- Dass Anthropics
strict-Modus das Problem behebt, könnte daran liegen, dass der Server das Sampling von Keys ablehnt, die gemäß JSON-Schema-Struktur nicht erlaubt sind
- Bei den getesteten Codex-Modellen war diese Art von Regression nicht zu sehen; 5.6 wurde wegen fehlender Zugriffsrechte ausgeschlossen
Auswirkungen auf das Harness-Design
- Bei Anthropic-Modellen sind Tool-Schemata möglicherweise keine neutralen abstrakten Verträge
- Manche Tool-Formen liegen nah an dem, was im Nachtraining gesehen wurde, andere liegen weiter entfernt
- Manche Formen können in der verborgenen Codierung des Anbieters einfach sein, während andere schwierig funktionieren, weil nach langen mehrzeiligen Strings ein großes escapetes JSON-Objekt innerhalb eines verschachtelten Arrays geschrieben werden muss
- Selbst wenn das Modell das Schema versteht, kann es unter Druck daran scheitern, die exakte Struktur zu sampeln
- Bei Anthropic kann das Problem durch Einschalten von
strict-Sampling verschwinden
- Das Verhalten der neuesten Modelle zeigt jedoch, welchen Einfluss Reinforcement Learning auf Modelle hat, und dass es für Spitzenleistung nachteilig sein kann, gegen die Prior-Verteilung eines bestimmten Harnesses zu arbeiten
- Claude Code ist nicht Open Source, und man weiß nicht, was in der RL-Umgebung geschieht; daher lässt sich schwer annehmen, dass auf Claude Code trainiertes Verhalten sauber auf andere Tools übertragbar ist
- Je mehr Nachtraining innerhalb eines dominanten Harnesses stattfindet, desto stärker müssen andere Harnesses dessen eigenartige Eigenschaften erben
- Constrained Decoding kann Qualitäts-Trade-offs haben, aber wenn neuere Modelle zwar Aufgaben besser lösen, jedoch alternative Tool-Schemata schlechter zuverlässig ausgeben, braucht es irgendwo im Harness stärkere Garantien
1 Kommentare
Lobste.rs-Kommentare
Falls jemand Fable nicht kennt: Ich verstehe es inzwischen so, dass Fable bei einem Downgrade jetzt immer explizit Bescheid gibt
Ich bin selbst schon einmal im Klassifikator hängen geblieben; vermutlich klang „sortiere die Bugs nach Schweregrad“ zu sehr nach Sicherheitsforschung
Sie haben zwar gesagt, dass sie es nicht heimlich im Hintergrund tun werden, aber den Mechanismus, der für Downgrades verwendet wird, habe ich noch nicht überprüft
Wenn diese Hypothese stimmt, reichen die Auswirkungen womöglich über Coding Agents hinaus
Anwendungen, die auf verlässliche Tool-Aufrufe angewiesen sind, könnten ähnliche Leistungseinbußen erleben, nachdem ein Modell per Post-Training auf die bevorzugte Ausführungsumgebung eines bestimmten Anbieters zugeschnitten wurde
Nur zur Einordnung: Ich habe das hier unter
aigepostet, nicht untervibecodingEs ist auf dieser Seite wirklich schwer zu verstehen, wo die Grenze von
vibecodingeigentlich verläuftDieser Beitrag hat viel mehr mit grundlegenden LLMs, Reinforcement Learning und dem Aufbau der Ausführungsumgebungen drumherum zu tun
Wenn sogar das schon
vibecodingist, wofür bleibt dann dasai-Tag überhaupt noch übrig?vibecodingist hier inzwischen wie ein riesiger Scharlachbuchstabe, der auf alles geklebt wird, was generative AI auch nur streift oder so aussieht, als könnte es das tunIn den letzten Wochen bekamen stimmungsvolle Blogposts, READMEs großer Projekte, die LLM-Beiträge verbieten, und Beiträge mit zu vielen Sätzen der Art „nicht X, sondern Y“ alle das
vibecoding-TagIch persönlich habe komplett aufgegeben, diesem Tag noch Aufmerksamkeit zu schenken. Die Community vergibt es inzwischen so reflexhaft, dass seine eigentliche Bedeutung verschwunden ist
Trotzdem stimme ich zu, dass gerade dieser konkrete Beitrag das
vibecoding-Tag verdient, weil es hier nun einmal um Modelle geht, die tatsächlich genau dafür eingesetzt werdenGleichzeitig stimme ich aus genau dem genannten Grund auch zu, dass
ainicht entfernt werden sollte. Ich würde es gern wieder hinzufügen, aber aus irgendeinem Grund gibt es diese Option bei diesem Beitrag nichtNicht überraschend. Vendor Lock-in ist vermutlich durchaus Teil des Plans
Die Haltung „Wenn du schon für Claude bezahlst und uns bereits deinen gesamten Code schickst, dann musst du unbedingt auch noch ein kostenloses UI nutzen, das für sich genommen vielleicht kein stark genuges Lock-in-Instrument wäre“ wirkt etwas anders als die übliche Art, wie reines Vendor Lock-in normalerweise funktioniert
Es ergibt schon Sinn, dass ein Modell in der Ausführungsumgebung, auf der es trainiert wurde, also in der vom Modellanbieter gebauten Umgebung, optimal funktioniert
Wenn es massives Reinforcement Learning auf Traces wie bei Claude Code gegeben hat, hätte ich erwartet, dass es in Ausführungsumgebungen, die sich nicht wie Claude Code verhalten, deutlich schlechter wird
Mich überrascht eher, dass es in Third-Party-Ausführungsumgebungen wie Pi trotzdem noch ziemlich gut zu funktionieren scheint
Es erscheint auch plausibel, dass der Bug erst tief in Agent-Traces auftritt
Ich habe Anfang des Jahres mit einem Bug in den Modellen GPT 5.2 und 5.3 gekämpft, bei dem der Agent später im Trace statt
ls -laplötzlichls -ლაausgabIch habe das hier kurz festgehalten: https://github.com/openai/codex/issues/7988
Meiner Erfahrung nach trat das ebenfalls erst auf, nachdem der Trace tiefer geworden war
In langen Kontexten wirkt es, als könne das Modell nicht mehr klar „denken“ und falle auf primitive Instinkte zurück
Vermutlich ist das genau der Punkt, an dem die Differenz zwischen der Trainingsverteilung des Modells und der Ausführungsumgebung oder den Aufgaben, die der Nutzer dem Modell aufzwingt, die Leistung am stärksten beeinflusst
Das Problem ist, dass zu viel Reinforcement Learning dazu führt, dass es gegenüber früheren Releases in anderen Ausführungsumgebungen regressiert
An diesem Punkt sollte man Fragen stellen wie: „Beginnt hier nicht auch noch eine andere Art von Overfitting?“