Artikel von: Malte
Veröffentlicht am: 01/02/2024

GitHub Copilot in der PHP-Entwicklung – ein Erfahrungsbericht

PHP
Wie nützlich ist das KI-Tool für meine tägliche Arbeit als PHP-Entwickler?

Vor etwas über einem Jahr hat OpenAI mit ChatGPT einen Chatbot veröffentlicht, der mit seinen Nutzer:innen mittels künstlicher Intelligenz (KI) in natürlicher Sprache und bis dahin ungesehener Qualität kommunizieren kann. Seitdem überschlagen sich die Nachrichten im Bereich KI. “Neueste KI-Tools in Kalenderwoche 9, die die Arbeitswelt revolutionieren” könnte eine echte Überschrift sein – vielleicht eine KI-generierte.

Abseits des Hype und den vielen, vielen Problemen rund um KI-Tools (die ich in diesem Beitrag bewusst ausklammere) habe ich mich ganz nüchtern gefragt: Wie nützlich ist ein KI-Tool für meine tägliche Arbeit als PHP-Entwickler?

Um das herauszufinden, habe ich GitHub Copilot ausgetestet, weil es mir das stärkste KI-Tool für Entwickler:innen zu sein schien. Ich habe es als Plugin für die Entwicklungsumgebung PhpStorm benutzt, in dem es ähnlich einer Autovervollständigung (aber deutlich anders als die PhpStorm-eigene Autovervollständigung) Vorschläge hinter dem Cursor einblendet, die man durchschalten und akzeptieren oder ignorieren kann.

Ich dachte mir: Einfach mal installieren und schauen, was passiert.

Die Ergebnisse waren gemischt. Während ich durch den Einsatz von GitHub Copilot an manchen Stellen Zeit einsparte, büßte ich sie an anderen wieder ein.

Hilfreich für Routineaufgaben, störend bei komplexen Problemen

Gute Ergebnisse lieferte Copilot, wenn Boilerplate-Code nötig war, beispielsweise:

  • häufig gesehene Klassen wie User mit typischen Attributen wie Vor- und Nachname
  • einfache Unit-Tests
  • Dataprovider für Unit-Tests
  • Mapping von Datenstrukturen zwischen verschiedenen Kontexten, z. B. von JSON in eine Modell-Klasse

Ein paar Details haben mich besonders erfreut – so führte etwa selbst eine Mischung aus Konstruktor-Parametern, anämischen Settern und domänenspezifischen Methoden mit mehreren Parametern zu brauchbaren Vorschlägen.

Auch kleinere Abweichungen zwischen Parameternamen wie  $neuerVorname und Klassenattribut-Namen wie  $vorname wurden richtig aufgelöst.

Bei solchen langweiligen, lästigen Schreibarbeiten hat Copilot einige Tastenanschläge und gelegentliches Nachschauen (z. B. zur Position und zum Datentyp von Parametern) erspart und kleine Glücksgefühle ausgelöst, wenn ich im Flow bleiben und diesen sogar beschleunigen konnte.

Die eingesparte Zeit würde ich über den Tag hinweg typischerweise im einstelligen, an Tagen mit mehr langweiliger Schreibarbeit auch im niedrigen bis mittleren zweistelligen Minutenbereich beziffern.

Je tiefer ich jedoch in einer speziellen Domäne ohne Boilerplate-Gelegenheiten entwickelte, desto schlechter wurden Copilots Vorschläge.

Die Probleme reichten von unpräzisen Namen über veraltete Syntax bis hin zu völlig unpassendem Code. Regelrecht geärgert hat mich Copilot, wann immer es mich mit seinen Vorschlägen aus meinem "Gedanken-runterschreiben-Flow" in einen "Schlechten-Code-reviewen-Modus" drängte.

Wenn ich einen Kommentar mit einer Formulierung wie // Das können wir hier nicht, weil  begann, schlug Copilot neben sinnvollen Begründungen auch Ausreden und unsinnige Argumentationen vor. Mehr als einmal hatte ich das Bedürfnis, den Autor:innen der Trainingsdaten bei ihren Problemen zu helfen.

Mit Copilots schlechten Vorschlägen habe ich in den ersten Wochen typischerweise Arbeitszeit im niedrigen bis mittleren zweistelligen Minutenbereich verloren. Das wirkte sich auch negativ auf meine Arbeitszufriedenheit aus.

Ich lernte daher mit der Zeit, schlechte Vorschläge schneller als solche zu erkennen und zu ignorieren – bald bewegten sich die Arbeitszeitverluste nur noch im einstelligen bis niedrigen zweistelligen Minutenbereich. Damit hielten sich Zeitersparnis und -verlust sowie Freude und Verärgerung ungefähr die Waage.

