Vibe Coding und Vise Coding sind relativ neue Methoden der KI-unterstützten Programmierung. Was sich hinter den Begriffen verbirgt, und wie man KI-gestützt zu wartbarem, qualitativ hochwertigem Code kommen kann, ist Thema dieses Beitrags.
Kürzlich erschien auf dem doubleSlash-Blog ein Artikel unseres Geschäftsführers Konrad Krafft mit dem Titel Vibe Coding – Die Zukunft der Softwareentwicklung mit KI. Konrad beschreibt darin, wie man sich im Softwareentwicklungsprozess von KI unterstützen lassen kann. Doch seine Darstellung geht über reines „Vibe Coding“ hinaus.
Vibe Coding
Der Begriff Vibe Coding wurde Anfang Februar 2025 geprägt von Andrej Karpathy, einem der Gründer von OpenAI, für eine bestimmte Art und Weise, Code mit Hilfe von KI generieren zu lassen. In einem Beitrag auf X schreibt er:
Es gibt eine neue Art zu coden, die ich „Vibe Coding“ nenne, bei der man sich voll dem „Vibe“ hingibt […] und vergisst, dass der Code überhaupt existiert. […] Ich akzeptiere immer alles, ich lese die Diffs nicht mehr. […] Das ist nicht allzu schlecht für Wegwerf-Wochenendprojekte, aber es ist trotzdem recht amüsant.
Andrej Karpathy über Vibe Coding
Mehr als der reine Vibe
Bei doubleSlash entwickeln wir allerdings, von Prototypen einmal abgesehen, keine Wegwerfsoftware. Die von uns entwickelten Systeme laufen in der Regel über Jahre, wenn nicht gar Jahrzehnte. Daher ist es unerlässlich, dass der Code, der entsteht, wartbar ist. Aus diesem Grund geht Konrad in seinem Beitrag einen Schritt weiter, und beschreibt die Wichtigkeit der Tatsache, dass die Entwickler die Kontrolle behalten und die KI dahingehend lenken müssen, damit der erzeugte Code die Qualitätsziele wie etwa für Wartbarkeit, Architektur und Sicherheit erfüllt.
Vise Coding
Für diese Vorgehensweise hat Deep Learning Engineer David Farago in einem LinkedIn-Beitrag den Begriff „Vise Coding“ geprägt:
[…] Vibe Coding ist weder wartbar noch nachhaltig, da sich technische
Schulden mit jeder Iteration rasch anhäufen. […] Für produktiven Code und größere Projekte benötigen wir einen anderen Ansatz mit stärkeren Leitplanken für eine bessere Code-, Test- und Dokumentationsqualität. Ich nenne diesen Ansatz „Vise Coding“ (vise = engl. für Schraubstock, Anm. d. Red.): Wie der Schraubstock für einen Handwerker das Werkstück fixiert, während Präzisionswerkzeuge angewendet werden, verwendet diese Methodik einen umfassenden Prozess, um die Ausgaben des Coding-Agenten einzuschränken und zu steuern.
David Farago
Wie Farago weiter ausführt, gehört zu diesem Prozess, dass für jeglichen Code, der erzeugt oder modifiziert wird, auch entsprechende Tests generiert werden. Zudem lässt man die KI immer nur kleine, qualitativ hochwertige Änderungen durchführen, die einfach zu verifizieren und zu reviewen sind. Auch die Dokumentation ist jeweils entsprechend anzupassen. Im Gegensatz zum Vibe Coding wird der erzeugte Code beim Vise Coding vom Entwickler geprüft, und entweder angenommen, oder nach dessen Vorstellungen nachgebessert (auch dies kann wiederum die KI übernehmen). Das Ergebnis ist lesbarer, wartbarer Code mit umfangreicher Dokumentation. Wichtig ist hierbei, der KI die Anforderungen, die an den Code gestellt werden, so präzise wie möglich mitzuteilen – z.B. dass sie nur die explizit beschriebenen Änderungen durchführen soll, dass kein duplizierter Code erzeugt werden soll, dass der Code unterschiedliche Umgebungen wie Entwicklung, Test und Produktion berücksichtigen soll, etc.
Vise Coding Dojo
Die ersten Berührungspunkte mit Vise Coding hatte ich in einem Coding Dojo, wo wir diese Art, Code zu schreiben, ausprobieren wollten. Der Fokus sollte hierbei auf der Methode liegen, daher wählten wir bewusst eine einfache Aufgabe, und zwar das String Calculator Kata, das zum Üben von Test-driven Development (TDD) gedacht ist. Die Übung ist in 9 Schritte unterteilt, die nacheinander abgearbeitet werden sollen. Die Schritte beinhalten Anforderungen, die aufeinander aufbauen, und die nacheinander implementiert werden sollen, jeweils ohne die nachfolgenden Schritte zu berücksichtigen. Dabei ist der TDD-Cycle anzuwenden: zuerst einen fehlschlagenden Test schreiben, danach den minimal notwendigen Code, damit der Test erfolgreich durchläuft, und zuletzt den Code aufräumen. Nach dem Refactoring müssen die Tests immer noch grün sein.
Für unser Experiment nutzten wir Cursor mit Claude Sonnet 4. Wir fütterten die KI Schritt für Schritt mit den Aufgaben, per Copy & Paste ohne weitere Anweisungen, um die Lösung für die jeweilige Anforderung von ihr generieren zu lassen. Gleich in Schritt 1 stellten wir fest, dass die KI mehr machte als wir eigentlich wollten. Sie erzeugte zwar unaufgefordert Tests, schrieb aber direkt auch den funktionalen Code, so dass die Tests direkt erfolgreich durchliefen. Wir wollten jedoch testgetrieben vorgehen, also zuerst lediglich die Tests erzeugen, und die Funktionalität hinterher. Dies mussten wir der KI mitteilen, was wir anhand von Cursor Rules taten. Dabei formulierten wir diese nicht selbst, sondern ließen uns auch die Regeln von der KI generieren. Ab diesem Zeitpunkt erzeugte sie stets zuerst nur die Tests, und implementierte die Funktionalität erst nach expliziter Bestätigung unsererseits.
Doch die KI machte immer noch zu viel – da das String Calculator Kata im Internet verfügbar ist, inklusive vieler Lösungen auf GitHub, „kannte“ die KI aufgrund ihres Trainings bereits die Anforderungen aus den nächsten Schritten, und implementierte manche der späteren Anforderungen direkt ohne explizite Anweisung unsererseits. Daher fügten wir eine weitere Regel hinzu, die die KI veranlasste, nur exakt das zu implementieren, was wir per Prompt spezifizieren, und das zu ignorieren, was sie bereits selbst über die Aufgaben „wusste“. Im Anschluss funktionierte der Prozess so wie wir uns das wünschten.
Refactoring mit KI
Nach der Implementierung einiger Anforderungen waren wir der Meinung, dass nun ein größeres Refactoring erforderlich war. Die Funktionalität war zwar gegeben, allerdings war alles in einer einzigen langen Methode implementiert. Auch hier ließen wir uns von der KI unterstützen und fragten sie, was getan werden könnte um den Code wartbarer zu machen. Sie antwortete gleich mit einer ganzen Liste von Maßnahmen, wie z.B., die Methode in Unterfunktionen aufzuteilen, sprechendere Namen zu vergeben u.v.m.
Wir entschieden uns dafür, erst einmal nur eine der Maßnahmen implementieren zu lassen, statt alle auf einmal (wir erinnern uns: immer nur kleine überschaubare, qualitativ hochwertige Änderungen). Dabei achteten wir darauf, dass ausschließlich der Produktionscode geändert wurde, aber kein Testcode. Schließlich dienen die Tests dazu, eventuelle Fehler aufzudecken, die ggf. durch das Refactoring entstehen. Ändern sich Tests und Produktivcode gleichzeitig, kann man nicht mehr sicher sein ob ein fehlschlagender Test nicht ggf. durch eine Änderung am Testcode entstanden ist.
Nach und nach formten wir den Code per Prompt-Anweisungen solange, bis er unseren Vorstellungen entsprach. Hier und da veranlassten wir auch eigene Refactorings, die nicht von der KI vorgeschlagen worden waren (z.B. eine Datenklasse, die von der KI als Javabean implementiert worden war in einen Record umzuwandeln), oder vergaben Namen, die unserer Meinung nach besser passten als die von der KI generierten.
Zuletzt hatten wir die komplette Aufgabe gelöst, und der dabei entstandene Code war wartbar und entsprach unseren Qualitätsansprüchen. Dabei hatten wir keine einzige Zeile Code selbst geschrieben, sondern alles von der KI machen lassen. Zudem waren wir um einiges schneller fertig als in früheren Dojos, in denen wir dieselben Aufgaben von Hand gelöst hatten. Im Großen und Ganzen waren wir letztendlich doch recht beeindruckt, wie gut alles funktioniert hatte.
Erfahrungen im Kundenprojekt
Danach habe ich auch im Kundenprojekt mit Vise Coding experimentiert. Obwohl ich üblicherweise IntelliJ nutze, verwendete ich hierfür ebenfalls Cursor – allerdings nur für die KI-Aktionen. Das Hin- und Herwechseln zwischen den IDEs funktioniert erstaunlich gut; beide übernehmen direkt die Änderungen, die in der jeweils anderen gemacht wurden. So kann ich die KI-Vorteile von Cursor nutzen, und trotzdem in meiner Lieblings-IDE arbeiten. (Ich hatte auch Jetbrains Junie getestet, dies war mir allerdings viel zu schwerfällig, und die Ergebnisse waren eher mäßig und die langen Wartezeiten nicht wert).
Aufgaben wie „Erstelle mir eine Klasse Y nach dem Vorbild von Klasse X“ oder „mache dieselbe Anpassung wie in Klasse Z“ erledigte die KI mit Bravour, inklusive Erstellung der Tests. Allerdings wurden Hilfsmethoden, die in einer Testklasse vorhanden waren für eine neue Testklasse dupliziert; für das Auslagern der Methoden in eine Hilfsklasse musste ich der KI explizite Anweisungen geben.
Mein Fazit
Letzten Endes unterscheidet sich die Entwicklung mit KI nicht besonders von der Delegation von Aufgaben an Teamkollegen: je genauer man spezifiziert was man möchte, desto eher bekommt man das gewünschte Ergebnis. Und am Ende jeglicher KI-gestützter Tätigkeit, sei es Coding, Erzeugung von Dokumentation oder Architekturschaubildern etc., braucht es immer noch den „Human in the loop“: den Menschen, der die Qualitätssicherung durchführt, und über das dafür notwendige Wissen verfügt.
Die Herausforderung in den nächsten Jahren wird noch sein, dieses Wissen parallel zur Arbeit mit der KI an die nachfolgenden Entwicklergenerationen weiterzugeben. Doch der Job des Softwareentwicklers wird wohl noch nicht so schnell von der KI ersetzt, wie es manche prognostizieren. Aber die Aufgaben werden sich verändern, weg vom handgeschriebenen Code und hin zum Prompting, zur Pflege der KI-Rules sowie der Sicherstellung der notwendigen Codequalität. Denn KI-generierter Code ist nicht automatisch wartbar, betreibbar oder sicher. Und die Ergebnisse von reinem Vibe Coding schon gleich gar nicht.
Der Beitrag Mit KI und Vise Coding zu wartbarem Code erschien zuerst auf Business -Software- und IT-Blog – Wir gestalten digitale Wertschöpfung.