Warum sich Bugs in von GitHub Copilot generiertem Code so schwer zuordnen lassen
Inline-Vervollständigung hat ein anderes Risikoprofil als ein Agent, der ganze Dateien umschreibt. Jeder Vorschlag ist klein genug, um überprüfbar zu wirken, also prüfen Sie ihn in einer Sekunde und machen weiter. Diese eine Sekunde Aufmerksamkeit ist ehrlich gegenüber der Zeile vor Ihnen und blind gegenüber dem System drumherum.
Die Folge: Wenn etwas kaputtgeht, wird die Eingrenzung per Bisect zur Qual. Es gibt keinen einzelnen verdächtigen Commit, nur eine lange Reihe akzeptierter Vervollständigungen, von denen jede zum damaligen Zeitpunkt korrekt aussah.
Drei Arten von Drift, auf die Sie achten sollten
Konventions-Drift
Vervollständigungen folgen Mustern aus ihrem Training und aus dem umgebenden Code – und das ist nicht immer die tatsächliche Konvention Ihrer Codebasis.
Fehlerbehandlung, Null-Prüfungen und Logging driften zwischen Modulen langsam auseinander.
Duplizierte Logik
Einen generierten Helper zu akzeptieren geht schneller, als den vorhandenen zu suchen – und so ist dieselbe Regel am Ende an drei Stellen implementiert.
Später wird eine davon korrigiert, die anderen beiden nicht.
Plausible Standardwerte
Ein vorgeschlagener Standardwert, ein Timeout oder eine Sortierreihenfolge wirkt vernünftig und entspricht trotzdem nicht der Regel Ihres Produkts.
Nichts schlägt fehl. Das Verhalten ist einfach nicht das, das irgendjemand beabsichtigt hat.
Alle drei sind im Review unsichtbar und erst im laufenden Produkt sichtbar – und genau das entscheidet, wo die Prüfung hingehört.
Prüfen Sie das Verhalten in festen Abständen, nicht pro Vervollständigung
Jeden akzeptierten Vorschlag zu verifizieren ist weder möglich noch sinnvoll. Die richtige Einheit ist der Pull Request: Bis dahin ist eine zusammenhängende Menge an Änderungen entstanden, und sie ist immer noch klein genug, um sie zu durchdenken, wenn etwas nicht stimmt.
Geprüft werden soll nicht der neue Code, sondern das Verhalten, in das dieser Code eingebettet ist. Ein Pull Request, der das Rechnungsmodul berührt hat, sollte die Rechnungsstellung durchgängig durchlaufen – einschließlich der Pfade, an die der Autor nicht gedacht hat, denn genau dort versteckt sich ein plausibler Standardwert.
Wenn Sie den Verifizierungs-Skill installieren, erledigt der Agent das von selbst, statt darauf zu warten, dass ein Mensch daran denkt.
Terminal
npm install -g @testsprite/testsprite-cli
testsprite setup
Das Dashboard deckt dasselbe für alle ab, die keine lokale Installation möchten, und den vollständigen Befehlsumfang finden Sie im CLI-Repository.
Die Regressionsfrage, die niemand früh genug stellt
Die nützliche Frage bei einer Codebasis voller Vervollständigungen lautet nicht „Ist dieser Code gut?“. Sie lautet „Tut das Produkt noch das, was es letzten Monat getan hat?“. Das sind zwei verschiedene Fragen, und nur die zweite deckt Drift auf.
Um sie zu beantworten, brauchen Sie Prüfungen, die älter sind als die Änderung – und genau das schieben Teams auf. Zehn Flows, die in der ersten Woche festgehalten werden, sind mehr wert als hundert nach dem ersten Zwischenfall, denn nur die ersten zehn wurden definiert, bevor irgendjemand wusste, welche davon wichtig werden.
Die Review-Gewohnheit, die skaliert
Jede Vervollständigung zu prüfen ist unmöglich, und keine zu prüfen ist genau der Weg, auf dem sich Drift ansammelt. Was funktioniert: nach Kategorie prüfen statt Zeile für Zeile.
Wenn eine Vervollständigung einen Fehlerpfad einführt, prüfen Sie, ob er dazu passt, wie der Rest des Moduls mit Fehlern umgeht – Abweichungen sind hier die häufigste Drift und später am mühsamsten zu entwirren. Führt sie einen Standardwert ein, fragen Sie, woher dieser Wert stammt, denn ein plausibler Standardwert ist die leiseste Art, Verhalten zu verändern. Führt sie einen Helper ein, nehmen Sie sich zehn Sekunden Zeit, um nach dem vorhandenen zu suchen, denn duplizierte Logik ist der Grund, warum ein späterer Fix unvollständig bleibt.
Diese drei Prüfungen kosten jeweils ein paar Sekunden und fangen das meiste ab, was sich ansammelt. Alles andere finden Sie eher, indem Sie das Produkt ausführen, als indem Sie es lesen.
Machen Sie es automatisch
Drift entsteht allmählich, also muss die Prüfung langweilig regelmäßig laufen. Alles, was davon abhängt, dass sich jemand daran erinnert, fällt genau in der hektischen Woche aus, in der die meisten Vervollständigungen akzeptiert werden.
Wenn die Pipeline einem anderen Team gehört, ist die GitHub App der Weg des geringsten Widerstands: Sie ist ein Webhook, sie verändert nichts in Ihrem Repository, und sie wird ausgelöst, sobald Ihr Build meldet, dass die neue Version live ist. Wenn Sie die Prüfung stattdessen im Repository sichtbar haben möchten, leistet ein Schritt in GitHub Actions genau das.
Drift erkennen, ohne jede Vervollständigung zu lesen
Jeden akzeptierten Vorschlag zu prüfen ist nicht möglich, deshalb prüft TestSprite stattdessen das Verhalten, in das der Code eingebettet ist. Die Abdeckung wird aus Ihrem Produkt heraus generiert, läuft bei jedem Pull Request und beantwortet die Frage, auf die es bei einer vervollständigungslastigen Codebasis ankommt: Tut das hier noch das, was es letzten Monat getan hat?
Damit sind die drei Driftformen direkt abgedeckt. Ein plausibler Standardwert, der eine Sortierreihenfolge verändert hat, zeigt sich als Flow, der sich anders verhält. Duplizierte Logik zeigt sich, wenn eine Kopie korrigiert wird und die andere nicht. Konventions-Drift in der Fehlerbehandlung zeigt sich als Pfad, der jetzt stillschweigend fehlschlägt.
Die Prüfung läuft dort, wo die Änderung entsteht – als Kommentar am Pull Request oder als Commit-Check –, sodass eine Regression auf einen einzelnen Schwung Vervollständigungen verweist statt auf ein ganzes Quartal davon.
Ist von Copilot generierter Code schlechter als handgeschriebener Code?
Pro Zeile betrachtet meistens nicht. Das Risiko liegt in der Menge: Es gelangt mehr Code pro Stunde ins Repository, als der Review-Prozess vorgesehen hat, und damit lässt dieselbe Fehlerrate mehr Defekte durchrutschen.
Würde strengeres Review das beheben?
Teilweise – und es arbeitet gegen genau den Grund, aus dem Vervollständigung überhaupt eingesetzt wird. Die Prüfung vom Lesen auf Verhaltensverifizierung zu verlagern, erhält das Tempo und stellt das Sicherheitsnetz wieder her.
Und was ist mit den Tests, die Copilot schreibt?
Nützlich für die Abdeckung, schwach als unabhängige Prüfung. Ein Test, der aus denselben Annahmen entsteht wie der Code, stimmt dem Code schon von seiner Konstruktion her zu.
Wie viele Flows sollten wir zuerst abdecken?
Beginnen Sie mit der Handvoll, die Sie einem Kunden vorführen würden, plus jedem Pfad, der Geld oder Berechtigungen berührt. Erweitern Sie ausgehend von Zwischenfällen, nicht von einem Abdeckungsziel.
Braucht das Zugriff auf das Repository?
Die Verifizierung läuft über deren Schnittstelle gegen die ausgerollte Anwendung. Repository-Zugriff wird nur genutzt, um Ergebnisse zurück an Pull Requests und Commits zu melden.
Der Bug ist die Drift, nicht der Vorschlag.
Bugs in von GitHub Copilot generiertem Code häufen sich über viele kleine akzeptierte Vervollständigungen an. Prüfen Sie das Verhalten pro Pull Request statt pro Vorschlag, definieren Sie die Flows, bevor Sie sie brauchen, und lassen Sie die Prüfung automatisch weiterlaufen.