Mein erster Eindruck von der Arbeit mit Copilot fiel dementsprechend ernüchternd aus. Aber war die Ursache des Problems vielleicht meine stümperhafte Bedienung? Diese Vermutung veranlasste mich dazu, Informationen zur effizienten Nutzung von Copilot zu recherchieren.

Meine erste Anlaufstelle war der Blogpost “Exploring Generative AI”, der schon länger auf meiner Leseliste stand. Birgitta Böckeler, die unter anderem die Erprobung von generativer KI bei dem Software-Unternehmen Thoughtworks koordiniert, hat bereits mehrere hilfreiche und absolut lesenswerte Memos zu dem Thema veröffentlicht.

Ergänzend dazu habe ich den Online-Workshop “Produktiver programmieren mit Github Copilot und ChatGPT” der heise Academy besucht. Ich fand es sehr hilfreich, in einer großen Live-Coding-Session den praktischen Einsatz vorgeführt zu bekommen und mit dem Workshop-Leiter Rainer Stropek als kompetenten Enthusiasten zu sprechen, um meine Erfahrungen einzuordnen. Er hat meine Perspektive deutlich erweitert, insbesondere um Herangehensweisen, ergänzende Tools und geeignete Aufgaben.

Im Folgenden einige Tipps, die ich...

  • bereits erfolgreich anwende,
  • derzeit noch erprobe, aber plausibel finde,
  • vielversprechend finde, aber bisher nicht erproben konnte.

Tipps zur effizienten Nutzung von GitHub Copilot

Copilot als situatives Hilfsmittel

Wer sich mit GitHub Copilot im Werkzeuggürtel an die Entwicklungsarbeit macht, muss wie bei jedem Werkzeug wissen, in welchen Situationen es sich am effizientesten einsetzen lässt. Hier bieten etwa die Memos “In-line assistance - when is it more useful?“ und “In-line assistance - how can it get in the way?“ eine erste Orientierungshilfe. Man kommt aber langfristig nicht umhin, ein eigenes Gespür dafür aufzubauen.

Copilot häufiger abschalten

In Situationen, in denen Copilot voraussichtlich Unsinn generieren wird, empfiehlt es sich, es einfach auszuschalten. So wird man nicht im Arbeitsfluss gestört.

Auf dem Mac bietet das PhpStorm-Plugin dafür von Haus aus die schöne Tastenkombination  Shift +  Option +  Command +  O, die man sich natürlich umlegen kann – oder man benutzt das Copilot-Icon in der Statusleiste oder das Menü.

Erst wenn sich die Situation geändert hat und man Copilot wieder brauchbare Vorschläge zutraut, sollte man es erneut aktivieren.

Bewusst auf Copilot einlassen

Wenn ich eine Teilaufgabe mit der Vorstellung “das könnte was für Copilot sein” beginne, bin ich viel offener für dessen Vorschläge. Statt das Gefühl zu haben, dass mein Flow durch Copilot gestört wird, stelle ich mich auf die Latenz der Vorschläge (mal Sekundenbruchteile, mal wenige Sekunden) und einen gewissen Aufwand ein, um diese gegebenenfalls zu redigieren.

Manchmal neige ich dazu, Copilot zu vermenschlichen. Einerseits glaube ich, dass das grundfalsch ist – andererseits scheint es manchmal nützlich, etwa wenn wir uns das Tool als Junior Developer vorstellen: enthusiastisch, sprüht vor Vorschlägen, ist sich aber der langfristigen Konsequenzen nicht bewusst. Es weiß noch nicht, was es alles nicht weiß und möchte manchmal nicht einsehen, dass es auf dem Holzweg ist.

Einem Junior Developer gebe ich keine vage formulierte, komplexe Aufgabe und erwarte im Gegenzug kein perfektes Programm. Um Aufgaben wie den Softwareentwurf kümmere ich mich, je nachdem auf System-, Komponenten-, Klassen- und teilweise Methoden-Ebene. Ich zerteile komplexe Aufgaben in Teilaufgaben, beschreibe kleine Artefakte und lasse den Junior Developer sich an deren Implementierung versuchen.

Spätestens beim Review des Implementierungsvorschlags hört die Vermenschlichung dann aber auf: Mit einem Menschen würde ich über den Vorschlag diskutieren und Kompromisse eingehen. Das braucht Zeit und Energie - die ich sehr gut investiert finde, wenn der Junior Developer dabei lernt. Copilot hat aus solchen Diskussionen (noch?) keinen langfristigen Lerneffekt - deshalb verwerfe ich unpassende Vorschläge einfach.

Prompt Engineering für Copilot

