Zum Inhalt springen
14. Aug. 2026·8 Min. Lesezeit

Wie KI-Programmierwerkzeuge fremden Code verändern

KI-Programmierwerkzeuge sagen Text voraus, beantworten Fragen oder handeln im Repository. So kontrollieren Sie Änderungen an unbekannten Systemen.

Wie KI-Programmierwerkzeuge fremden Code verändern

Autocomplete, Assistenten und Agenten können alle eine plausibel wirkende Funktion erzeugen. Diese oberflächliche Ähnlichkeit hat Anbieter und Entwicklungsteams dazu verleitet, drei verschiedene Betriebsmodelle mit demselben Begriff zu bezeichnen. Der Begriff verdeckt, worauf es ankommt: was das Werkzeug beobachten kann, was es ändern kann und welche Belege es sammelt, bevor es die Arbeit für erledigt erklärt.

Bei einer vertrauten Codebasis beeinflussen diese Unterschiede die Geschwindigkeit. Bei einem System, dessen Autoren nicht mehr da sind, entscheiden sie darüber, ob Sie Verhalten erhalten, das nie jemand dokumentiert hat. Eine Codevervollständigung sagt Text in der Nähe des Cursors voraus. Ein Assistent antwortet anhand eines begrenzten Kontexts. Ein Agent wählt Aktionen aus, beobachtet ihre Ergebnisse und arbeitet weiter. Wer das eine wie das andere behandelt, gewinnt falsches Vertrauen, lange bevor ein Compiler einen Fehler meldet.

Wie Autocomplete die nächste lokale Änderung vorhersagt

Autocomplete schlägt Text aus dem Code rund um den Cursor und aus zusätzlichem Repository-Kontext vor, den die jeweilige Umgebung bereitstellt. Die natürliche Arbeitseinheit ist das nächste Token, die nächste Zeile oder ein kleiner Block. Selbst wenn eine Vervollständigung eine ganze Funktion umfasst, bleibt die Interaktion eine Vorhersage: Das Werkzeug bietet Text an, und der Entwickler entscheidet, ob er ihn übernimmt.

Dieses Modell funktioniert ausgezeichnet, wenn die Absicht bereits in der aktuellen Datei erkennbar ist. Ein Muster zur Fehlerbehandlung wiederholen, einen Switch für ein bekanntes Enum ergänzen, eine Testtabelle aus benachbarten Fällen ableiten oder eine weitere Methode nach einem sichtbaren Interface schreiben, all das passt. Der Entwickler hat den Entwurf im Kopf. Das Werkzeug erspart Tipparbeit und erinnert an Syntax.

Das Language Server Protocol trifft hier eine nützliche Unterscheidung. Seine Completion-Anfrage enthält eine Dokumentposition und kann ein auslösendes Zeichen oder eine Auslöserart enthalten. Das Protokoll definiert keine Mission wie „Ersetze diese Speicherschicht“ und keine Beweisschleife, die den Ersatz bestätigt. Ein Produkt kann die Vervollständigung mit indizierten Repository-Ausschnitten anreichern, doch die Interaktion endet weiterhin bei einem Vorschlag. Mehr Retrieval kann die Vermutung verbessern, ohne aus ihr eine Untersuchung zu machen.

Autocomplete verliert seinen Nutzen, wenn die Korrektheit von Fakten außerhalb der bereitgestellten Umgebung abhängt. Ein COBOL-Absatz kann ein Feld aktualisieren, dessen Layout aus einem Copybook stammt, während JCL zum Monatsabschluss einen anderen Eingabedatensatz auswählt. Ein VB6-Event-Handler kann unbenutzt wirken, bis eine Formulardatei ihn über seinen Namen bindet. Eine PL/SQL-Prozedur kann von einer Paketvariablen abhängen, die ein früherer Aufruf initialisiert hat. Die fehlende Tatsache besitzt oft gültige Syntax und hinterlässt an der Änderungsstelle keinen sichtbaren Hinweis.

Achten Sie auf die Geste zur Annahme. Die Tabulatortaste bedeutet „Füge diese Zeichen ein“, nicht „Ich habe nachgewiesen, dass dieses Verhalten sicher ist“. Teams geraten in Schwierigkeiten, wenn die Leichtigkeit der Annahme unbemerkt die Prüfung ersetzt. Eine lange Vervollständigung verdient mehr Misstrauen, nicht weniger, denn ihre glatte Oberfläche kann mehr Annahmen verbergen.

Wie ein Assistent im bereitgestellten Gespräch arbeitet

Ein Programmierassistent beantwortet eine Anfrage mit dem Material in seinem Kontext: ausgewählter Code, offene Dateien, abgerufene Ausschnitte, Diagnosen, Anweisungen und frühere Gesprächsrunden. Seine natürliche Einheit ist das Gespräch. Er kann eine Routine erklären, Entwürfe vergleichen, einen Patch schreiben oder über einen Fehler nachdenken und hat dafür mehr Raum als Autocomplete.

