- Die Nutzung von AI-Coding-Tools erhöht die „Code-Schulden“
- Von zwei Unternehmen mit demselben Produkt und Umsatz ist ein Unternehmen mit 1 Million Zeilen Code deutlich schneller zu verstehen und zu ändern, wenn es statt dessen mit 100.000 Zeilen Code betrieben wird
- Das bedeutet: Je mehr Code, desto mehr Schulden; AI-Codegenerierung steigert zwar die Produktivität, kann aber gleichzeitig als Aufbau von Schulden verstanden werden
- Schulden haben eine positive und eine negative Seite
- Positiv: Sie ermöglichen kurzfristig schnelles Wachstum
- Negativ: Bei langfristigem Missmanagement können sie zum Risiko des Zusammenbruchs eines Projekts führen
- Mit anderen Worten: Schulden können gut oder schlecht sein, sie können Zinsen tragen oder nicht, sie können schnelles Wachstum ermöglichen, aber ein Projekt auch zum Scheitern bringen
- Entscheidend ist nicht, ob man das Tool verwendet, sondern die Haltung, es verantwortungsvoll zu managen
- Während ein niedrigschwelliger Zugang zu Tools gewährleistet wird, müssen auch die Qualität des erzeugten Codes und die langfristigen Kosten berücksichtigt werden
5 Kommentare
Auch wenn Code sehr lang ist, ist er keine Schuld, wenn sich leicht erklären lässt, „was er tut“.
Es geht also darum, dass der unüberlegte Einsatz von AI genau das erschwert und dadurch Schuld erzeugt.
https://github.com/kelseyhightower/nocode
Im Text wird das zwar nicht ausdrücklich klar gesagt, aber könnte damit nicht gemeint sein, dass mit KI geschriebener Code zu technischem Schulden führt, weil er einem im Vergleich zu von Menschen direkt geschriebenem Code weniger vertraut ist?
Hacker-News-Kommentare
Oberflächlich betrachtet wirkt es verkürzt, alles an der Zahl der Codezeilen (LOC) zu messen. Wenn Company A 1 Million Zeilen Code deutlich sauberer strukturiert und dokumentiert hat, kann das eine bessere Situation sein als bei Company B mit 100.000 Zeilen schlecht geschriebenem Code. Das eigentliche Problem ist nicht der Code, sondern die Komplexität, und die Zeilenzahl ist nur ein grober Indikator dafür. Code ist ein Asset. Er ist das Ergebnis und Vermögen eines Softwareunternehmens. Natürlich steigt mit mehr Assets auch die Komplexität, aber das ist eine ziemlich banale Feststellung. Genauso wie man das US-Highway-Netz nicht einfach nur deshalb insgesamt negativ bewerten kann, weil es schwer zu warten und komplex ist. Selbst wenn man die AI-Frage beiseitelässt, läuft die Aussage des Autors am Ende auf die grundlegende und jedem bekannte Schlussfolgerung hinaus: „Weniger Komplexität ist besser.“ Der wichtigste Punkt dieses Artikels lässt sich daher eher so zusammenfassen: „Prüft genau, ob AI-Coding-Tools dem fertigen Code keine unnötige Komplexität hinzufügen.“
Ich denke eher, dass Komplexität hier gar nicht der Kernpunkt ist. Wenn man davon ausgeht, dass bereits ein überlebensfähiges Softwaregeschäft existiert, und von dort rückwärts denkt, dann gilt grundsätzlich: Alle Kosten (Einkauf, Gehälter usw.) sollten so weit wie möglich reduziert werden. Dass Komplexität schlechter ist als Einfachheit, liegt letztlich daran, dass echte Komplexität teurer ist. Aber entscheidend sind am Ende die Kosten selbst, ob kurzfristig oder langfristig, ob CapEx oder OpEx. Die eigentliche Frage ist, ob von LLMs erzeugter Code die Kosten senkt oder erhöht. Codegröße, Komplexität und zahllose weitere Variablen, die weder OP noch du erwähnt habt, sind alle relevant.
Ich schaue bei meinen Funktionen meist auf die cyclomatic complexity. Ich messe die Komplexität mit SwiftLint und lasse Dinge markieren, wenn sie einen Schwellenwert überschreiten. Manchmal zerlege ich etwas auch einfach grob, aber normalerweise versuche ich unbedingt, einen Weg zu finden, es wirklich einfacher zu machen. Meine Dateien sind ziemlich lang, aber ich bemühe mich um ungefähr ein 50:50-Verhältnis zwischen Kommentaren und Code. Wenn man einem LLM den Prompt gibt, die Komplexität zu senken und die Zahl der Kommentare zu erhöhen, sollte es das ziemlich gut hinbekommen.
Code ist wie eine flüchtige Chemikalie: zugleich Asset und Schuld. Wenn man ihn korrekt und schnell einsetzt, kann man damit Geld verdienen, aber wenn man ihn liegen lässt oder verschüttet, wird er zur Last. Source Code verdirbt nicht von selbst, aber seine „Fitness for Purpose“ verändert sich ständig, wenn sich Ziele und Prozesse einer Organisation ändern.
Ich finde das Thema „Warum können wir keine einfache Software bauen?“ interessant. Beeindruckend ist an Komplexität die Aussage: „Komplexität entsteht, wenn Systeme miteinander interagieren. Komplexe Systeme können irrational eskalieren, aber auch unerwartete Kreativität hervorbringen.“
Ich denke, dass die Software selbst das Asset ist, nicht der Code. So wie bei einer Autobahn das Asset nicht der Beton ist, sondern die fertige Infrastruktur. Die Qualität des Betons beeinflusst die Wertminderung (Abschreibung) des Assets und die Wartungskosten, und das wirkt sich wiederum auf den Asset-Wert aus. Dazu muss man unbedingt auch die Perspektive des Risikomanagements einbeziehen.
Zu Beginn meiner Karriere dachte ich, dass es wichtig sei, viel Code zu schreiben. Nach 20 Jahren bin ich eher stolz darauf, noch mehr Code zu löschen. Aus Sicht eines Security Engineers ist Code nicht nur Schuld, sondern auch Risiko. Besonders externe Library-Abhängigkeiten sind ein großes Risiko. Kürzlich habe ich mit einem Kollegen ein kleines Linux-init-System mit weniger als 600 Zeilen geschrieben, das nur die Rust-Standardbibliothek nutzt und in der Produktion mehrerer Organisationen läuft. Ohne Abhängigkeiten, und der Bootvorgang ist in unter 1 Sekunde abgeschlossen. Es hat mir gezeigt, dass man appliance-artige Linux-Server auch ohne systemd und ohne Millionen Zeilen C-Code bauen kann. Wenn man es selbst macht, ist die Codebasis viel kleiner und man kann das gesamte System vollständig verstehen.
Ich denke, das Worst-Case-Szenario von AI-generiertem Code wird nicht so sehr aus Unternehmenssicht sichtbar, sondern eher in persönlicheren Projekten. Ich kann entweder 10.000 Zeilen großartigen Code selbst schreiben, den ich gut kenne, oder in einem Bruchteil der Zeit 20.000 problematische Zeilen zusammenwerfen. Ich versuche für mich, irgendwo dazwischen die Balance zu finden. Wenn ich die Entwicklung weiter ausbauen will, dann war die im ersten Fall „verlorene“ Zeit am Ende vielleicht doch ein Nachteil.
Ich denke, einen Mittelweg gibt es immer. Bei mir beschränkte sich tatsächliche Codegenerierung durch AI bisher auf in sich geschlossenen Code wie Bash- oder Python-Skripte. Diese Skripte interagieren nur mit der Command Line, deshalb sind die Grenzen klar und sie lassen sich gut verwalten. Solchen Code habe ich nach dem Schreiben oft nie wieder angeschaut. Aber Core-Business-Domain-Code von AI erzeugen zu lassen, ergibt für mich wenig Sinn, deshalb mache ich das nicht. Ich muss den Code sowieso reviewen, und was ich wirklich brauche, sind Situationen, in denen ich die Wartbarkeit verifizieren kann. Wenn man den Code nicht einfach wegwerfen kann oder nur kurz prüfen muss, braucht man Codegenerierungs-Tools nicht. Wenn AI allerdings die Rolle des Product Owners übernehmen und echte geschäftliche Verluste verstehen und verbessern könnte, wäre das etwas anderes — dann müsste man sich eher Sorgen um das Verschwinden der Nutzer machen.
Mir ging es genauso: Jedes Mal, wenn ich AI zu viel Code anvertraut habe, musste ich irgendwann den Preis in Form verlorener Produktivität zahlen. Wenn eine App vollständig aus Vibe Coding besteht, ist die wichtigste Fähigkeit vermutlich, beurteilen zu können: „Brauchte diese Funktion wirklich jemand?“ Beim Debuggen von Spaghetti-Code Zeile für Zeile überhaupt nicht zu verstehen, was etwas macht, wäre wirklich schmerzhaft.
Du sagst, im ersten Fall sei Zeit verloren gegangen, aber auch der zweite Fall (schlechterer Code in kürzerer Zeit) ist am Ende ein Zeitverlust. Im Kern geht es darum, den Mittelweg zu finden.
Kurzer Code mit schlecht gewählten Variablennamen oder übertrieben cleverem Stil ist oft viel schlechter als ausführlicher, gut dokumentierter Code mit aussagekräftigen Namen. Die Schuld ist letztlich proportional zu der Zeit, die man braucht, um Code zu verstehen, zu ändern und zu erweitern. Die Zahl der Codezeilen ist auch kein perfekter Maßstab für diese Schuld. Wenn wirklich alle anderen Bedingungen gleich wären, könnte weniger Code sogar die Lesbarkeit verschlechtern und damit die Schuld erhöhen. Deshalb halte ich die Aussage „Der Mangel an Theorie ist die Schuld“ für treffender. Aus LLM-Sicht könnte gerade kurzer Code sogar selbst eine Schuld sein. Denn der Einsatz von LLMs minimiert den Aufbau dieser Theorie — besonders in der aktuellen Lage, in der AI keine Theorie über das gesamte Projekt aufbauen und sie dem Engineer korrekt vermitteln kann.
Ich mag die Sichtweise, Programmierung als einen Prozess des Theorieaufbaus zu verstehen. Besonders bei Business-Software sollte diese Theorie geschäftszentriert sein. Zum Beispiel sollten Fragen wie „Kann man für diese Codebasis leicht Entwickler einstellen?“, „Wie stabil ist das Geschäftsmodell?“ und „Welche geschäftliche Bedeutung haben einzelne Funktionen?“ unbedingt Teil davon sein.
Mir kam gerade ein Gedanke: Könnte man AI nach den Variablennamen oder Funktionsbeschreibungen im Code fragen? Bisher habe ich AI nur für Codegenerierung verwendet.
Ich habe lange in Unternehmen gearbeitet, die keine eigenen Code-Assets hatten, deren Kerngeschäft aber von externen 3rd-party-Enterprise-Services abhing. Die Frage ist dann: Wie misst man in so einem Fall eigentlich, wie viel Code man „hat“? Wenn man etwa von einem Legacy-SaaS-Anbieter abhängt, muss man dann dessen Codezeilen ebenfalls als unsere Schuld betrachten?
Aus meiner Sicht ist das größte Risiko bei der Abhängigkeit von 3rd-party-Services, dass der Anbieter scheitert oder sich durch Übernahme oder Fusion die Servicebedingungen ändern. Oft müssen wir Dinge nutzen, die von gut finanzierten Startups kommen, deren Services aber noch nicht wirklich eigenständig tragfähig sind.
Dem stimme ich komplett zu. In einer früheren Firma haben wir ein SaaS für E-Mail-Marketing genutzt. Unser Integrationscode hatte nur etwa 500 Zeilen, aber wegen der vielen Probleme des Dienstes mussten wir enorm viel Feuerwehrarbeit leisten. Am Ende haben wir nur die Funktionen, die wir wirklich brauchten, selbst neu implementiert und ins Haus geholt. Das hat uns massiv Kosten und Ärger erspart, auch wenn die Codebasis dadurch um etwa 3.000 Zeilen gewachsen ist.
Ich verstehe es nicht ganz.
Code ist ganz klar ein Asset, aber ähnlich wie Hardware verliert er aus vielen Gründen an Wert, etwa durch Defekte oder Veränderungen in der Software- und Hardwarebranche. Je mehr Software-Code man hat, desto höher werden die jährlichen Abschreibungskosten. Wenn man ihn nicht ausreichend pflegt (zum Beispiel wenn es im Verhältnis zur Zahl der Entwickler viel zu viel Code gibt), steigen die Kosten für spätere Fehlerbehebungen exponentiell. Es ist, als käme zur Abschreibung noch „Zins“ hinzu. Deshalb kann ich nachvollziehen, warum man von „Schuld“ spricht, auch wenn der Begriff nicht perfekt passt.
Natürlich ist das perfekte Repository dieses hier.
Früher war ich stolz darauf, pro Monat netto 20.000 Zeilen Code zu löschen. Vor ein paar Jahren wollte ich das mit einem 20-köpfigen Remote-Entwicklerteam wiederholen, aber die Pull Requests kamen so schnell herein, dass ich unmöglich mithalten konnte. Heute mache ich Pair Programming mit Claude Code und GPT, und es fühlt sich ganz klar eher nach Letzterem an. Ich denke, hier gibt es Chancen für intelligente Refactorings. Allerdings braucht es wohl mehr Kontext. Ich habe so etwas mit Cursor und Claude opus 4.1 an Legacy-Code ausprobiert, aber selbst 1 Million Tokens haben nicht gereicht. Vielleicht müsste man so etwas wie eine Übersetzung zwischen persönlichem LLM und gemeinsam genutztem LLM bauen. Mich würde interessieren, ob jemand damit Erfahrung hat.
Kaum jemand scheint die sehr wichtige Frage zu stellen: „Wie viel Code ist absolut minimal nötig, um Funktion X vollständig umzusetzen?“ Natürlich kann man das nicht exakt beantworten, aber allein diese Denkweise fördert ein effizientes Mindset. Stattdessen interessieren sich viele für Dinge wie formale Verifikation, die praktisch oft nicht entscheidend sind. Ohne den minimal realisierbaren Codeumfang mitzudenken, wird formale Verifikation eher verschwenderisch und sinnlos. Und meist gehen Ingenieure auch einfach davon aus, dass der von Engineers geschriebene Code schon gut sei, obwohl er in Wirklichkeit oft unnötige Abstraktion und Komplexität hinzufügt und dadurch mehr Arbeit verursacht. Ein erheblicher Teil des Software Engineerings hat sogar negativen Wert. Natürlich ist es ein Mix aus positivem und negativem Wert, und gerade deshalb ist die Beurteilung so schwierig.