Ich kann erkennen, wenn du Vibe Coding machst
(alexkondov.com)- In Teams lässt sich mittlerweile leicht erkennen, dass es sich um LLM-generierten Code handelt
- Dieser Code ist klar, funktional und gut getestet, hält dabei aber oft Projektkonventionen nicht ein
- Er ignoriert verschiedene bestehende Muster oder Bibliotheken und implementiert stattdessen eigene Lösungen
- In der Softwareentwicklung wächst die Sorge, dass zunehmend nur Geschwindigkeit im Fokus steht
- Am Ende zählen jedoch Qualität und Konsistenz sowie die Wartbarkeit
Spuren des Vibe Coding
- In den von Teammitgliedern geschriebenen Codeblöcken wirkt manches auf den ersten Blick klar und funktional perfekt, doch weil es die projektspezifischen Konventionen nicht einhält, erkennt man sofort, dass er von einem LLM stammt
- Obwohl bereits eine Datenabruf-Bibliothek im Projekt vorhanden ist, wird trotzdem eine eigene HTTP-Anfragen-Implementierung geschrieben, die alle Ausnahmefälle abdeckt
- Bestehende Hilfsfunktionen in Modulen werden wiederholt neu erstellt, oder obwohl es einen Mechanismus zur Konfigurationsänderung auf Modulebene gibt, wird stattdessen die globale Konfiguration angepasst
- Obwohl eine funktionale Programmierkultur etabliert ist, wird neuer klassenbasierter Code geschrieben
- Dieser Code zeigt eine Code-Entwicklung, die Menschen vor einigen Jahren so nicht mehr umgesetzt hätten
Bedeutung von Wartbarkeit und Softwaregrundsätzen
- In der Softwareentwicklung wurden lange Anstrengungen unternommen, um langfristig wartbare Muster und Standards zu etablieren
- Tatsächlich kann jeder Code schreiben, der funktioniert, aber die eigentliche Herausforderung ist Code zu schaffen, der sich über lange Zeit leicht verwalten und ändern lässt
- Nicht die reine Feature-Umsetzung ist der Maßstab, sondern eine Codebasis, die auch in der Zukunft wartbar bleibt
- „Vibe Coding“ kann diese Philosophie und Standards untergraben
Ist Geschwindigkeit der höchste Maßstab?
- Er vergleicht es mit einem neuen Barista im Café, der in Eile Kaffee verschüttet, und betont, dass Fixierung auf Geschwindigkeit nicht zu guten Ergebnissen führt
- Auch heutige Entwicklungsteams versuchen oft, zu schnell neue Software zu bauen, was zu Qualitätsverlust führt
- Menschen wollen in der Regel eher ein ordnungsgemäßes Ergebnis, selbst wenn sie ein wenig länger warten müssen
- Eigentlich dachte er, dass der Fokus auf Tempo ein Problem außerhalb der Entwicklung sei, ist aber enttäuscht, dass auch Kolleginnen und Kollegen in der Entwicklung Principien aufgeben und nur noch auf Geschwindigkeit setzen
Was wir wirklich wollen
- Es spielt keine Rolle, wie man den Code in die IDE einfügt
- Entscheidend ist die Einstellung des Entwicklers zur Codequalität
- Er erkennt an, dass LLMs eine bedeutende technische Innovation sind, betont jedoch, dass die Verantwortung für die tatsächliche Software weiterhin bei den Entwicklerinnen und Entwicklern liegt
- Er empfiehlt, konkrete bestehende Prinzipien wie „bessere Prompt-Formulierung“, „korrekte Bibliotheksauswahl“, „Bereitstellung von Beispielen“ und „Arbeiten in kleinen Datei-Einheiten“ zu kennen und anzuwenden
- Ermahnt dazu, Codequalität und Wartbarkeit nicht nur den „Gewichten“ des Modells zu überlassen
2 Kommentare
Hacker-News-Kommentare
Ich würde gern in einem Team arbeiten, in dem niemand eine neue HTTP-Fetching-Implementierung baut, wenn die im Projekt vorhandene Data-Fetching-Bibliothek bereits alle Sonderfälle abdeckt, niemand etwas neu implementiert, obwohl es schon ein passendes Utility-Funktionsmodul gibt, niemand globale Konfiguration verändert, obwohl das auch auf Modulebene ginge, und niemand neue Klassen anlegt, obwohl sonst überwiegend funktional gearbeitet wird. In der Realität machen das aber viele Entwickler immer wieder.
Ehrlich gesagt passiert so etwas in großen Projekten sehr leicht, wenn die Dokumentation schwach ist. In dem akademischen Forschungsprojekt, an dem ich arbeite, heißt es in der Codedokumentation im Grunde, der Code selbst sei selbsterklärend, und es gibt nur kurze Hinweise zu CMake-Konfiguration, Build und Benchmarks. Interne Regeln oder Konventionen muss man durch Erfahrung lernen. Wenn neue Leute dazukommen, bauen sie oft bereits vorhandene Funktionen noch einmal oder ändern globale Einstellungen. Am Ende ist es am besten, die Codebasis zu indexieren und direkt ein LLM zu fragen (die Schlüsselpersonen des Projekts sind gegangen oder antworten erst sehr spät).
Ich glaube, du verfehlst den Punkt des Autors. Wenn Geschwindigkeit die höchste Tugend ist, werden solche Dinge immer wieder passieren. Wenn Geschwindigkeit der absolute Wert ist, müsste der Output exponentiell steigen, um die technische Schuld auszugleichen. Wenn neben Geschwindigkeit noch andere Faktoren wichtig sind, muss man Schulden klug verwalten und abbauen. Im Moment wirkt es aber eher so, als würde man einfach riesige Schulden anhäufen und hoffen, dass es schon gutgeht. Und viele Leute sind tatsächlich schlecht darin, technische Schulden zu managen.
Viele erfinden bei jeder Gelegenheit das Rad neu, ignorieren erwartbare Konventionen oder verwenden gemischte Muster. Der Autor nennt das vielleicht "vibe coding", aber das ist eigentlich kein reines LLM-Problem, sondern passiert jedem, der unter Zeitdruck nur schnell Ergebnisse liefern will oder zu wenig Erfahrung hat. Die Formulierung "Code, den niemand im Team so schreiben würde" klingt eher nach Frust über eine bestimmte Person. Man sollte vorsichtig sein, diese Sichtweise einfach auf alles zu übertragen.
Ich habe auch Entwickler gesehen, die noch eine ORM-Bibliothek zusätzlich einführen. Die erste ORM reicht völlig, aber dann kommt eine zweite dazu, weil sie "gerade angesagt" ist. Ob Entwickler oder LLM, beide bringen ihre eigenen Biases mit. Es ist extrem wichtig, die Regeln und Muster eines Projekts zu kennen und innerhalb dieses Rahmens zu arbeiten. Ohne Rücksicht auf den Kontext einfach die eigene Methode durchzuziehen, ist sehr riskant. Bei Menschen kann man das über Code-Review-Kultur und die Förderung des Codelesens lösen, bei LLMs muss man alle Muster und Regeln explizit vorgeben. Sonst ist das Risiko groß, dass Code entsteht, der nicht zum Projekt passt. Entscheidend ist, Werte und klare Standards ausdrücklich festzulegen.
Ich habe tatsächlich schon in so einem guten Team gearbeitet. Es waren meist kleine, aber wichtige Projekte mit 2 bis 4 Leuten. In so einem Umfeld ist es leicht, eine Entwicklungskultur und einen Konsens zu schaffen, die Qualität und Geschwindigkeit ausbalancieren. In solchen Teams würde niemand, weder Mensch noch LLM, für solchen Code jemals ein PR absegnen.
Ich persönlich sehe LLMs als sehr juniorige Entwickler. Sie wollen ihre Arbeit gut machen und folgen Anweisungen, aber ihnen fehlt das Verständnis für die Codebasis und ihre Muster. Man muss sie durch jeden Schritt führen, potenzielle Fehler erklären, sehr konkrete und kleine Aufgaben vergeben und den Code gründlich prüfen. Ich selbst zeichne mir zuerst das Datenmodell im Kopf und gehe dann an den Code. Konkrete Erklärungen sind wichtig. Eine eiserne Regel ist bei mir, immer einen Blockkommentar am Dateianfang zu haben, der den Inhalt der Datei erklärt. Das dient nach einem Session-Neustart als eine Art zweiter Prompt. So funktioniert die Methode gut, ohne dass es sich "magisch" anfühlt, aber ungefähr 30 % der Zeit muss man hinterher noch aufräumen, umbenennen und refactoren, damit das Ergebnis ordentlich aussieht. Trotzdem kann ich mit LLMs deutlich schneller arbeiten, als wenn ich alles komplett von Hand schreiben müsste.
Begriffe wie "Junior-Entwickler" oder "Copilot" bilden die Stärken und Schwächen von LLMs manchmal nicht richtig ab. Anders als normale Menschen vergessen sie leicht Dinge und machen selbst sehr grundlegende Fehler, aber in manchen Bereichen sind sie besser als ich, etwa bei Off-by-one-Problemen mit Arrays. Außerdem kennen sie enzyklopädisch fast alles aus dem Internet. Nach meiner praktischen Erfahrung sind LLMs eher wie Jagdhunde: Der Besitzer führt die Jagd und muss sie am Ende selbst zu Ende bringen.
Der Unterschied zwischen LLMs und Junior-Entwicklern liegt in der Lernfähigkeit. Ein Junior lernt dazu und kann wachsen, ein LLM nicht. Je mehr Anweisungen man in den Prompt packt, desto eher vergisst es wieder Dinge und fällt auf generische Antworten zurück. Bei jedem neuen Prompt muss man praktisch wieder von vorn anfangen.
Für mich unterscheidet sich ein LLM nicht dramatisch davon, Code im Internet zu suchen und zu kopieren. Am Ende muss ein Entwickler den Code selbst prüfen und verifizieren, dass er korrekt funktioniert. In letzter Zeit muss ich wegen meiner Augen alle 20 Minuten Pause machen, deshalb ist Effizienz für mich noch wichtiger geworden. LLMs erzeugen Code viel schneller als Menschen, daher ist es schon ein großer Vorteil, wenn sie nur die grundlegenden Teile übernehmen. Ich generiere gerade mit Unity C# und LINQ Strukturen für SIMD, und wenn ich dem LLM einfach die gewünschten Bedingungen nenne, bekomme ich den benötigten Code oder String viel schneller, als wenn ich selbst copy-paste mache. Das Konzept, AI wie ein HUD zu verwenden, fühlt sich für mich real an. Ich brauche keine AI, die das ganze Programm baut, sondern ein starkes Entwicklungswerkzeug für kleine Einheiten.
Für mich sind LLMs ein viel besserer Ersatz für StackOverflow. Ich kann direkt fragen, was ich wissen will, und bekomme eine präzise Antwort. Darauf basierend schreibe ich den Code in meinem Stil neu oder lasse mir nur eine Funktion erzeugen. Vor dem Kopieren versuche ich unbedingt, den Code vollständig zu verstehen. Manchmal habe ich mich gefragt, ob es karrieretechnisch nicht sogar vorteilhafter wäre, einfach ein PR mit 400.000 Zeilen in einer Sprache, die man kaum kennt, in ein Open-Source-Projekt zu werfen, statt ehrlich und qualitätsorientiert zu arbeiten. Dahinter steckt die Realität, dass Years of Experience oft stärker bewertet werden als tatsächliche Fähigkeiten.
Damit LLMs erfolgreich arbeiten, sollte man sie eher auf die eigentliche Codierungsphase beschränken als auf das Denken. Es hat bei mir gut funktioniert, Aufgaben zu zerlegen und möglichst detailliert Spezifikationen, zu ändernde Dateien und Orte mit Referenzbeispielen anzugeben. Man muss nicht übertrieben kleinteilig werden, aber je mehr Hinweise man gibt, desto höher ist die Erfolgsquote. Den erzeugten Code prüfe ich trotzdem immer Stück für Stück mit
git add -p. Vorbereitung und Review kosten Zeit, aber es spart immer noch deutlich mehr Zeit und Energie, als alles selbst zu schreiben oder schlechten Code einfach stehen zu lassen.Die größte Gefahr von vibe coding ist für mich, dass gute Entwickler dadurch nur ein bisschen schneller werden, während schwächere Entwickler viel schneller viel mehr schlechten Code produzieren. Die Frage ist, ob solche Entwickler durch vibe coding besser werden oder einfach auf diesem Niveau stecken bleiben.
Meiner Erfahrung nach kann selbst ein mediokrer Entwickler sehr schnell zu einem schlechten Entwickler werden. Der Grund ist falsches Selbstvertrauen und ein sprunghafter Anstieg der Codeproduktion. Von AI erzeugter Code berücksichtigt die Gesamtarchitektur, den Informationsfluss oder das Single-Responsibility-Prinzip kaum. Er ist oft so gebaut, dass statt Exceptions einfach Placeholder zurückgegeben werden, damit der Code "sicher" wirkt. Dann muss der aufrufende Code ständig prüfen, ob das Ergebnis ein Placeholder ist oder nicht. Schon wenn die Input-Parameter schlecht sind, versucht die AI oft von sich aus, sie zu "reparieren", und ignoriert dabei die Struktur
gather_parameters → call → process_results. Und wenn man dann noch zu Tests kommt, wird das Problem viel größer.Ich glaube, viele Entwickler werden jetzt das Konzept des net-negative programmers wiederentdecken, also eines Entwicklers, dessen bloße Existenz die Projektqualität senkt.
Aus meiner Sicht ist die knappste Ressource hier Fürsorge. Vibe coding selbst verursacht den Mangel an Fürsorge nicht, AI ist nur ein Werkzeug. Alle Probleme, die der Autor nennt, gelten genauso für menschliche Junior-Entwickler und lassen sich durch bessere Führung oder Kommunikation verbessern. Ich glaube nicht, dass AI das Interesse an Qualität verringert (wer sich nicht kümmert, hat das auch früher schon nicht getan). Als Gegenargument hört man oft, dass man Chancen zur Ausbildung von Juniors verliere, aber viele nutzen AI auch nur als Übergangslösung, weil ihnen die Kapazitäten fehlen (in meinem Startup, wo Hiring schwierig ist, ist das genauso). Es kann gut sein, dass AI-Tools die Standards für Softwarequalität verändern, und ich denke, dass sich in diesem Bereich noch viel verschieben wird.
Ein LLM sollte nicht nur den aktuellen Zustand, sondern auch die Commit-Historie als Kontext nutzen. Viele Codebasen migrieren schrittweise von Muster A nach B, sodass verschiedene Muster parallel existieren. Weil eine Migration selten auf einmal abgeschlossen wird, bleibt Altes meist lange neben Neuem bestehen. Selbst wenn ein LLM, wie im HTTP-Beispiel, Muster erkennt, ist es Glückssache, welchem es folgt.
Ich habe in einer großen Codebasis gearbeitet, die über mehr als 20 Jahre Fusionen, Umbenennungen und Übernahmen erlebt hat. Dort gibt es noch Beispiele für uralte API-Aufrufe, obwohl daneben längst neuere Varianten existieren, die aber oft für bestimmte Kundenfälle erhalten wurden. Es gibt auch viele ähnliche APIs ganz ohne Dokumentation, sodass man einzeln herausfinden muss, welche davon die gewünschten Daten liefert.
Eine Möglichkeit ist, mit Dateien wie
CLAUDE.mdklar vorzugeben: "Diesem Muster folgen, jenes vermeiden."Noch wirksamer ist es aber, sehr konkret zu beschreiben, wie in jedem Teil gearbeitet werden soll, inklusive Beispielen.
Das Problem ist, dass genau dieses Kontextverständnis bei Leuten, die vibe coding betreiben, oft ohnehin schwach ausgeprägt ist. Viele hatten schon vor LLMs wenig Programmiererfahrung.
Das funktioniert auch nur, wenn Commit-Messages vernünftig geschrieben sind. In der Praxis steht dort meist nur so etwas wie "Datei geändert" oder "Bugfix".
Bei der Arbeit mit LLMs helfen Automatisierungstools wie Linter, Formatter und strenge Type-Checks enorm. Gerade wenn Codebeiträge von Leuten oder LLM-Agenten kommen, die Stil und implizite Regeln einer Codebasis nicht kennen, kann man so automatisiert prüfen und vieles direkt korrigieren. Dasselbe gilt für Tests. Automatisierte Validierung ist sowohl für Menschen als auch für Agenten sehr nützlich, um Qualität zu halten.
Ich glaube allerdings nicht, dass solche Tools in der Praxis die meisten Fälle von vibe coding verhindern, die im Artikel beschrieben werden.
Diese Tools überdecken Probleme manchmal auch nur und lassen die Oberfläche sauber aussehen.
Alle großen AI assistants bringen inzwischen standardmäßig Wege mit, um solche Probleme abzumildern, etwa
/initin Claude Code oder/Generate Cursor Rulesin Cursor. Das lässt sich organisationsweit automatisierter anwenden als bloßes context engineering. Es ist am Ende auch interessant, wie diese Tools die Entwickler-Community aufteilen.In der Praxis ignoriert CC (Claude Code) aber selbst klar formulierte Regeln in
CLAUDE.mdoft. Je länger der Dialog dauert, desto mehr wiederholen sich dieselben Probleme, und ich habe bisher keine wirklich zufriedenstellende Lösung gefunden. Deshalb finde ich es falsch, diesen Artikel einfach als bloß anti-AI abzutun.Ich bewerte Cursor gerade neu. Dass es nicht so schnell ist wie erhofft, liegt nicht nur an kleinen Fehlern (etwa wenn das LM
:durch,ersetzt), sondern auch daran, dass die Codebasis zu groß, zu alt und qualitativ zu uneinheitlich ist. LLMs übernehmen am Ende häufiger die am weitesten verbreiteten Muster, und das sind oft die schlechten. Selbst wenn man ausdrücklich sagt: "Orientiere dich an diesem Teil", wird das Modell noch von der gesamten Codebasis beeinflusst. Selbst Regeln scheinen kaum etwas anderes zu sein als direkt in den Prompt geschriebene Anweisungen. Ich frage mich, ob es dafür überhaupt eine Lösung gibt.Das Kernproblem ist nicht das Tool, sondern der auf Vibes fixierte "Coder". Ihm fehlt die Fürsorge, und entsprechend schlampig ist der Code.
Nach meiner Erfahrung gehen fast alle Probleme auf das begrenzte Kontextfenster und suboptimales "context engineering" zurück. Wenn ein LLM wichtigen Kontext wie globale Funktionen wirklich mitbekommt, nutzt es ihn relativ gut. Das eigentliche Problem ist, welchen Kontext man ohne Brüche dauerhaft mitliefert. Ich erwarte, dass es hier mit Dingen wie Sub-Agents künftig große Fortschritte geben wird.
Ich halte all das für richtig. Die beste Nutzung von LLMs ist aus meiner Sicht ähnlich wie bei einem Compiler, der eine Ebene über Assembler arbeitet: Wenn man Anforderungen sowie Ein- und Ausgaben klar beschreibt, erzeugt das Modell den Code als logische Übersetzung. Deshalb sollte man Verwirrung bzw. Entropie im Input möglichst minimieren. Ein LLM ist im Kern eine translation engine. Es ist effizienter, es zum "Übersetzen" als zum "Generieren" zu verwenden. Gleichzeitig erscheinen regelmäßig intelligentere und intuitivere Modelle, bei denen man sich weniger kümmern muss und trotzdem bessere Ergebnisse bekommt. Irgendwann werden LLMs bei jeder Aufgabe bessere Resultate liefern als menschliche Entwickler, und wahrscheinlich gilt das dann auch für andere menschliche Rollen.
Das ist eine falsche Analogie. Ein LLM ist keine Engine, die natürliche Sprache in High-Level-Code "kompiliert". Programmiersprachen und Maschinensprache verlangen klare und konsistente Bedeutungsstrukturen, natürliche Sprache gehört aber von vornherein einer anderen Abstraktionsebene an. Dasselbe LLM kann mit einem anderen Seed oder einer anderen Version zu einem anderen Ergebnis kommen. Ein Compiler dagegen muss bei identischem Input immer exakt denselben Output liefern.
Ich stimme nicht zu, dass LLMs eine Art Compiler-Abstraktionsschicht sind. In der Praxis sind sie nur beliebige Token-Generatoren. Ich habe noch kein mit LLMs erzeugtes Ergebnis gesehen, das man wirklich sinnvoll verwenden konnte. Techno-optimistische Vorstellungen von Singularität oder unbegrenzter Datenverfügbarkeit haben keine realistische Grundlage. Hochwertige Daten zu beschaffen ist extrem teuer. Im Moment sind hoffnungsvolle Prognosen daher sinnlos.
Ich habe später als der Autor verstanden, dass viele Menschen lieber schnellen und billigen Kaffee wollen als guten Kaffee. In der Realität legen die meisten mehr Wert auf Tempo und Preis als auf Qualität.
Der HN-Beitrag ist noch süßer als der eigentliche Artikel.