Dieser zusätzliche Raum verändert die Qualität der Arbeit. Sie können einen Assistenten bitten, einen Wert durch vier Funktionen zu verfolgen, eine implizite Invariante zu erkennen oder zu erklären, warum ein geplanter Umbau Transaktionsgrenzen verändert. Sie können die erste Antwort anzweifeln und die fehlende Datei hinzufügen. Das hilft bei der Erkundung, besonders wenn ein Entwickler weiterhin entscheidet, welche Belege zählen.

Die Grenze wird leicht übersehen, weil Chatoberflächen flüssig über Dateien sprechen, die sie nie geöffnet haben. Wenn der Assistent sagt: „Diese Funktion wird nur vom Batch-Importeur aufgerufen“, kann die Behauptung eine Ableitung aus dem eingefügten Ausschnitt sein und nicht das Ergebnis einer Repository-Suche. Fragen Sie, was er geprüft hat. Eine tragfähige Antwort sollte die Aufrufstellen, Konfiguration, generierten Bindungen oder Laufzeitbelege nennen, auf denen der Schluss beruht. Kann sie das nicht, behandeln Sie die Aussage als Hypothese.

Kontextfenster lösen die Auswahl des Kontexts nicht. Eine Million Zeilen können schlecht hineinpassen, selbst wenn ein Modell eine große Eingabe akzeptiert. Quellbäume enthalten generierten Code, doppelte Versionen, Datenbankdefinitionen, Deployment-Skripte, Binärlayouts und Tests mit unterschiedlicher Aussagekraft. Mehr Tokens in einem Prompt verraten dem Assistenten nicht, welches Copybook in der Produktion aktiv ist oder welche von zwei fast gleichen Berechnungen den regulatorischen Vorgaben entspricht.

Nutzen Sie einen Assistenten, um Unsicherheit in konkrete Fragen zu verwandeln. Lassen Sie ihn die Annahmen hinter einem Patch auflisten, Dateien nennen, die diese Annahmen widerlegen würden, und den erwarteten Verhaltenstest beschreiben. Damit erhält ein Prüfer etwas Greifbares. Verlangen Sie keine Konfidenzwerte. Eine präzise klingende Prozentzahl hat keine gemeinsame Kalibrierung und trägt nichts zu den Belegen bei.

Wie ein Agent das Repository in einer Aktionsschleife ändert

Ein Programmieragent kann Aktionen auswählen und ausführen und anschließend anhand der Ergebnisse die nächste Aktion bestimmen. Er kann den Baum durchsuchen, Dateien öffnen, mehrere Module bearbeiten, einen Compiler starten, Tests ausführen, Fehler untersuchen und den Patch überarbeiten. Seine natürliche Einheit ist eine Aufgabe mit Abbruchbedingung und keine einzelne Antwort.

Die Schleife ist wichtiger als das Chatfenster. Ein brauchbarer Agent arbeitet ungefähr so:

  1. Ermittelt den Repository-Zustand und die geltenden Anweisungen.
  2. Sucht nach Definitionen, Aufrufern, Konfiguration, Tests und generierten Kanten.
  3. Nimmt eine begrenzte Änderung in einem Branch oder isolierten Worktree vor.
  4. Führt Prüfungen aus, die die Änderung widerlegen können.
  5. Untersucht den Diff und meldet verbleibende Unsicherheit.

Jede Beobachtung kann die Arbeit umlenken. Ein fehlgeschlagener Test kann eine undokumentierte Rundungsregel aufdecken. Ein Compilerfehler kann ein Build-Tag sichtbar machen, das eine andere Implementierung auswählt. Eine Suche kann eine zweite Sprache finden, die dieselbe Datenbankroutine aufruft. Der Agent kann diesen Abzweigungen folgen, ohne darauf zu warten, dass jemand die nächste Datei einfügt.

Handlungsfähigkeit bedeutet keine grenzenlose Autonomie. Schreibrechte auf Dateien, Shell-Befehle, Netzwerkzugriff, Zugangsdaten, Deployment-Rechte und Freigaberegeln sind getrennte Fähigkeiten. Ein Werkzeug, das den Baum bearbeiten, aber keine Tests ausführen kann, hat eine kürzere Beweisschleife. Ein Werkzeug, das beliebige Produktionsbefehle ausführen kann, hat ein gefährliches Berechtigungsmodell. Beide „Agenten“ zu nennen, sagt einer Entwicklungsleitung fast nichts.

Auch eine Abbruchbedingung verlangt Prüfung. „Die Tests sind grün“ reicht nur, wenn die Tests das gefährdete Verhalten abdecken. „Der Build läuft durch“ bestätigt Typ- und Verknüpfungsregeln, aber keine fachliche Gleichheit. Der Agent sollte stoppen, weil er eine ausdrückliche Abnahmebedingung erfüllt und die vereinbarten Prüfungen ausgeschöpft hat, nicht weil ihm keine offensichtliche Aktion mehr einfällt oder der Diff ordentlich aussieht.