Die Vorschläge von Copilot hängen maßgeblich vom Algorithmus, den Trainingsdaten und dem jeweiligen Prompt ab, das vom Copilot-Plugin ans Copilot-Backend geschickt wird.

Als Nutzer:innen haben wir auf die ersten beiden Faktoren keinerlei Einfluss. Auch die Prompt-Formulierung können wir bei Copilot (im Gegensatz zu ChatGPT) nicht beeinflussen, denn diese legt das Copilot-Plugin abhängig von der Cursor-Position und dem Kontext selbst fest.

Neben der trivialen Cursor-Position können wir also am meisten auf den Kontext einwirken. Zwei Aspekte spielen dabei eine besonders große Rolle:

  • Specification/Comment Driven Development: Indem wir mit ausdrucksstarken Namen und Kommentaren die Absicht textuell beschreiben, helfen wir Copilot dabei, den Kontext zu verstehen. Auch Beispiele können hilfreich sein.

  • Neighboring Tabs: Copilot berücksichtigt nicht nur die aktuelle Datei, sondern auch eine unbestimmte Anzahl weiterer geöffneter Dateien. Es lohnt sich also, relevante Tabs geöffnet zu lassen.

GitHub Copilot Chat und ChatGPT 4

In seinem Workshop führte Rainer Stropek zwei Ergänzungen zu GitHub Copilot vor:

  • GitHub Copilot Chat ist ein zweites IDE-Plugin, das sich nicht als Autovervollständigung, sondern als Chat-Prompt einbettet und Prompts zur geöffneten Datei entgegennimmt (z. B. “Was macht diese Datei?” oder “Schreib mir einen Unit-Test für diese Datei”).

  • ChatGPT 4 wird derzeit wie das öffentlich verfügbare ChatGPT 3.5 nur über die OpenAI-Website angeboten (und ist im Gegensatz zu 3.5 kostenpflichtig). Es erfordert also einen Kontextwechsel aus der IDE, hat aber derzeit noch Feature-Vorteile gegenüber GitHub Copilot Chat, etwa den Direktzugriff auf Online-Inhalte.

Rainer skizzierte in seinem Workshop seine Kriterien für die Wahl eines Tools für ein konkretes Problem, die ich hier tabellarisch ohne jede Garantie zusammenzufassen versuche:

 GitHub CopilotGitHub Copilot ChatChatGPT 4
Cut-Off-Datum, bis zu dem das Tool allgemeine Trainingsdaten verfügbar hat2021wie Copilotunbekannt (möglicherweise nicht relevant, da das Tool ad hoc aufs Internet zugreifen kann)
Spezifität der Trainingsdatenhochwie Copilotgering
Prompt-Eingabenur indirekt, da das Plugin mit einem unbekannten Algorithmus die Cursor-Position und den Kontext in einen Prompt umwandeltdirekte Eingabe, daher viele Aufgaben möglichdirekte Eingabe, daher viele Aufgaben möglich
Dauer zur Beantwortung eines Promptsniedrig, gefühlte Latenz etwa 1 Sekundeunbekanntein- bis zweistelliger Sekundenbereich
Maximale Anzahl an Tokens pro Promptlaut GitHub: ein Teil der offenen Datei plus Teile von ungefähr ein bis zwei weiteren Dateien (plus ein bisschen drum herum)unbekannt

ChatGTP 4: ~8.000
Chat GPT 4 Turbo: ~128.000

Um die unterschiedlichen Stärken zu demonstrieren, nannte Rainer ein paar interessante Anwendungsbeispiele für Copilot Chat und ChatGPT.

GitHub Copilot Chat:

  • “Generier mir zu dieser Datei ein Diagramm in mermaid.js-Syntax” – ich habe noch keine Vorstellung davon, wie gut das funktioniert. Ein Knackpunkt könnte sein, dass ich Diagramme meistens interessanter finde, wenn sie das Zusammenspiel mehrerer Klassen zeigen – verarbeitet Copilot Chat alle Dateien in einem Verzeichnis als Kontext für einen solchen Prompt?

  • “Erkläre mir diese Klasse” – könnte wertvoll beim Verständnis fremder oder gar dem Lernen neuer Sprachen oder Sprachfeatures sein.

  • Rubberducking mit Prompts wie “Was könnte man an dieser Klasse verbessern?”

