Warum eine schrittweise Strangler-Fig-Migration mit KI-Unterstützung zuverlässiger zum Ziel führt als ein Big-Bang-Rewrite
Viele Unternehmen betreiben geschäftskritische Kernsysteme in COBOL, Perl oder anderen Sprachen, deren letzte vollständige Dokumentation Jahrzehnte zurückliegt und deren ursprüngliche Autoren längst nicht mehr im Unternehmen sind. Ein kompletter Neubau von Grund auf klingt verlockend, scheitert in der Praxis aber regelmäßig an unterschätzter, über Jahre gewachsener Geschäftslogik. Dieser Artikel zeigt, wie sich Claude gezielt einsetzen lässt, um solche Systeme erst zu verstehen, ihre Regeln zu extrahieren und dann kontrolliert, Modul für Modul, statt in einem einzigen riskanten Schritt abzulösen.
Inhaltsverzeichnis
- 1. Warum Big-Bang-Rewrites bei Legacy-Systemen scheitern
- 2. Verständnis ohne Dokumentation aufbauen: Claude als Code-Archäologe
- 3. Geschäftslogik aus undokumentiertem Code extrahieren und verifizieren
- 4. Strangler-Fig-Migration: schrittweise statt Big Bang planen
- 5. Characterization Tests vor der Migration generieren lassen
- 6. COBOL-Datentypen-Fallstricke: COMP-3, Rundung und Skalierung
- 7. Perl-spezifische Tücken: Kontext, implizite Variablen und Regex
- 8. Verifikation durch Parallelbetrieb und Diff-Testing
- 9. Migrationsphasen im Überblick
- 10. Zusammenfassung
- 11. FAQ
1. Warum Big-Bang-Rewrites bei Legacy-Systemen scheitern
Ein vollständiger Neubau eines jahrzehntealten COBOL- oder Perl-Systems wirkt auf dem Papier oft wie der sauberste Weg: alten Ballast abwerfen, mit moderner Architektur neu anfangen, keine Kompromisse mit historischen Design-Entscheidungen eingehen müssen. In der Praxis zeigt sich jedoch immer wieder dasselbe Muster: Während der monatelangen oder sogar jahrelangen Neubau-Phase läuft das alte System parallel weiter und wird laufend um neue Anforderungen erweitert, wodurch der Neubau nie wirklich fertig wird, weil das Ziel sich ständig verschiebt.
Der eigentliche Grund für das Scheitern liegt aber tiefer: In solchen Systemen steckt über Jahrzehnte gewachsene Geschäftslogik, die nirgends vollständig dokumentiert ist, sondern sich nur aus dem tatsächlichen Verhalten des Codes ableiten lässt, etwa Sonderregeln für bestimmte Kundengruppen, historisch gewachsene Rundungsregeln oder Ausnahmebehandlungen für längst vergessene Randfälle. Ein Rewrite-Team, das diese Regeln nicht kennt, reproduziert sie im Neubau schlicht nicht, was erst Monate nach dem Go-Live in Form schwer nachvollziehbarer Fachabteilungs-Beschwerden auffällt.
2. Verständnis ohne Dokumentation aufbauen: Claude als Code-Archäologe
Der erste sinnvolle Schritt ist nicht das Schreiben von neuem Code, sondern das systematische Verstehen des Bestehenden. Claude eignet sich hierfür gut, weil es große COBOL- oder Perl-Dateien am Stück lesen und dabei Muster erkennen kann, die einem menschlichen Leser beim linearen Durchgehen leicht entgehen, etwa versteckte Abhängigkeiten zwischen weit auseinanderliegenden Programmteilen oder implizite Zustandsänderungen über globale Variablen. Wichtig ist dabei, Claude nicht nach einer reinen Übersetzung zu fragen, sondern gezielt nach dem fachlichen Zweck einzelner Abschnitte.
In der Praxis bewährt sich ein iteratives Vorgehen: Claude bekommt zunächst ein einzelnes Modul samt Aufrufkontext vorgelegt und liefert eine strukturierte Zusammenfassung der Programmlogik in Klartext, gefolgt von gezielten Rückfragen zu unklaren Stellen. Diese Rückfragen sind oft aufschlussreicher als die erste Zusammenfassung selbst, weil sie genau jene Stellen markieren, an denen der Code mehrdeutig oder inkonsistent ist und ein menschlicher Fachexperte zur Klärung hinzugezogen werden sollte, statt eine Vermutung ungeprüft zu übernehmen.
# Ein einzelnes COBOL-Modul gezielt verstehen lassen, statt blind zu übersetzen
claude "Lies PROG-BILLING.cbl vollständig. Fasse den fachlichen Zweck jeder \
Paragraph-Sektion in Klartext zusammen. Markiere explizit alle Stellen, \
an denen sich die Absicht nicht eindeutig aus dem Code ergibt, und liste \
offene Fragen an einen Fachexperten separat auf. Übersetze noch nichts.
3. Geschäftslogik aus undokumentiertem Code extrahieren und verifizieren
Sobald ein grobes Verständnis vorliegt, geht es um die eigentliche Extraktion: fachliche Regeln aus prozeduralem Code in eine sprachunabhängige, für Fachabteilungen lesbare Form zu überführen. Claude kann etwa aus einem verschachtelten COBOL-EVALUATE-Block eine Entscheidungstabelle ableiten, die dieselben Fälle in Klartext auflistet. Entscheidend ist, dass diese extrahierten Regeln anschließend von jemandem aus der Fachabteilung gegengelesen werden, der die historischen Hintergründe kennt, denn Claude kann nur wiedergeben, was im Code tatsächlich steht, nicht beurteilen, ob eine Regel fachlich noch gewollt ist oder ein vergessener Sonderfall aus den Neunzigern ist.
Diese Verifikation ist kein optionaler Nice-to-have-Schritt, sondern der eigentliche Kern der Migration, weil genau hier die spätere Korrektheit des neuen Systems entschieden wird. Ein bewährtes Vorgehen ist, die extrahierte Regel zusammen mit einem konkreten Beispiel-Datensatz vorzulegen, der zeigt, wie die Regel auf reale Eingabedaten wirkt, statt sie nur abstrakt zu beschreiben. So lässt sich schnell erkennen, ob die Regel korrekt verstanden wurde, bevor sie in neuen Code übersetzt wird.
4. Strangler-Fig-Migration: schrittweise statt Big Bang planen
Das Strangler-Fig-Muster, benannt nach der Würgefeige, die einen Wirtsbaum langsam umschließt und schließlich ersetzt, überträgt genau dieses Prinzip auf Legacy-Systeme: Statt das Altsystem komplett zu ersetzen, wird eine Routing-Schicht davorgesetzt, die Anfragen wahlweise an das alte oder das neue System weiterleitet. Modul für Modul wandert Funktionalität ins neue System, während der Rest weiter über das Altsystem läuft, bis am Ende nichts vom ursprünglichen COBOL- oder Perl-Code mehr aufgerufen wird und es gefahrlos abgeschaltet werden kann.
Claude eignet sich gut dafür, gemeinsam die Reihenfolge der zu migrierenden Module festzulegen, etwa nach Kriterien wie Änderungshäufigkeit, Kopplungsgrad zu anderen Modulen und fachlichem Risiko bei einem Fehler. Module mit geringer Kopplung und überschaubarem Risiko eignen sich als erste Kandidaten, weil sich an ihnen das gesamte Vorgehen, von der Regel-Extraktion bis zur Verifikation, mit begrenztem Schaden im Fehlerfall einüben lässt, bevor die wirklich kritischen Kernmodule angegangen werden.
<?php
declare(strict_types=1);
// Routing-Schicht im Strangler-Fig-Muster: Feature-Flag pro Modul
final class BillingRouter
{
public function __construct(
private readonly LegacyCobolBridge $legacy,
private readonly ModernBillingService $modern,
private readonly FeatureFlags $flags,
) {
}
public function calculateInvoice(CustomerId $customerId): Invoice
{
if ($this->flags->isEnabled('billing.invoice.modern', $customerId)) {
return $this->modern->calculateInvoice($customerId);
}
return $this->legacy->calculateInvoiceViaCobol($customerId);
}
}
5. Characterization Tests vor der Migration generieren lassen
Bevor auch nur eine Zeile Legacy-Code angefasst wird, braucht es ein Sicherheitsnetz, das das tatsächliche, nicht das vermeintliche Verhalten des Altsystems festhält. Genau das leisten Characterization Tests: Statt zu prüfen, ob der Code fachlich korrekt ist, dokumentieren sie einfach, was er bei gegebenen Eingaben aktuell ausgibt, inklusive aller Kuriositäten und Altlasten. Claude kann aus einem Perl-Modul systematisch Testfälle ableiten, die verschiedene Eingabekombinationen durchspielen und das jeweils beobachtete Ergebnis als Erwartungswert festschreiben.
Diese Tests laufen anschließend gegen das neue Modul und decken sofort auf, wenn die Migration eine Verhaltensänderung eingeführt hat, unabhängig davon, ob diese Änderung beabsichtigt war oder ein Übersetzungsfehler ist. Wichtig ist, jede abweichende Stelle explizit zu klären: Handelt es sich um einen Bug im Altsystem, der bewusst nicht mehr reproduziert werden soll, oder um einen tatsächlichen Fehler in der neuen Implementierung? Diese Unterscheidung lässt sich nur mit fachlichem Wissen treffen, nicht allein technisch.
# Legacy-Perl-Funktion mit implizitem Kontext, Kandidat für Characterization Tests
sub calculate_discount {
my @items = @_;
my $total = 0;
$total += $_->{price} * $_->{qty} for @items;
return $total > 500 ? $total * 0.9 : $total;
}
# Claude generiert daraus Testfaelle, die das aktuelle Verhalten festhalten,
# bevor irgendetwas an der Funktion geändert wird:
# calculate_discount({price=>100, qty=>6}) == 540 (Rabattschwelle exakt überschritten)
6. COBOL-Datentypen-Fallstricke: COMP-3, Rundung und Skalierung
COBOL-Programme verwenden für Geldbeträge häufig gepackte Dezimalzahlen über die Klausel COMP-3, deren Rundungs- und Skalierungsverhalten sich nicht ohne Weiteres eins zu eins auf moderne Fließkomma- oder Dezimaltypen übertragen lässt. Eine PIC 9(7)V99 COMP-3-Definition legt implizit zwei Nachkommastellen und ein bestimmtes Rundungsverhalten bei arithmetischen Operationen fest, das sich je nach Compiler-Einstellung unterscheiden kann. Wird diese Feinheit bei der Migration übersehen, entstehen Centbeträge-Abweichungen, die bei einzelnen Buchungen unauffällig bleiben, sich über Millionen Transaktionen aber zu spürbaren Bilanzdifferenzen summieren.
Claude lässt sich gezielt bitten, für jede geldwertrelevante Variable im Legacy-Code das exakte COMP-3-Format samt Rundungsverhalten zu dokumentieren und daraus eine passende Zuordnung zu einem modernen Decimal-Typ mit identischer Präzision vorzuschlagen, statt pauschal auf Fließkommazahlen zu setzen, die für Geldberechnungen grundsätzlich ungeeignet sind. Anschließend lohnt sich ein gezielter Testlauf mit Grenzwerten wie exakt 0,005 Beträgen, um zu prüfen, ob das neue System bei kaufmännischer Rundung dasselbe Ergebnis liefert wie das COBOL-Original.
7. Perl-spezifische Tücken: Kontext, implizite Variablen und Regex
Perl-Code aus den Neunzigern und frühen Zweitausendern nutzt häufig implizite Mechanismen, die die Sprache bewusst als Komfortfeature anbietet, für Nachfolger aber zur Falle werden: die implizite Variable $_, kontextabhängiges Verhalten von Funktionen je nach Skalar- oder Listenkontext über wantarray, sowie komplexe reguläre Ausdrücke mit unklaren Rückreferenzen. Ein Entwickler, der solchen Code zum ersten Mal liest, übersieht leicht, dass eine Funktion je nach Aufrufkontext ein komplett anderes Ergebnis zurückgibt, was bei der Übersetzung in eine Sprache ohne dieses Konzept zu stillschweigend falschem Verhalten führt.
Claude kann genau diese impliziten Stellen gezielt markieren, bevor eine Übersetzung stattfindet, etwa mit dem Hinweis, dass eine bestimmte Funktion in Skalarkontext eine Zahl, in Listenkontext aber ein ganzes Array liefert und beide Aufrufstellen im Code identifiziert werden müssen. Für komplexe Regex-Muster empfiehlt sich zusätzlich, Claude explizit um eine Zerlegung in benannte, kommentierte Teilausdrücke zu bitten, damit die eigentliche fachliche Absicht hinter dem Muster nachvollziehbar wird, statt eine kryptische Zeichenkette unverstanden eins zu eins zu übernehmen.
# Kontextabhängiges Verhalten, leicht zu übersehende Perl-Falle
sub get_customer_ids {
my @ids = (101, 205, 309);
return wantarray ? @ids : scalar(@ids);
}
# In Listenkontext: liefert (101, 205, 309)
my @all = get_customer_ids();
# In Skalarkontext: liefert 3 (die Anzahl!), nicht die erste ID
8. Verifikation durch Parallelbetrieb und Diff-Testing
Selbst mit sorgfältiger Regel-Extraktion und umfangreichen Characterization Tests bleibt ein Restrisiko, dass ein seltener Grenzfall im echten Produktionsdatenstrom übersehen wurde. Deshalb hat sich Parallelbetrieb als letzte Absicherungsstufe etabliert: Das neue Modul läuft im Schatten des Altsystems mit, verarbeitet dieselben echten Eingaben, aber sein Ergebnis wird zunächst nur protokolliert und nicht ausgeliefert, während weiterhin die Ausgabe des Altsystems maßgeblich bleibt.
Claude eignet sich gut, um aus den beiden protokollierten Ergebnisströmen ein Diff-Skript zu bauen, das Abweichungen nicht nur meldet, sondern nach Muster gruppiert, etwa alle Abweichungen bei Kunden mit einem bestimmten Rabatt-Code oder alle Abweichungen, die exakt einen Cent betragen. Diese Gruppierung macht systematische Fehler viel schneller sichtbar als eine reine Liste einzelner Differenzen, weil sich ein einzelnes falsch migriertes Regelfragment oft in Dutzenden gleichartigen Abweichungen niederschlägt.
# Ausgaben von Alt- und Neusystem im Schattenbetrieb vergleichen
diff <(sort legacy_output_2026-08-07.csv) <(sort modern_output_2026-08-07.csv) \
| claude "Gruppiere diese Diff-Zeilen nach erkennbarem Muster (Kunde, \
Rabattcode, Betragsgröße) und schätze pro Gruppe die wahrscheinlichste \
Ursache in der migrierten Regel ein."
9. Migrationsphasen im Überblick
Die folgende Tabelle fasst die typischen Phasen einer Strangler-Fig-Migration mit dem jeweiligen Claude-Einsatz und dem größten Risiko pro Phase zusammen.
| Phase | Claude-Einsatz | Ziel | Typisches Risiko |
|---|---|---|---|
| Bestandsaufnahme | Module lesen und fachlich zusammenfassen | Überblick ohne vorhandene Dokumentation | Falsche Annahmen unentdeckt übernehmen |
| Regel-Extraktion | Entscheidungstabellen aus Code ableiten | Geschäftslogik in Klartext überführen | Vergessene Sonderfälle übersehen |
| Testnetz aufbauen | Characterization Tests generieren | Aktuelles Verhalten absichern | Bugs versehentlich als Soll-Verhalten festschreiben |
| Router einführen | Feature-Flag-Struktur entwerfen | Schrittweise Umschaltung ermöglichen | Routing-Fehler treffen Produktivbetrieb |
| Modul-Migration | Regel für Regel in Zielsprache übersetzen | Modul für Modul ablösen | Rundungs- und Kontextfehler bei Übersetzung |
| Parallelbetrieb | Diffs zwischen Alt- und Neusystem gruppieren | Restrisiken vor Abschaltung aufdecken | Seltene Grenzfälle im Livebetrieb |
Mironsoft
KI-gestützte Entwicklung, Agenten-Workflows und Team-Prozesse
Claude oder andere KI-Tools im Team einsetzen, aber ohne klaren Workflow?
Wir richten KI-gestützte Entwicklungs-Workflows für Teams ein, von CLAUDE.md-Konventionen über Subagenten-Strategien bis zu Code-Review-Prozessen, die menschliche Kontrolle und KI-Tempo verbinden.
Workflow-Setup
CLAUDE.md, Projektkonventionen und Tool-Berechtigungen für das Team sauber einrichten.
Agenten-Strategie
Subagenten- und Automatisierungs-Workflows für wiederkehrende Entwicklungsaufgaben aufbauen.
Team-Onboarding
Entwickler im produktiven, sicheren Umgang mit KI-Coding-Assistenten schulen.
10. Zusammenfassung
Legacy-Migration mit Claude: Das Wichtigste auf einen Blick
Kernidee
Strangler-Fig-Migration löst Legacy-Systeme Modul für Modul ab, statt sie in einem riskanten Schritt komplett zu ersetzen.
Wichtigstes Werkzeug
Claude als Code-Archäologe, der fachliche Absicht aus undokumentiertem COBOL- und Perl-Code extrahiert.
Größtes Risiko
Vergessene Sonderregeln und Rundungsfeinheiten, die erst Monate nach dem Go-Live auffallen.
Erfolgskriterium
Parallelbetrieb mit gruppiertem Diff-Testing zeigt Abweichungen, bevor das Altsystem abgeschaltet wird.