In unbekannten Systemen ist fehlender Kontext das Hauptrisiko

Bei unbekanntem Code liegt das größte Risiko gewöhnlich nicht darin, die Ersatzsyntax zu erzeugen. Es liegt darin, den Verhaltensvertrag zu finden, der Quellcode, Jobsteuerung, Daten, Betrieb und Gewohnheiten der Nutzer verbindet. Die ursprünglichen Autoren haben diesen Vertrag oft an Stellen abgelegt, die eine moderne Repository-Suche schlecht bewertet.

Nehmen Sie einen nächtlichen Abrechnungslauf. Eine Berechnungsroutine ist isoliert gut lesbar, also schreibt ein Assistent sie in einer modernen Sprache neu, und die Unit-Tests bestehen. Das Produktionsverhalten hängt außerdem von einem JCL-Condition-Code ab, der nach einer unvollständigen Eingabe einen Schritt überspringt, von einem Feld fester Breite, in dem ein leerer Betrag etwas anderes als null bedeutet, und von einem Bedienablauf für Wiederholungen, der eine Zwischendatei erhält. Keine dieser Tatsachen muss in der Berechnungsroutine stehen. Eine lokal treue Neufassung kann bei einer Wiederholung trotzdem doppelt abrechnen.

Hier vermischt die Branche zwei Arten von Kontext. Quellkontext ist Material, das das Werkzeug lesen kann: Code, Schemata, Build-Dateien, Tickets und Tests. Betriebskontext belegt, was das System tatsächlich tut: Produktionsanfragen, Batch-Eingaben, Ausgaben, Zeitverhalten, Nebenwirkungen, Fehlerbehebung und Entscheidungen der Bediener. Mehr Quellkontext kann Betriebskontext nicht automatisch zurückgewinnen. Die Konsequenz ist eindeutig: Repository-Verständnis kann eine Migration unterstützen, aber allein keine Verhaltensparität beweisen.

Legacy-Systeme besitzen Kanten zwischen Sprachen. COBOL ruft Assembler- oder Datenbankprozeduren auf. RPG-Programme hängen von CL-Befehlen und extern beschriebenen Dateien ab. Eine Classic-ASP-Seite ruft COM-Komponenten aus VB6 auf. Eine Excel-Arbeitsmappe startet eine Access-Abfrage, die wiederum eine Stored Procedure aufruft. Ein Werkzeug, das nur die im Ticket genannte Sprache indiziert, erzeugt eine saubere Karte mit fehlenden Straßen.

Halten Sie vor einer Änderung die Beweisgrenze fest. Welche Repositories gehören dazu? Welche Scheduler, Schemata, Datenlayouts und Laufzeitspuren liegen vor? Welche externen Aufrufe werden simuliert? Welche Bedienerhandlungen bleiben unbeobachtet? Das ist keine Projektbürokratie. Es zeigt, welche Aussagen das Werkzeug tragen kann und für welche weiterhin ein Mensch mit Produktionserfahrung nötig ist.

Verhaltensparität braucht ein Orakel außerhalb des neuen Codes

Mehr als den Cursor umschreiben
CodeHero liest die ganze Codebasis, bevor verbundenes Verhalten sprachübergreifend neu entsteht.

Eine Neufassung sollte an beobachtetem Verhalten gemessen werden, nicht daran, wie vernünftig die neue Implementierung wirkt. Das sicherste Orakel ist vom erzeugten Code unabhängig: aufgezeichnete Eingaben laufen durch beide Versionen, während Ausgaben und Nebenwirkungen nach ausdrücklichen Normalisierungsregeln verglichen werden.

Ein kleiner Paritätstest kann mit einem Manifest beginnen, das Gleichheit definiert:

{
  "case": "month_end_partial_input",
  "input": "fixtures/partial.dat",
  "compare": ["stdout", "records", "exit_code"],
  "ignore": ["run_id", "processed_at"]
}

Führen Sie danach alte und neue Implementierung aus einem sauberen Zustand aus und bewahren Sie maschinenlesbare Ergebnisse auf:

case                         old  new  records  result
month_end_partial_input      04   04   1827     PASS
blank_amount_field           00   00   19       PASS
operator_rerun_after_step_3  00   08   641      FAIL

Die fehlgeschlagene Zeile ist nützlicher als ein selbstsicheres Code-Review. Sie liefert eine reproduzierbare Eingabe, den ersten abweichenden Effekt und einen Ansatzpunkt für die Untersuchung. Der Vergleich sollte Rückgabedaten, Datenbankschreibvorgänge, gesendete Nachrichten, Dateien, Exit-Codes und Reihenfolgen abdecken, wenn Verbraucher diese Reihenfolge beobachten. Normalisieren Sie nur Werte, die laut Vertrag tatsächlich variieren dürfen, etwa erzeugte Laufkennungen. Eine zu breite Ignore-Liste kann jede Implementierung korrekt aussehen lassen.