ChatGPT 4:

  • Die Eingabe eines Architektur-Diagramms in Form einer Bilddatei mit dem Prompt “Erklär mir dieses Architektur-Diagramm” lieferte ein scheinbar brauchbares Ergebnis. Highlight für mich war, dass ChatGPT eine Komponente aufgrund des stark abgekürzten Namens nicht eindeutig zuordnen konnte, aber eine als solche gekennzeichnete Vermutung dazu anstellte.

  • “Gib mir die SQL-Statements aus dem mitgeschickten Screenshot” veranlasste ChatGPT zunächst zu einer Texterkennung, dann zu einer Prüfung, ob es sich bei dem erkannten Text um gültiges SQL handelte – diese schlug fehl, was wiederum eine Korrektur des erkannten Textes auslöste.

Den selbstständigen Ablauf empfand ich in den ersten Sekunden beeindruckend - und in der folgenden halben Minute, in der man ChatGPTs Verarbeitungsschritte mitlesen konnte bzw. musste, recht langwierig. Die Selbstkontrolle der Screenshot-Texterkennung wirkte auf mich angeberisch, denn mir schien der Screenshot so deutlich, dass eine Texterkennung damit keine Probleme gehabt haben sollte. Daraus habe ich für mich den Schluss gezogen, dass spezialisierte Tools wohl auch in Zukunft bessere Ergebnisse liefern werden als ein Chat-Hans-Dampf-in-allen-Gassen. Allerdings muss man diese erst mal kennen oder zumindest wissen, wo man nach ihnen suchen soll. Da hat ChatGPT eine niedrigere Einstiegshürde.

Frischer Mut für die Nutzung von GitHub Copilot und Konsorten

Motiviert durch meine Recherchen möchte ich nun lernen, wie ich Copilot effizienter einsetzen kann und verlängere daher mein Experiment. Besonders freuen würde ich mich über einen Austausch mit meinen Kolleg:innen, wofür dieser Beitrag ein Anfang sein könnte.

Rainer sagte, dass er mit Copilot beim Coden etwa doppelt so viele Story Points wie bisher schaffen würde. Er fügte jedoch hinzu, dass er mit mehreren Sprachen jongliere, die er dann nicht immer fließend spräche. Er wisse jedenfalls nicht mehr, wann er das letzte Mal Stack Overflow geöffnet habe.

Sein Anwendungsfall unterscheidet sich zwar deutlich von meinem, in dem ich tagein, tagaus praktisch nur PHP schreibe – aber ein bisschen Steigerung ist bei mir bestimmt noch drin.

Im Bereich Technical Writing und bei Architekturthemen schaffe Rainer auch drei- bis fünfmal so viel, sagt er. Bei Letzterem setze er allerdings noch weitere KI-Tools ein, z. B. für die automatische Generierung von Transkripten seiner Architektur-Meetings via Teams. Diese dienen dann ihrerseits als Input für ChatGPT, sodass es Fragen zur Architektur beantworten kann. Das behalte ich mal im Hinterkopf.

Ein Satz von Rainer hat mir besonders dabei geholfen, meine eigenen Erfahrungen einzusortieren:

GitHub Copilot kann zwar Seniors produktiver, aber Juniors nicht zu Seniors machen.

Ansonsten bleibe ich gespannt, was die Zukunft bringen wird. "AI-Driven Legacy Modernization"? Count me in!

PS: Zwischen dem ersten Entwurf dieses Textes und seiner Veröffentlichung sind gut 8 Wochen vergangen (huch!). Mittlerweile bemerke ich unangenehm, wenn ich ohne Copilot arbeite, weil ich mich an einen neuen Flow gewöhnt habe: Sobald mein Gespür für geeignete Copilot-Aufgaben anschlägt, richte ich mich darauf ein, in der nächsten Sekunde einen Vorschlag zu bewerten - und wenn der nicht kommt, warte ich manchmal eine weitere Sekunde, bis ich merke: "Ach Mist, kein Copilot! Jetzt muss ich mir doch alle lästigen Details von Grund auf zusammen denken."

Disclaimer

Die geschilderten Erfahrungen sind meine persönlichen. Die Copilot-Erfahrung könnte zwischen verschiedenen Persönlichkeiten, Arbeitsweisen, Aufgaben und Umgebungen deutlich variieren. Selbst der Unterschied zwischen Symfony und allgemeinem PHP könnte sich z. B. aufgrund der Menge von Trainingsdaten auf die Erfahrung auswirken.

Bei meinen Tests wurde zwar Quellcode aus Kundenprojekten an GitHub Copilot übertragen. GitHub sichert aber zu, dass diese Daten ausschließlich zur Generierung von Vorschlägen verwendet werden. Insbesondere werden sie nicht als Trainingsdaten verwendet, sodass sie sich nicht in Vorschlägen für andere Entwickler:innen wiederfinden.

Die Übertragung an GitHub sehe ich unproblematisch, da wir den Quellcode unserer Kundenprojekte ohnehin bei GitHub verwalten.