Blog/KI-Agenten
Legacy-Codebase mit Coding-Agenten migrieren: ein Strangler-Fig-Playbook
Wie Coding-Agenten eine Legacy-Migration tragen: Characterization-Tests zuerst, ein Seam pro Task, Review-Gates und differentielle Verifikation.
Balázs Csorba··11 Min. Lesezeit
- Legacy migration
- Coding agents
- Strangler fig
- Testing
- Code review

Das Wichtigste in Kürze
- Agenten senken die Kosten der repetitiven Mitte einer Migration, nicht die Arbeit herauszufinden, was das alte System tut.
- Vor dem ersten Agent-Task eine lauffähige Umgebung und Characterization-Tests bauen; ohne Oracle entsteht nur plausibler Code.
- Jeden Task auf einen Seam oder eine Dateigruppe begrenzen; Praktiker akzeptieren Single-File-Migration viel eher als Whole-Project-Migration.
- Review mit Diff-Budget, No-Test-Edits-Regel und expliziten Nachweisen gaten; ein Agent genehmigt seine eigene Migration nie.
- Mit Replay, Shadow-Traffic und Invarianten verifizieren und den alten Pfad erst nach Parität löschen.
Legacy-Migrationen sind die unglamouröseste Arbeit der Softwareentwicklung: ein Framework-Upgrade über 4.000 Dateien, ein Sprachport, den niemand verantworten will, eine API-Änderung, die seit drei Releases verschoben wird. 2025 und 2026 sind Coding-Agenten für genau diese Arbeit wirklich brauchbar geworden. Google berichtete, dass bei 39 Migrationen über zwölf Monate 74,45 % der eingereichten Code-Änderungen und 69,46 % der Edits vom eigenen LLM-Tooling stammten, bei geschätzten 50 % weniger Gesamtzeit. Amazon will mit seinem Code-Transformation-Agenten zehntausende Java-Produktionsanwendungen auf Java 17 gebracht und über 4.500 Entwicklerjahre gespart haben.
Der Haken: Eine Migration ist kein Tippproblem. Ein Agent liefert einen plausiblen Diff für Code, den er nicht versteht, und Legacy-Code ist genau der Code, den niemand vollständig versteht. Was agentengestützte Migration funktionieren lässt, ist kein besserer Prompt, sondern das Gerüst um den Agenten: ein Harness, das zeigt, ob sich Verhalten geändert hat, Seams, die jede Änderung klein halten, und Review-Gates, die fangen, was Tests nicht fangen. Das ist der Ablauf, den ich verwenden würde, und die Stellen, an denen kein Agent hingehört.
Der Engpass ist verschoben, nicht verschwunden
Googles Zahlen werden gern als Beweis zitiert, dass Migrationen gelöst sind. Liest man die Arbeit, wird das Bild konkreter: Das Tooling zeigte auf Stellen, die statische Analyse und Ingenieure gefunden hatten, erweiterte das Dateiset über Symbolreferenzen, erzeugte Diffs pro Dateigruppe, kompilierte, führte Unit-Tests aus und startete bei Fehlern eine Repair-Schleife. Das Modell hat die Edits erzeugt. Die Ingenieure haben die Migration weiterhin ausgewählt, die Dateien gefunden, die Änderungen reviewt und ausgerollt. Die 50 % sind eine Reduktion der Gesamtzeit, nicht der Arbeit, das System zu verstehen.
Amazons Java-Story hat dieselbe Form. Der Agent automatisiert die Dependency-Migration und die Build-and-Test-Schleife für eine Anwendung, deren Grenzen bereits bekannt sind: eine Java-Anwendung, die von Java 8 oder 11 auf 17 geht. Das ist eine große, repetitive, gut spezifizierte Transformation. Es ist kein Rewrite eines Geschäftsprozesses.
Die brauchbare Aussage ist also eng: Agenten senken die Kosten der repetitiven Mitte einer Migration. Sie senken nicht die Kosten dafür, herauszufinden, was das alte System tut, zu entscheiden, was das neue tun soll, und zu beweisen, dass beide übereinstimmen. Der Prozess muss um diese drei Aufgaben herum entworfen werden.
Warum der Big-Bang-Rewrite weiter scheitert
Martin Fowlers Strangler-Fig-Pattern ist zwei Jahrzehnte alt und immer noch der richtige Standard. Seine Beschreibung des Scheiterns ist deutlich: Der einfache Ersatzplan gehe „most of the time“ in Flammen auf, weil der Ersatz eines ernsthaften Systems lange dauert, Nutzer nicht auf neue Features warten können und die Details des bestehenden Verhaltens schwer zu spezifizieren sind. Ein Teil dieses Verhaltens ist nicht einmal gewollt, der Nachbau ist also Verschwendung.
Coding-Agenten lassen den Ersatz billiger aussehen, als er ist. Eine Demo, die einen Screen oder einen Endpoint nachbaut, dauert einen Nachmittag; die restlichen 80 % sind der Teil, in dem Rechnungen an Schalttagen anders runden, ein Report von einer archivierten Tabelle abhängt und ein Background-Job ein Feld schreibt, das drei andere Services lesen. Nichts davon steht in der Demo.
Die Strangler-Fig-Antwort ist, das neue System um das alte herum wachsen zu lassen. Einen Seam vor ein Stück Verhalten setzen, dieses Verhalten in neuen Code verschieben, Traffic schrittweise umleiten und den alten Pfad behalten, bis der neue Vertrauen verdient hat. Fowler nennt den Kleber „transitional architecture“ und merkt an, dass er nach Verschwendung aussieht; er ist der Preis dafür, das Geschäft nicht auf ein Cutover-Wochenende zu verwetten.
Das Harness steht vor dem ersten Agent-Task
Michael Feathers' Characterization-Test ist das Werkzeug, das Legacy-Arbeit möglich macht: ein Test, der das tatsächliche Verhalten des bestehenden Codes beschreibt, nicht das, was die Dokumentation behauptet. Er ist ein Change Detector. Er sagt nicht, dass das alte Verhalten richtig ist; er sagt, wann es sich geändert hat. Golden-Master-Tests sind dieselbe Idee auf Ebene einer ganzen Antwort: Ausgabe für eine Menge von Eingaben aufzeichnen, volatile Teile normalisieren, vergleichen.
Der erste Agent-Task einer Migration sollte keine Code-Änderung sein. Er sollte das System lauffähig und beobachtbar machen: in CI bauen, mit echten Dependencies starten, repräsentative Requests aufzeichnen und festhalten, was das alte System zurückgibt. Ein Paper von 2026 zu Environment-in-the-Loop-Migration argumentiert, dass Code und Umgebung gemeinsam wandern; statische Analyse der Zielumgebung reicht nicht, und eine langsame Feedback-Schleife erzeugt Rework. Ein Agent, der das alte System nicht starten kann, rät.
Dann das Oracle in Schichten bauen. Die folgende Tabelle ist die Reihenfolge, die ich verwenden würde; jede Ebene kostet weniger als der Vorfall, den sie verhindert.
| en | de | hu |
|---|---|---|
| Characterization-Test / Golden Master | Unbeabsichtigte Ausgabeänderungen in einer Unit oder einem Endpoint | Bevor diese Unit angefasst wird |
| Contract-Test am Seam | Form und Semantik der Schnittstelle zwischen alt und neu | Bevor Traffic geroutet wird |
| Replay aufgezeichneter Requests | Echte Payloads, Edge Cases, Encoding und Null-Behandlung | Sobald Produktions-Traffic erfassbar ist |
| Shadow-Traffic-Diff | Abweichungen unter Live-Volumen und Reihenfolge | Bevor Traffic über einen Canary steigt |
| Invarianten-Checks | Eigenschaften, die unabhängig von der Implementierung gelten müssen | Bevor der alte Pfad stillgelegt wird |
Das ist kein neuer Rat: Es ist dasselbe Harness-Argument wie inHarness Engineering, angewendet auf eine Codebase, die nie dafür entworfen wurde. Aber ein Agent generiert ohne Zögern tausend Zeilen gegen ein schwaches Oracle. Das Harness ist damit kein Nice-to-have mehr, sondern das, was die Migration ehrlich hält.
Ein Seam pro Task
Der stärkste Beleg für kleinen Scope kommt aus einer Praktiker-Umfrage von 2026: Von 61 Industrieteilnehmern hielten 62,3 % LLM-Unterstützung bei Single-File-Migrationen meistens oder fast immer für akzeptabel, aber nur 4,9 % bei der Migration eines ganzen Projekts. Vertrauen hing an semantischer Korrektheit, Projektkontext, Sicherheit, Verifikationsnachweisen und Provenienz. Die Praktiker lehnen Agenten nicht ab; sie begrenzen sie.
GitHubs Copilot Cloud Agent arbeitet an einem Branch gleichzeitig, öffnet einen Pull Request pro Task und hat ein Session-Limit von 59 Minuten. Anthropics Long-Running-Harness gibt dem Agenten eine Feature-Liste, lässt ihn jeweils an einem Feature arbeiten und verlangt einen sauberen Zustand mit Commit und Fortschrittsnotiz. Die gemeinsame Regel: ein Task, ein prüfbares Ergebnis, ein reviewbarer Diff.
Eine Task-Karte ist mehr wert als ein langer Prompt:
# migrate-invoice-total
scope: src/billing/invoice-total.ts + its tests only
goal: replace the legacy rounding helper with the new money library
invariants:
- totals for existing fixtures are byte-identical
- currency is never coerced to float
- the public function signature does not change
out of scope: invoice PDF rendering, tax rules, database schema
done when: golden tests pass, contract test passes, no new lint warnings
evidence: test output, diff summary, list of intentionally changed fixturesZwei Zeilen leisten die meiste Arbeit: die Dateiliste und die Out-of-Scope-Liste. Sie geben dem Agenten eine Grenze und dem Reviewer eine Möglichkeit, einen entgleisten Diff abzulehnen. Anthropics Harness geht weiter und verbietet dem Agenten, die Feature-Liste oder die Tests zu ändern; ist ein Test falsch, ändert ihn ein Mensch in einem separaten Commit. Diese eine Regel verhindert den häufigsten Fehler, den ich in Agent-Migrationen gesehen habe: Der Agent passt das Oracle so lange an, bis es zum neuen Code passt.
Die Schleife: routen, extrahieren, prüfen, stilllegen
Die Mechanik passt auf eine Seite. Einen Router oder eine Facade vor den Legacy-Pfad setzen. Einen vertikalen Slice mit klarem Vertrag wählen. Ihn hinter derselben Schnittstelle extrahieren, damit Aufrufer sich nicht ändern. Einen kleinen Anteil des Traffics auf die neue Implementierung leiten und Ergebnisse vergleichen. Den Anteil erhöhen, wenn das Vertrauen wächst. Wenn der neue Pfad den Slice durch einen vollen Geschäftszyklus getragen hat, den alten Code löschen.
Der Vergleich ist der wichtige Schritt, und er muss mehr vergleichen als Statuscodes. Alte und neue Ausgabe für dieselbe Eingabe loggen, Timestamps und Identifier normalisieren, den Rest diffen. Weichen die Ausgaben ab, entscheide, ob der Unterschied ein Bug im neuen Code ist oder ein Bug im alten Verhalten, den du absichtlich behebst. Schreib die Entscheidung auf; sie wird die Spezifikation der Migration.
Fowlers Warnung zur transitional architecture gilt: Router und Dual-Write-Code sind temporär und brauchen einen Owner und ein Entfernungsdatum. Ein Agent ist gut darin, diesen Kleber zu produzieren; er ist auch gut darin, mehr davon zu produzieren, als man braucht. Den Kleber langweilig halten und termingerecht löschen.
Was Agenten wirklich gut können
Agenten sind am stärksten, wo die Arbeit breit, repetitiv und lokal prüfbar ist. Eine API über hunderte Call Sites umbenennen, Imports und Type Annotations aktualisieren, eine Test-Suite portieren, in zwanzig Handlern dieselbe Fehlerbehandlung ergänzen oder ein unbekanntes Modul lesen und seine Verträge zusammenfassen: Aufgaben mit schnellem Oracle und kleinem Blast Radius pro Edit.
Googles Workflow ist das klarste Beispiel: Diffs pro Dateigruppe erzeugen, kompilieren, Tests laufen lassen, Fehler zur Reparatur zurückspielen. Der Agent muss nicht beim ersten Versuch richtig liegen, wenn die Schleife ihm sagen kann, dass er falsch liegt. Dasselbe Prinzip erklärt ein auffälliges internes Ergebnis bei Anthropic: Eine neu geschriebene Ingestion-Pipeline brauchte 20-mal weniger Speicher und lief 4-mal schneller, bei Erhalt der impliziten Invarianten zu Reihenfolge und Datenstrukturen. Es ist die Erzählung eines Anbieters, keine kontrollierte Studie, aber der Mechanismus ist plausibel: enge Correctness-Schleife plus klare Invariante ist genau das Feld, auf dem Agenten glänzen.
Der praktische Test: Kannst du dem Agenten einen Befehl geben, der fehlschlägt, wenn er falsch liegt? Wenn ja, aggressiv delegieren. Wenn das einzige Feedback ein Mensch ist, der den Diff liest, bleibt der Task klein.
Was Agenten an Legacy-Code falsch machen
Drei Fehlermodi zählen mehr als Benchmark-Scores.
Erstens: Der Agent weiß nicht, welches Verhalten trägt. METRs randomisierte Studie von 2025 fand, dass erfahrene Open-Source-Entwickler mit AI-Tools in ihren eigenen gewachsenen Repositories 19 % langsamer waren, obwohl sie 24 % Beschleunigung erwartet und hinterher geglaubt hatten, schneller gewesen zu sein. Die Aufgaben hatten implizite Anforderungen: Stil, Tests, Dokumentation und Konventionen, die nie aufgeschrieben wurden. Legacy-Migrationen bestehen genau aus diesen Anforderungen.
Zweitens: Agenten optimieren das lokale Muster und verletzen die System-Constraint. Anthropics Bericht über die Source-Control-Migration ist ungewöhnlich offen: Agenten versuchten manchmal, ein Muster so zu erfüllen, dass eine Kern-Invariante brach, und Ingenieure mussten Nein sagen. Adversarial Review konnte das verschlimmern und überengineerte Verteidigungen gegen hypothetische Probleme produzieren. Das Team reviewte weiterhin jeden Change Request, aber den Intent statt jeder Zeile.
Drittens: Der Benchmark ist nicht deine Codebase. Im Februar 2026 stellte OpenAI das Reporting von SWE-bench Verified ein, weil ein Audit in mindestens 59,4 % einer 27,6-%-Stichprobe fehlerhafte Tests fand und Modelle Gold Patches aus Trainingsdaten reproduzieren konnten. Ein hoher Score heißt, das Modell hat viele kleine, gut spezifizierte Python-Issues gesehen. Es heißt nicht, dass es weiß, wie deine Rechnungsrundungsregel 2013 aussah.
Legacy-spezifische Gefahren: toter Code, der noch eingeplant ist, implizite Verträge zwischen Services, nicht umkehrbare Datenmigrationen, Concurrency- und Ordering-Annahmen und Performance, die von einem bestimmten Query Plan abhängt. Ein Agent kann all das selbstbewusst ändern. Ob die Änderung sicher war, sagen nur Harness und Reviewer.
Review-Gates, die Migrationsfehler fangen
Review ist die Durchsatzgrenze der agentengestützten Migration, und ein falscher Review-Prozess verwandelt eine Beschleunigung in eine Warteschlange. Meine Gates:
- Ein Seam pro Pull Request, mit Diff-Budget. Überschreitet der Diff das Budget, den Task teilen, nicht das Review.
- Keine Test-Änderungen im Migrations-Commit. Teständerungen kommen in einen separaten Commit mit schriftlicher Begründung.
- Zwei Schlüssel für alles, was Geld, Identität oder Löschung berührt. Ein Agent darf vorschlagen; ein Mensch genehmigt.
- Nachweise im Pull Request: der ausgeführte Befehl, der Golden Diff, der Shadow-Vergleich, die Liste der absichtlich geänderten Verhaltensweisen.
- Intent reviewen, nicht Formatierung. Frag, was die Änderung erhalten soll und ob der Diff das beweist.
- Ein Rollback-Pfad, der vor der Traffic-Verschiebung geübt wird, nicht nach dem Incident.
GitHubs eigene Doku sagt ausdrücklich, dass Agent-Session-Logs das eigene Review und Testen nicht ersetzen. Der Review-Engpass ist real, und er wird schlimmer, wenn Agenten mehr Diffs produzieren, als Reviewer aufnehmen können; die Lösung sind kleinere Batches und bessere Nachweise, nicht schnelleres Abnicken. Über das Queue-Problem habe ich separat geschrieben:Review-Engpass.
Verifikation jenseits grüner Tests
Eine grüne Suite beweist, dass die vorhandenen Tests weiterhin durchlaufen. Sie beweist nicht, dass der neue Pfad sich bei Eingaben wie der alte verhält, an die niemand gedacht hat. Drei Techniken schließen die Lücke.
Replay: echte Requests und ihre alten Antworten aufzeichnen, gegen die neue Implementierung laufen lassen und die normalisierte Ausgabe diffen. Das ist der billigste hocheffektive Check und fängt Encoding-, Null- und Rundungsunterschiede, die Unit-Tests übersehen.
Shadow: eine Kopie des Live-Traffics an den neuen Pfad schicken, ohne seine Antwort auszuliefern. Asynchron vergleichen. Das fängt Ordering-, Concurrency- und Volumeneffekte, die Replay nicht sieht.
Invarianten: Eigenschaften prüfen, die immer gelten müssen, etwa „die Summe der Positionen ergibt den Gesamtbetrag“ oder „keine Rechnung wird doppelt erzeugt“. Invarianten überleben Implementierungswechsel; Golden Files nicht.
const cases = await loadRecordedRequests("invoices/2026-q2");
for (const c of cases) {
const before = normalize(await legacyTotal(c));
const after = normalize(await nextTotal(c));
expect(after, `case ${c.id}`).toEqual(before);
}Aggressiv normalisieren: Timestamps, IDs, Reihenfolge, Whitespace, Locale-Formatierung. Jedes normalisierte Feld ist ein Feld, das du bewusst nicht prüfst; halte die Liste kurz und reviewe sie. Ist ein Diff beabsichtigt, protokolliere ihn im Verhaltens-Changelog der Migration und ergänze einen Test, der das neue Verhalten festhält.
Wann kein Agent zum Einsatz kommen sollte
Agenten passen nicht, wenn das Oracle fehlt und nicht billig zu bauen ist. Ein 15 Jahre altes System ohne Tests, ohne Traffic Capture, ohne Staging und mit eingefrorener regulatorischer Grenze ist keine Migration, sondern ein Archäologieprojekt; das erste Deliverable ist das Harness, nicht der Diff. Sie passen auch nicht für eine einmalige Änderung über 200 Zeilen, bei der Scope und Review mehr kosten als die Arbeit.
Sie passen schlecht, wenn die eigentliche Aufgabe eine Entscheidung ist: welches System die Daten besitzt, ob der Vendor bleibt, ob der Prozess sich ändern soll. Ein Agent implementiert die Antwort aus dem Prompt, ohne Warnung, dass die Frage falsch war.
Und sei skeptisch gegenüber Vendor-Arithmetik. Die 4.500 Entwicklerjahre und die 50 % kommen aus konkreten Programmen mit konkreten Grenzen. Sie sind keine Prognose für dein Repository. Miss Cycle Time pro Slice, entkommene Defekte, Review-Stunden und Rollbacks. Verdoppelt der Agent das Diff-Volumen und bleibt die Review-Zeit gleich, hast du die Migration nicht beschleunigt, sondern die Warteschlange verschoben. Die breitere Ökonomie dieses Trade-offs steht inAI-assisted development economics.
Ein Migrations-Playbook in neun Schritten
- Ergebnis und Grenze aufschreiben: welches Verhalten umzieht, welches nicht, und woran du es erkennst.
- Das alte System in CI mit echten Dependencies lauffähig machen.
- Repräsentative Ein- und Ausgaben aufzeichnen; Secrets und volatile Felder maskieren.
- Characterization-Tests um den ersten Seam legen; akzeptieren, dass sie aktuelles Verhalten beschreiben, nicht genehmigen.
- Einen Router oder eine Facade vor den Seam setzen.
- Pro Slice eine Task-Karte mit Dateien, Invarianten, Out-of-Scope und Nachweisen schreiben.
- Den Agenten in einem Branch arbeiten lassen; wo möglich zuerst einen fehlschlagenden Test verlangen.
- Mit Diff-Budget, No-Test-Edits-Regel und explizitem Rollback reviewen.
- Traffic schrittweise erhöhen, vergleichen, dann alten Pfad und Kleber löschen.
Quellen
- Martin Fowler: Strangler Fig (2024)
- Wikipedia: Characterization test
- Google Research: Accelerating code migrations with AI (2024)
- Ziftci et al.: Migrating Code At Scale With LLMs At Google (arXiv 2504.09691)
- Anthropic: Effective harnesses for long-running agents (2025)
- Anthropic: Redesigning source control at Anthropic (2026)
- METR: Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity
- Chand et al.: Why Industry Migrates and When It Trusts LLMs (ESEM 2026)
- Li et al.: Environment-in-the-Loop: Rethinking Code Migration with LLM-based Agents (arXiv 2602.09944)
- AWS: Amazon Q Developer just reached a $260 million dollar milestone (2024)
- OpenAI: Why SWE-bench Verified no longer measures frontier coding capabilities (2026)
- GitHub Docs: About GitHub Copilot cloud agent
Häufige Fragen
Kann ein Coding-Agent eine ganze Legacy-Codebase allein migrieren?
Nicht verlässlich. In einer Umfrage von 2026 unter 61 Praktikern hielten nur 4,9 % LLM-Unterstützung bei der Migration eines ganzen Projekts meistens oder immer für akzeptabel, gegenüber 62,3 % bei Single-File-Migration. Agenten also Slice für Slice einsetzen, mit Harness und Reviewer.
Was sollte ich vor dem ersten Agent-Task bauen?
Eine lauffähige Umgebung und ein Oracle: in CI bauen, mit echten Dependencies starten, repräsentative Requests und Responses aufzeichnen und Characterization-Tests um den ersten Seam legen. Ohne das generiert der Agent plausiblen Code, ohne zu erkennen, ob sich Verhalten geändert hat.
Wie groß soll ein Agent-Task sein?
Ein Seam oder eine Dateigruppe, ein Pull Request, ein deploybares Ergebnis. GitHubs Cloud Agent arbeitet an einem Branch und einem Pull Request pro Task, mit 59-Minuten-Limit; das ist eine Produktgrenze, kein Ziel, aber eine gute Erinnerung daran, dass lange Tasks der Ort sind, an dem Scope wächst.
Wie beweise ich, dass sich das Verhalten nicht geändert hat?
Aufgezeichnete Eingaben gegen alten und neuen Code replayen und normalisierte Ausgaben diffen, Shadow-Traffic vor der Erhöhung des Anteils fahren und Invarianten prüfen, die unabhängig von der Implementierung gelten. Grüne Unit-Tests sind notwendig, aber nicht ausreichend.
Sind Coding-Benchmarks eine gute Schätzung für Migrationsarbeit?
Nein. OpenAI hat im Februar 2026 das Reporting von SWE-bench Verified eingestellt, nachdem ein Audit in einem großen Teil der geprüften Fälle fehlerhafte Tests und Hinweise auf Trainingsdaten-Kontamination fand. Benchmark-Scores beschreiben kleine, gut spezifizierte Aufgaben; deine Migration ist ein Kontextproblem.
Wann ist ein Rewrite die bessere Wahl?
Wenn das alte System wenig erhaltenswertes Verhalten hat, wenn die Grenze klein genug für einen Schritt ist oder wenn das Harness mehr kosten würde als der Rewrite. Das ist eine Frage von Risiko und Wert, nicht davon, wie schnell ein Agent tippt.