Aufgezeichneter Produktionsverkehr hat Lücken. Seltene Fehlerpfade kommen womöglich nicht vor, sensible Felder verlangen kontrollierte Behandlung, und Batch-Jobs können von Uhrzeit oder Umgebung abhängen. Ergänzen Sie entworfene Fälle für Grenzen, fehlerhafte Eingaben, Wiederholungen und Wiederherstellung. Halten Sie die alte ausführbare Datei in einer isolierten Testumgebung verfügbar, sofern Lizenz und Plattformzugriff es erlauben. Wenn kein unabhängiges Orakel existiert, sagen Sie das offen und verkleinern Sie den Umfang automatischer Änderungen.

Ich rate davon ab, modellgeschriebene Tests als einzige Abnahmesuite zu verwenden. Die Empfehlung ist beliebt, weil das Modell Code und Tests in einem Durchgang erzeugen kann und der grüne Build vollständig wirkt. Beide Artefakte können dieselbe falsche Annahme teilen. Generierte Tests helfen, bekannte Regeln auszudrücken; sie entdecken nicht unabhängig die Regeln, die bei der Erzeugung übersehen wurden.

Paritätsarbeit scheitert, wenn Teams nur den Rückgabewert des Normalfalls vergleichen. Zustandsänderungen entkommen oft über Kanäle, die der neue Entwurf beseitigen soll: eine temporäre Datei für einen anderen Job, ein von JCL geprüfter Statuscode, eine vor einem Fehler geschriebene Datenbankzeile oder ein Bericht in der von Bedienern erwarteten Sortierung. Erfassen Sie beobachtbare Effekte von außen. Wenn ein Verbraucher zwei Läufe unterscheiden kann, muss der Test diesen Unterschied vergleichen oder dokumentieren, warum der neue Vertrag ihn ändern darf.

Zeit braucht ein eigenes Testobjekt. Alte Programme lesen die Uhr häufig mehrfach, leiten Geschäftsdaten aus Scheduler-Variablen ab oder verwenden lokale Mitternacht als Verarbeitungsgrenze. Frieren Sie die Zeit ein, wo die Plattform es zulässt, und zeichnen Sie die Werte des Schedulers auf. Tun Sie dasselbe für Zufallswerte, Sequenzgeneratoren, Locale, Kodierung und Umgebungsvariablen. Ohne kontrollierte Eingaben füllt sich der Differenzbericht mit Rauschen, und Prüfer ignorieren schließlich Fehler, unter denen der entscheidende liegen kann.

Ein Datenbankvergleich braucht mehr als einen Dump der Endtabellen. Erfassen Sie Transaktionsgrenzen und Fehlerpunkte, wenn Aufrufer sie bemerken können. Zwei Implementierungen können nach Erfolg identische Zeilen besitzen und sich nach dem Fehlschlag des dritten Schreibvorgangs verschieden verhalten. Führen Sie Fehlerfälle aus, die den Job an kontrollierten Punkten unterbrechen, und vergleichen Sie übernommene Zeilen, Retry-Markierungen, Sperren, Nachrichten und das Ergebnis des dokumentierten Wiederholungsablaufs. Diese Arbeit ist mühsam, macht aber aus „Verhalten erhalten“ einen Beleg, über den Ingenieure streiten können.

Normalisierungsregeln gehören unter Review neben den Test. Eine Regel wie „Ignoriere alle Zeitstempel“ ist meistens zu breit; sie kann ein Abrechnungsdatum in der falschen Periode verstecken. Bevorzugen Sie Regeln auf Feldebene mit Begründung, zum Beispiel eine erzeugte Trace-ID zu ignorieren und den fachlich wirksamen Zeitstempel exakt zu vergleichen. Wenn sich eine Regel ändert, führen Sie frühere Fälle erneut aus und halten Sie fest, welche Abweichungen verschwinden. Die Ignore-Konfiguration ist Teil der Migrationsspezifikation und keine Aufräumarbeit.

Auch das alte System kann sich selbst widersprechen. Produktionsaufzeichnungen können einen akzeptierten Fehler, eine undokumentierte manuelle Korrektur oder je nach Deployment anderes Verhalten enthalten. Lassen Sie den Agenten nicht still die bequemste Version auswählen. Ordnen Sie jede Abweichung einer Kategorie zu: zu erhaltendes Verhalten, separat zu entscheidender Fehler, erlaubter Unterschied oder ungeklärte Beobachtung. Der Eigentümer des Geschäftsprozesses muss die zweite und dritte Kategorie genehmigen. Sonst schmuggelt eine Neufassung Richtlinienänderungen durch ein technisches Review.

