- Literate Programming, bei dem Code und natürlichsprachige Erklärungen zu einer einzigen Erzählung verwoben werden, konnte sich nie breit durchsetzen, weil die parallele Pflege von Code und Beschreibung aufwendig ist; AI-Coding-Agenten könnten diese Kernarbeit jedoch eliminieren
- Mit
org-babel in Emacs Org Mode ist mehrsprachiges literarisches Programmieren möglich, doch in großen Projekten ist der umständliche Prozess des Extrahierens des Quellcodes (Tangling) ein limitierender Faktor
- Wenn man Agenten anweist, ein Org-Datei-basiertes Runbook zu erstellen, wird ein Workflow möglich, in dem Absichten in Textform erläutert, Codeblöcke interaktiv ausgeführt und Ergebnisse im Dokument gespeichert werden
- Da der Agent die Synchronisierung zwischen Beschreibung und Code sowie das Tangling automatisch übernimmt, entfällt die Mühe, bei Codeänderungen die Erklärungen neu zu schreiben, und zugleich werden die Stärken von LLMs bei Übersetzung und Zusammenfassung genutzt
- In einer Entwicklung, in der sich die Rolle von Engineers vom Schreiben von Code hin zum Lesen von Code verschiebt, rückt die praktische Nutzbarkeit eines von Agenten gepflegten narrativen Codebestands als zentrale Frage in den Vordergrund
Konzept und Grenzen des literarischen Programmierens
- Literate Programming ist die Idee, Code mit natürlichsprachigen Erklärungen zu vermischen, sodass selbst Leser ohne Vorwissen eine Codebasis als zusammenhängende Erzählung lesen und ihre Funktionsweise verstehen können
- Das Konzept ist reizvoll, in der Praxis entsteht jedoch die Last, zwei parallele Erzählungen zu pflegen – den Code selbst und die Erklärung –, und genau das ist der grundlegende Grund für die begrenzte Verbreitung
- Die in der Praxis häufigste Form sind Jupyter-Notebooks aus der Data-Science-Community, in denen Erklärungen, Berechnungen und Ergebnisse gemeinsam im Webbrowser angezeigt werden
Emacs Org Mode und literarisches Programmieren
- Emacs Org Mode unterstützt über das Paket
org-babel mehrsprachiges literarisches Programmieren; beliebige Sprachen können ausgeführt und die Ergebnisse im Dokument festgehalten werden
- Dennoch ist dieses Vorgehen ein Nischenmuster, das im Wesentlichen nur von einer kleinen Zahl besonders engagierter Nutzer verwendet wird
- Wenn man in großen Softwareprojekten Org-Dateien als Source of Truth verwendet, wird der eigentliche Quellcode faktisch zu einem kompilierten Ausgabeartefakt, und nach jeder Bearbeitung muss der Code extrahiert („tangle“) und am Zielort abgelegt werden
- Das lässt sich zwar automatisieren, doch wenn Nutzer oder Agenten den eigentlichen Quellcode direkt bearbeiten, tritt beim nächsten Tangle-Vorgang leicht das Problem auf, dass Änderungen überschrieben werden
Nutzungsmuster vor den Agenten
- Der Einsatz von literarischem Programmieren zur Verwaltung persönlicher Konfigurationen war erfolgreich genug, dass die Idee schon vor dem Aufkommen von LLMs nicht aufgegeben wurde
- Ein Nutzungsmuster mit Org Mode für manuelle Tests und Notizen: Statt die Kommandozeile zu verwenden, werden Befehle im Editor geschrieben und ausgeführt, schrittweise überarbeitet, bis jeder Schritt korrekt ist, und die Ergebnisse direkt an Ort und Stelle gespeichert
- „Wenn man das Schreiben von Notizen und das Ausführen von Tests kombiniert, entstehen die Notizen nach Abschluss der Tests kostenlos mit.“
Ein neuer Workflow mit Agenten
- Coding-Agenten wie Claude und Kimi verstehen die Syntax von Org Mode gut, und da Org eine tolerante Markup-Sprache ist, kommen LLMs sehr gut damit zurecht
- Die umfangreiche Syntax von Org Mode ist für Menschen eher ein Nachteil, für Sprachmodelle jedoch kein Problem
- Wenn man einen Agenten bei Funktionstests darum bittet, ein Org-Runbook zu schreiben, dann gilt:
- Die Beschreibung enthält die Reflexion des Modells über die Absicht jedes einzelnen Schritts
- Codeblöcke können nach Prüfung einzeln oder als ganzes Skript interaktiv ausgeführt werden
- Ergebnisse werden wie in einem Jupyter-Notebook unter dem Code gespeichert
- Man kann die Beschreibung bearbeiten und das Modell um eine Aktualisierung des Codes bitten, oder den Code bearbeiten und das Modell die geänderte Bedeutung in die Beschreibung übernehmen lassen, oder der Agent ändert beides gleichzeitig
- Das Problem der Pflege paralleler Erzählungen verschwindet
Die Kernarbeit, die Agenten eliminieren
- Wenn man dem Agenten das Tangling überlässt, verschwindet auch das Problem der Codeextraktion
- Über eine Datei
AGENTS.md kann man dem Agenten anweisen, Org-Mode-Dateien als Source of Truth zu behandeln, immer Erklärungen zu schreiben und vor der Ausführung zu tangeln
- Agenten beherrschen all diese Aufgaben gut und werden es nie leid, nach einer Codeänderung auch die Erklärung neu zu schreiben
- Agenten beseitigen den grundlegenden Zusatzaufwand, der literarisches Programmieren bislang an einer breiten Nutzung gehindert hat, und nutzen damit genau jene Fähigkeiten zur Übersetzung und Zusammenfassung, in denen LLMs besonders stark sind
Erwartete Vorteile
- Eine Codebasis lässt sich in verschiedene Formate exportieren, um sie bequemer lesen zu können
- Das ist besonders wichtig, wenn sich die Hauptrolle von Engineers vom Schreiben zum Lesen verlagert
- Zwar gibt es dafür keine Datengrundlage, doch weil die Erzählung, die die Absicht jedes Codeblocks erklärt, gemeinsam mit dem Code im Kontext erscheint, lässt sich vermuten, dass sich auch die Qualität des erzeugten Codes verbessern könnte
- Bisher wurde das noch nicht an großen, produktionsreifen Codebasen ausprobiert; genutzt wird es derzeit für Tests und Workflows zur Dokumentation manueller Prozesse
Grenzen von Org Mode und Alternativen
- Das Org-Format ist eng mit Emacs integriert, was ein einschränkender Faktor ist; die Überzeugung, dass Org Emacs verlassen sollte, besteht schon lange
- Man würde gern Markdown als Alternative empfehlen, aber Markdown bietet zu wenig Unterstützung für eingebettete Metadaten
- Das Properties-Konzept von Org Mode erlaubt es, Dokumente programmatisch mit Emacs Lisp zu manipulieren, und inzwischen kann ein LLM maßgeschneiderte Funktionen nur für dieses Dokument als Emacs Lisp im Abschnitt für file variables schreiben
- Markdown bietet keine Entsprechung zu den header arguments von Org Mode, mit denen sich Ausführungsdetails von Codeblöcken festlegen lassen, etwa wo sie ausgeführt werden oder auf welcher Remote-Maschine
- Spannend ist nicht die konkrete Implementierung in Emacs, sondern die Idee selbst
Die zentrale Frage
- „Kann es durch Agenten praktikabel werden, eine große Codebasis zu haben, die sich wie eine Erzählung lesen lässt und bei der eine unermüdliche Maschine den Gleichlauf von Codeänderungen und Erklärungen aufrechterhält?“
2 Kommentare
Hacker-News-Kommentare
Ich denke, der einfachste Weg ist, das LLM seine eigenen Kommentare direkt hinterlassen zu lassen
So greift das LLM, wenn es den Code später erneut liest, auf seine eigenen Kommentare zurück, was wie eine Art Just-in-Time-Gedächtnis (just-in-time memory) funktioniert
In
<summary>soll eine Zusammenfassung stehen, in<remarks>die Gründe und der Kontext, in<params>die Einschränkungen; Inline-Kommentare werden minimiertSo kann man beim PR-Review den Gedankengang des LLM direkt in
<remarks>nachvollziehen und leicht erkennen, wo es etwas anders als beabsichtigt verstanden hatAm Ende verschmutzen sie nur den eigenen Kontext mit nutzlosen Informationen und verschlechtern das Verständnis noch weiter
Von menschlicher Literalität (literacy) ist das noch weit entfernt
Aber genau solche Kommentare sind es, an denen das LLM hängenbleibt, wenn es denselben Code erneut liest; insofern könnten sie sogar wertvolle Informationen sein
Solche Kommentare dienen also dazu, diese Erinnerung zu bewahren
Ich denke, Programmiersprachen sind entstanden, weil natürliche Sprache wegen ihrer Mehrdeutigkeit ungeeignet war
Deshalb werden Code-Kommentare letztlich ebenfalls mehrdeutig, und weil sie nicht ausgeführt werden, veralten sie schnell
LLMs sind stark beim Übersetzen von Code, aber das Umwandeln von Prompts in natürlicher Sprache in Code fühlt sich weiterhin schwierig an
Guter Code sollte seine Absicht klar ausdrücken, und viele Kommentare könnten ein Signal für schlechte Codequalität sein
Aber gute Software sollte auch gute Dokumentation enthalten
Literate Programming ist eher erklärendes Schreiben als eine Darstellung von Implementierungsdetails
Im Code wird das „Wie“ eng definiert, während natürliche Sprache stärker das „Was“ ausdrücken kann, sodass das LLM Spielraum hat, bessere Wege vorzuschlagen
Es braucht redundante Informationen, damit Fehler erkannt und korrigiert werden können
Sie legen nur Regeln fest, die den Interpretationsspielraum einschränken
Manchmal sind Metaphern oder Mehrdeutigkeit sogar die passendere Ausdrucksform
Wenn man Beispielcode und Dokumentation als Vorlage gibt, nimmt die Halluzination (hallucination) ab
Es gibt Forschung dazu, dass Kommentare im Stil von Literate Programming Menschen beim Verstehen von Code helfen
Forschende bei Google haben getestet, ob LLMs solche Kommentare aktualisieren können und ob das Menschen beim Verständnis hilft
Das Ergebnis: Block-Kommentare auf Ebene der Absichtserklärung sind am wirksamsten
(Siehe: arXiv-Paper von 2024 "Natural Language Outlines for Code")
Ein interessantes jüngeres Phänomen ist, dass Menschen früher nur ungern README-Dateien oder Architektur-Dokumente für andere Menschen geschrieben haben
Aber wenn man sagt, dass sie nun für LLMs geschrieben werden, sind die Leute viel engagierter
LLMs konsultieren Dokumentation jedoch bei jeder Aufgabe, daher ist die Motivation zur Dokumentation viel stärker
Commit-Messages und Aufzeichnungen wie ADRs schaut sich kaum ein Mensch an, aber LLMs lesen sie alle
Am Ende helfen solche Gewohnheiten damit auch neuen Mitarbeitenden
Denn damit Code funktioniert, muss die Dokumentation nicht korrekt sein
Deshalb fühlt es sich oft besser an, direkt in den Code zu schauen als in die Dokumentation
Ich denke, eine Kombination aus leichtgewichtigem Literate Programming und konventionsgetriebenen Sprachen passt gut ins Zeitalter der Agenten
Sprachen wie Go mit schneller Kompilierung und klaren Styleguides sind gut geeignet
Wenn man Agenten beim Schreiben von Code den Google Go Style Guide referenzieren lässt, kommen ziemlich gute Ergebnisse heraus
(Siehe: Anekdote zu Rob Pike)
LLMs sind Sprachmodelle, daher lohnt es sich, in klares Schreiben zu investieren
Auch wenn es nicht gleich Literate Programming sein muss, sind gute Namen, Docstrings, Typsignaturen und Kommentare, die das „Warum“ erklären, wichtig
Im Kern geht es darum, Kommunikationsmuster für Menschen und LLMs gleichermaßen zu schaffen
Besonders wichtig sind Dokumente, die die übergeordnete Struktur auf Datei-, Verzeichnis- und Projektebene erklären
Solche Konzepte spannen sich jedoch oft über mehrere Dateien, daher bleibt immer die Frage, wo man sie hinschreibt und wie man Dokumentation und Code synchron hält
Ich habe in den letzten zehn Jahren fast jeden Code im Stil von Literate Programming geschrieben
Ich habe nbdev gebaut, um Code, Dokumentation und Tests gemeinsam notebookbasiert zu verwalten
In letzter Zeit habe ich ein Tool namens Solveit gebaut, das LLMs integriert und nun im ganzen Unternehmen genutzt wird
(Solveit-Link)
Literate Programming ist auch für Aufgaben außerhalb des Programmierens nützlich
Eine kurze Demo oder Screenshots wären hilfreich
Die Idee, mit LLMs Widersprüche zwischen Kommentaren und Code automatisch zu erkennen, ist interessant
Dokumentation driftet mit der Zeit zwangsläufig vom Code weg; wenn man das automatisch erkennen könnte, hätte das großen Wert
Man könnte daraus sogar ein Startup machen
Änderungen beginnen mit einem Dokumentations-PR, und Entwickler setzen sie dann im Code um
Beim Review werden Dokumentation und Code nebeneinander angezeigt, damit sie gemeinsam geprüft werden können
Über Links zwischen Dokumenten soll außerdem Kontextnavigation möglich sein
Zum Beispiel: GitHub gh-aw, Continue.dev
Die Paarstruktur aus Testcode und Produktionscode ist wie die doppelte Buchführung in der Rechnungslegung nützlich
Tests erklären die Absicht des Codes, und der Code ergänzt die Bedeutung der Tests
Wenn beim Review eine Seite unklar ist, schaut man auf die andere
Der Nachteil ist die größere Code-Menge, aber die bessere Lesbarkeit ist diesen Preis wert
Ich habe kürzlich ebenfalls über intentionsbasiertes Coding geschrieben, und das berührt sich mit dieser Diskussion
(Blog-Link)
Wichtig ist, dass sich eine Codebasis in verschiedene Formate umwandeln lässt, damit sie leichter lesbar wird
In Zukunft werden auch Menschen ohne Informatikhintergrund näher an Code heranrücken, und die Einbindung natürlicher Sprache wird ihrer Produktivität und ihrem Lernen sehr helfen
Wikipedia – Literarisches Programmieren
> Literarisches Programmieren (literate programming) ist eine Programmiermethodik, bei der der Schwerpunkt beim Programmieren nicht darauf liegt, für den Computer kompilierbaren Code zu erzeugen, sondern Code zu schreiben, den Menschen leicht verstehen können. Anders gesagt ist das Ziel, so zu programmieren, als würde man ein Dokument verfassen, damit Menschen den Code lesen und verstehen können. Da das Ziel darin besteht, „Programmierung so lesbar zu machen, als würde man ein literarisches Werk lesen“, erhielt sie den Namen „literarisches Programmieren“.