Ein Paritätsergebnis muss für jemanden reproduzierbar sein, der die ursprüngliche Aufgabe nicht ausgeführt hat. Bewahren Sie Quellrevision, Build-Eingaben, Fixture-Identität, Umgebungsbeschreibung, Normalisierungsversion, Befehlszeile und Ausgabeartefakte auf. Verwenden Sie Hashes für große oder sensible Fixtures, wenn Kopieren ungeeignet ist, aber behalten Sie einen kontrollierten Pfad zu den Originalen. Schwärzen Sie Daten nach einem definierten Verfahren statt Fixtures beiläufig zu bearbeiten, denn Maskierung kann Feldlängen, Zeichensätze, Prüfsummen und Verzweigungsverhalten ändern.

Dynamisches Verhalten braucht eine andere Entdeckungsmethode als statische Aufrufgraphen. Eine Suche findet einen direkten Funktionsnamen, kann aber Reflection, String-basierte Dispatches, Datenbank-Callbacks, Plugin-Registrierung, Scheduler-Aufrufe und aus Konfiguration zusammengesetzte Namen verpassen. Verbinden Sie Quellsuche mit Build-Metadaten und Laufzeitbeobachtung. Zeichnen Sie auf einem geeigneten System für repräsentative Fälle geladene Module, ausgeführte Jobs, aufgerufene Endpunkte, geöffnete Dateien und Datenbankroutinen auf. Die Spur ersetzt das Lesen des Codes nicht; sie zeigt, welche Teile einer breiten Quellkarte am beobachteten Verhalten teilnehmen.

Aussagen zur Abdeckung müssen den Nenner nennen. Wenn ein Agent „das Repository gelesen“ hat, kann das bedeuten, dass er jede Datei aufgelistet, ausgewählten Text eingebettet, unterstützte Sprachen geparst oder einen sprachübergreifenden Abhängigkeitsgraphen gebaut hat. Das sind verschiedene Handlungen. Verlangen Sie Zahlen nach Dateityp, ausdrückliche Ausschlüsse, Parse-Fehler, nicht aufgelöste Symbole und aus Konfiguration abgeleitete Kanten. Ein kurzer Ausschlussbericht ist glaubwürdiger als die pauschale Behauptung vollständigen Verständnisses.

Testen Sie schließlich den Test selbst mit absichtlichen Mutationen. Ändern Sie ein Vergleichsfeld, kehren Sie eine geordnete Ausgabe um, ändern Sie einen Exit-Code und unterdrücken Sie eine Nebenwirkung. Jede Mutation sollte einen klaren Fehler auslösen. Bleibt alles grün, ist der Test für dieses Verhalten kein Orakel. Teams prüfen Anwendungscode bereitwillig und behandeln Testinfrastruktur als neutral; bei einer generierten Neufassung verdient die Vergleichsmechanik mindestens dasselbe Misstrauen wie der Code, den sie beurteilt.

Autocomplete gewinnt, wenn der Entwickler die Absicht bereits kennt

Autocomplete ist für eine schmale, verstandene Änderung oft das beste Werkzeug, weil Latenz und Aufwand gering bleiben. Wenn Sie den Vertrag kennen, die relevanten Typen sehen und jede Einfügung prüfen, erzeugt eine Aktionsschleife Zusatzaufwand, ohne viele neue Belege zu finden.

Gute Vervollständigungsarbeit besitzt einen engen Prüfradius. Dazu gehören das Umstellen wiederholter Assertions auf eine Tabelle, ein weiterer Parser-Zweig nach benachbarten Fällen, ein vertrauter API-Aufruf oder Serialisierungscode aus einem sichtbaren Schema. Der Entwickler kann einen falschen Vorschlag in Sekunden ablehnen, weil er bereits weiß, wie das richtige Ergebnis aussieht.

Setzen Sie eine praktische Grenze. Sobald Sie fragen müssen, ob eine andere Datei das Verhalten steuert, nehmen Sie keine großen Vervollständigungen mehr an und suchen Sie. Wenn die Änderung eine Persistenz-, Berechtigungs-, Sprach- oder asynchrone Jobgrenze überschreitet, wechseln Sie für die Analyse zu einem Assistenten oder für die Untersuchung zu einem Agenten. Unsicherheit und Auswirkungsradius bestimmen den Wechsel, nicht die Zeilenzahl. Eine einzeilige Änderung an einem Satzlayout kann riskanter sein als eine Test-Fixture mit hundert Zeilen.

Prüfen Sie Vervollständigungen wie Code eines schnellen Kollegen, der beim Designgespräch nicht dabei war. Kontrollieren Sie Fehlerpfade, Ressourcenbesitz, numerische Umwandlung, Kodierung und Annahmen zur Nebenläufigkeit. Belohnen Sie das Werkzeug nicht dafür, dass es lokalen Stil nachahmt, wenn dieser Stil einen Fehler trägt. Gerade bei Wiederholungen kann Autocomplete ein schlechtes Muster effizient vervielfachen.

Deaktivieren oder begrenzen Sie Autocomplete, wo versehentliche Offenlegung oder Einfügung nicht hinnehmbar ist. Regulierter Quellcode, Geheimnisse in benachbarter Konfiguration, erzeugte Rechtstexte und Produktionskonsolen brauchen klare Regeln. Es geht nicht darum, ob der Modellanbieter allgemein vertrauenswürdig ist. Entscheidend ist, welche Daten der Host sendet, wo die Inferenz läuft, was gespeichert wird und welche Kontrollen Ihre Umgebung durchsetzen kann.

Assistenten sind am stärksten bei begrenzbaren Fragen

Mehr als Syntax modernisieren
Legacy-Verhalten wechselt zu Go, Rust, TypeScript und Postgres, ohne alte Architektur mitzunehmen.

Ein Assistent funktioniert gut, wenn ein Entwickler die Belegmenge festlegen und die Antwort ohne Schreibrechte bewerten kann. Er eignet sich für Code-Archäologie, Entwurfsvergleiche, Patch-Reviews, Erklärungen von Abfragen und die Umwandlung einer Incident-Beobachtung in Testfälle.

Stellen Sie eine begrenzte Frage mit benannten Belegen. Fragen Sie statt „Erkläre dieses Subsystem“: „Erkläre anhand der Jobdefinition, dieser beiden Copybooks und der drei Aufrufer, wann CUSTOMER-STATUS von H zu A wechselt. Nenne für jeden Übergang Datei und Symbol und liste jeden Pfad auf, den du nicht auflösen kannst.“ Die Antwort kann weiterhin falsch sein, doch die verlangte Form macht unbelegte Sprünge sichtbar.

Der Assistent sollte Beobachtung, Schlussfolgerung und Vorschlag trennen. Eine Beobachtung lautet, dass ein Aufrufer ein leeres Feld übergibt. Eine Schlussfolgerung lautet, dass das leere Feld wahrscheinlich einen fehlenden Betrag darstellt, weil zwei Tests dieses Ergebnis erwarten. Ein Vorschlag lautet, dass der neue Parser leere Felder in einen ausdrücklichen optionalen Wert abbilden soll. Werden diese Aussagen vermischt, erscheint eine plausible Designentscheidung als angebliche Tatsache über das alte System.

Nutzen Sie das Gespräch für eine gegnerische Prüfung. Fragen Sie, was bei ungeordneten Sätzen, einem Neustart nach einem Schreibvorgang, einem Nicht-ASCII-Zeichen oder einem unabhängig commitenden Datenbankaufruf passiert. Prüfen Sie die Antworten anschließend im Quellcode oder in Laufzeitbelegen. Der Assistent ist nützlich, weil er Pfade aufzählen kann, die müde Menschen überspringen, aber eine erfundene Frage belegt nicht, dass der Pfad existiert.

Vermeiden Sie endlose Chats mit veralteten Annahmen. Sobald sich die Belegmenge wesentlich ändert, beginnen Sie eine neue Analyse mit den korrigierten Fakten und einer knappen Entscheidungsaufzeichnung. Andernfalls kann eine frühe Fehlinterpretation im Gespräch bleiben und spätere Antworten beeinflussen, obwohl das Team sie für korrigiert hält. Speichern Sie dauerhafte Erkenntnisse in Tests, Architekturnotizen oder Issue-Einträgen und nicht nur im Chatverlauf.

Agenten brauchen begrenzte Befugnisse und sichtbare Belege

Das Million-Zeilen-System bewältigen
Die Ganzcodeanalyse deckt Systeme mit über einer Million Zeilen statt bequemer Stichproben ab.

Ein Agent verdient einen größeren Umfang, wenn seine Aktionen nachvollziehbar und umkehrbar sind. Geben Sie ihm nur die für die Aufgabe nötigen Rechte, einen isolierten Branch oder Worktree, deterministische Setup-Anweisungen und Abnahmeprüfungen, die deutlich fehlschlagen. Halten Sie Produktionszugänge und Deployment-Rechte aus der Schleife heraus, sofern die Aufgabe sie nicht ausdrücklich verlangt und kein menschliches Freigabetor existiert.

Ein brauchbarer Laufbericht sollte konkrete Fragen beantworten:

  • Mit welchem Repository-Zustand und welchen Anweisungen begann der Agent?
  • Welche Dateien hat er gelesen und geändert?
  • Welche Befehle liefen, und mit welchem Exit-Ergebnis?
  • Welche Abnahmebedingungen bestanden oder scheiterten?
  • Welche Unsicherheit bleibt, und welcher Beleg würde sie auflösen?

Der Diff bleibt nötig, reicht aber nicht. Prüfer müssen auch den Weg kennen, der ihn hervorgebracht hat. Ein Agent kann einen Test löschen, damit eine Suite besteht, einen Snapshot aktualisieren, der eine Regression erfasst hat, oder eine Fallback-Konfiguration wählen, die nie in Produktion läuft. Befehlsprotokolle und Testzahlen vor und nach der Änderung legen einige dieser Abkürzungen offen. Repository-Regeln sollten andere verbieten.

Begrenzen Sie Fehler mechanisch. Beschränken Sie nach Möglichkeit beschreibbare Pfade. Verlangen Sie Freigaben vor zerstörerischen Befehlen, Abhängigkeitsänderungen, Netzwerkzugriff oder Änderungen an der Deployment-Konfiguration. Begrenzen Sie Aufgabendauer und Zahl geänderter Dateien als Alarmschwellen, nicht als Korrektheitsbeweis. Wenn eine Schwelle auslöst, bewahren Sie Arbeit und Belege für das Review auf, statt den Agenten seine eigenen Rechte erweitern zu lassen.

Sicherheit und Compliance brauchen genaue Sprache. Ein Modell innerhalb der Kundenumgebung kann Anforderungen an Datenort und Netzwerk erfüllen, verleiht aber weder dem Werkzeug noch dem resultierenden System eine Zertifizierung. Auch eine air-gapped Umgebung braucht Zugriffskontrollen, Audit-Aufzeichnungen, Herkunftsnachweise für Modell und Abhängigkeiten sowie einen Prozess zur Freigabe dessen, was die Umgebung verlässt.

Wählen Sie nach Belegen und Auswirkungsradius

Die Wahl sollte der Aussage folgen, die Sie treffen müssen. Für „Diese Zeile entspricht dem Muster, das ich bereits verstehe“ kann Autocomplete genügen. Für „Diese Dateien deuten auf dieses Verhalten“ verwenden Sie einen Assistenten und prüfen seine genannten Belege. Für „Das Repository erfüllt jetzt diese Abnahmebedingung“ kann ein Agent die Belege sammeln, sofern seine Werkzeuge und Rechte die Bedingung abdecken.

Kaufen Sie nicht den Kategorienamen. Lassen Sie Anbieter die tatsächliche Beobachtungs- und Aktionsgrenze zeigen. Kann das Werkzeug jede Sprache im Baum lesen? Verfolgt es generierte und konfigurierte Kanten? Kann es Build und Paritätstests in Ihrer Umgebung ausführen? Zeigt es Befehle und Fehler? Können Sie Schreibrechte, Netzwerk und Zugangsdaten beschränken? Was genau beendet die Arbeit? Ein polierter Patch beantwortet keine dieser Fragen.

Beginnen Sie die Werkzeugwahl für ein geerbtes System mit einer Risikotabelle und nicht mit einer Funktionsliste. Tragen Sie Verhaltensunklarheit auf einer Achse und Auswirkungsradius auf der anderen auf. Geringe Unklarheit und geringe Auswirkung sprechen für Vervollständigung. Begrenzte Unklarheit mit einer menschlichen Entscheidung spricht für einen Assistenten. Hohe Unklarheit oder eine systemübergreifende Änderung verlangt einen Agenten plus unabhängiges Orakel, und manchmal eine Verschiebung, bis das Team dieses Orakel erfassen kann.

CodeHero verwendet das letzte Modell für Legacy-Neufassungen: Die Plattform liest die gesamte mehrsprachige Codebasis, modernisiert die Architektur und prüft das Verhalten mit aufgezeichnetem Produktionsverkehr in einem Paritätstest. Jedes Projekt wird in unter 30 Tagen geliefert, doch der Zeitplan schwächt die Beweispflicht nicht; Aktionsschleife und Orakel machen diesen Zeitplan technisch diskutierbar.

Die Beschaffung sollte eine Aufgabe verwenden, die mindestens ein irreführendes lokales Muster, eine sprachübergreifende Abhängigkeit und ein nur zur Laufzeit sichtbares Verhalten enthält. Geben Sie allen Kandidaten denselben Repository-Zustand und dieselben Abnahmebelege. Vergleichen Sie unbelegte Behauptungen, ausgeschlossene Dateien, Befehle, fehlgeschlagene Versuche und Prüfaufwand so sorgfältig wie den endgültigen Patch. Ein Werkzeug, das eine nicht aufgelöste Kante zugibt, ist sicherer als eines, das die Lücke mit einer flüssigen Annahme füllt.

Auch die Verantwortung nach dem Lauf zählt. Das Team muss die Prüfungen reproduzieren, den Ersatz warten und verbleibende Ausnahmen ohne Zugriff auf eine verschwundene Chatsitzung verstehen können. Verlangen Sie gewöhnlichen Quellcode, Tests, Ausführungsanweisungen und Entscheidungsaufzeichnungen. Kann ein Anbieter die Beweiskette nicht in Formen übergeben, die Ihre Ingenieure prüfen können, bleibt das System nach der Neufassung unbekannt, nur in einer neueren Sprache.

Ein Werkzeug sollte nie mehr Befugnis erhalten, als seine Belege rechtfertigen. Prüfen Sie bei unbekanntem Code, was das Werkzeug gesehen hat, was es getan hat und wie es das Ergebnis zu beweisen versucht hat. Die drei Namen sind wichtig, weil sie dieses Gespräch erzwingen, bevor ein flüssiger Vorschlag zu einer ungeprüften Produktionsänderung wird.

FAQ

Ist ein Programmierassistent dasselbe wie ein Programmieragent?

Nein. Ein Assistent antwortet innerhalb eines bereitgestellten Gesprächs, während ein Agent Aktionen auswählen, Ergebnisse prüfen und bis zu einer Abbruchbedingung weiterarbeiten kann. Manche Produkte verbinden beide Modi, daher sollten Sie Rechte und Aktionsschleife statt des Namens prüfen.

Kann Autocomplete ein gesamtes Repository verstehen?

Ein Vervollständigungsprodukt kann Repository-Ausschnitte abrufen, doch die Interaktion bleibt eine Textvorhersage am Cursor. Retrieval kann einen Vorschlag verbessern, beweist aber nicht, dass das Werkzeug jede konfigurierte, generierte oder laufzeitabhängige Beziehung gefunden hat.

Wann sollte ich Autocomplete statt eines Agenten verwenden?

Verwenden Sie Autocomplete, wenn Sie das beabsichtigte Verhalten bereits kennen, die Änderung lokal ist und Sie jede Einfügung sofort beurteilen können. Wechseln Sie, wenn die Korrektheit eine Suche über Dateien, Sprachen, Persistenzgrenzen oder Betriebsbelege verlangt.

Sind Programmieragenten bei Legacy-Code sicher?

Das können sie sein, wenn Sie Schreibvorgänge isolieren, Rechte begrenzen, ein Aktionsprotokoll behalten und gegen ein unabhängiges Verhaltensorakel testen. Ein unbeschränkter Agent mit schwacher Testsuite kann eine falsche Annahme schneller vervielfachen, als ein Entwickler sie prüfen kann.

Welchen Kontext braucht ein KI-Werkzeug für unbekannten Code?

Es braucht relevanten Quellcode, Build- und Deployment-Definitionen, Datenlayouts, sprachübergreifende Aufrufer und Belege aus dem tatsächlichen Betrieb. Quellkontext erklärt mögliches Verhalten; aufgezeichnete Eingaben und Effekte zeigen, worauf Nutzer und nachgelagerte Systeme angewiesen sind.

Wie prüfe ich eine KI-generierte Legacy-Neufassung?

Führen Sie aufgezeichnete Eingaben durch alte und neue Implementierung und vergleichen Sie Ausgaben, Datenbankeffekte, Dateien, Nachrichten, Exit-Codes und beobachtbare Reihenfolgen. Ergänzen Sie entworfene Fälle für seltene Fehler und Wiederherstellung, weil Produktionsaufzeichnungen nie jede Grenze abdecken.

Können modellgenerierte Tests die Korrektheit des generierten Codes beweisen?

Nicht allein. Code und Tests können dieselbe falsche Deutung des alten Verhaltens teilen. Nutzen Sie generierte Tests für bestätigte Regeln und vergleichen Sie anschließend mit einem vom neuen Code unabhängigen Orakel.

Welche Rechte sollte ein Programmieragent haben?

Gewähren Sie nur die Dateien, Befehle, Netzwerkzugriffe und Zugangsdaten, die die Aufgabe verlangt. Arbeiten Sie in einem isolierten Branch oder Worktree, verlangen Sie Freigaben für zerstörerische oder Deployment-bezogene Aktionen und behalten Sie Befehle und Ergebnisse im Protokoll.

Bedeutet ein erfolgreicher Build, dass ein Agent fertig ist?

Ein erfolgreicher Build bestätigt, dass ausgewählte Kompilierungs- und Verknüpfungsprüfungen bestanden wurden. Er beweist keine fachliche Gleichheit, Wiederherstellung, Datenkompatibilität oder sichere Auslieferung. Die Abnahme braucht Bedingungen, die zum gefährdeten Verhalten passen.

Wie vergleiche ich Anbieter von KI-Programmierwerkzeugen?

Lassen Sie jeden Anbieter zeigen, was das Werkzeug beobachten kann, welche Aktionen es ausführt, wie Rechte begrenzt werden, welche Belege es speichert und was eine Aufgabe beendet. Prüfen Sie diese Aussagen an einem repräsentativen sprachübergreifenden Pfad Ihres eigenen Systems und nicht an einer vorbereiteten Greenfield-Demo.