- Die Sichtweise, die die Schwierigkeit des Programmierens den formalen Symbolen zuschreibt, führt zu der falschen Erwartung, dass die Last für den Menschen sinke, wenn Maschinen natürliche Sprache verstünden
- Die Gefahren früher Maschinensprache wurden durch höhere Programmiersprachen teilweise gemildert, doch es blieben im Kern präzise Anweisungen erforderlich; nur falsche Antworten wurden zu Fehlermeldungen
- Natürliche Sprachschnittstellen sind keine Lösung zur Arbeitsteilung, sondern können durch steigende Kooperations- und Kommunikationskosten zwischen Mensch und Maschine die Last auf beiden Seiten erhöhen
- Die Entwicklung der Mathematik zeigt, dass von Persönlichkeiten wie Vieta, Descartes, Leibniz und Boole geschaffene formale Symbolsysteme ein zentrales Werkzeug zum Umgang mit komplexem Denken waren
- Hätte Natural Language Programming von Anfang an die grundlegende Ein-/Ausgabe gebildet, wäre die Informatik am Ende womöglich nur ein langer Umweg zurück zu nutzbaren formalen Systemen gewesen
Erwartungen und Irrtümer rund um Natural Language Programming
- Seit den Anfängen des automatischen Rechnens sahen manche Menschen darin einen Mangel, dass Programmieren die für formale Symbole nötige Sorgfalt und Genauigkeit verlangt
- Dass Maschinen auch fehlerhafte Befehle strikt ausführen, wurde als Problem betrachtet, und man erwartete „vernünftigere“ Maschinen, die kleine bürokratische Fehler zurückweisen würden
- Maschinensprache war wegen ihrer fast fehlenden Redundanz eine gefährliche Schnittstelle zwischen Mensch und Maschine
- Als Reaktion darauf wurden höhere Programmiersprachen entwickelt
- Mit der Zeit führte dies zu Verbesserungen, bei denen viele kleine Fehler statt zu falschen Ergebnissen nur noch zu Fehlermeldungen führten
- Doch die abstrakte Maschine hinter der Programmiersprache bleibt ein Automat, der gegebene Befehle treu ausführt und auch sinnlose Anweisungen verarbeiten kann
- Der Vorschlag, Maschinen in natürlicher Sprache anzuweisen, stützt sich auf die Logik, dass die Last für den Menschen sinken könne, selbst wenn die Maschine dadurch komplexer werde
- Plausibel wirkt diese Logik nur, wenn man die „Pflicht zur Verwendung formaler Symbole“ als Ursache der Schwierigkeit ansieht
- Eine Änderung der Schnittstelle verteilt Arbeit nicht einfach neu, sondern fügt Kooperations- und Kommunikationskosten über die Schnittstelle hinweg hinzu
- Erfahrungsgemäß kann eine Änderung der Schnittstelle das Arbeitsvolumen auf beiden Seiten stark erhöhen, weshalb die Vorliebe für eine „schmale Schnittstelle“ wächst
Wie formale Symbole das Denken erweitern
- In der Geschichte der Mathematik haben natürliche, sprachliche oder bildzentrierte Ansätze immer wieder ihre Grenzen gezeigt
- Die griechische Mathematik blieb bei sprachlichen und zeichnerischen Aktivitäten stehen und stagnierte
- Die moslemische „algebra“ versuchte kurz den Einsatz von Symbolen, kehrte dann aber zu einer rhetorischen Form zurück und verschwand
- Westeuropa löste sich dank der bewusst entworfenen formalen Symbole von Vieta, Descartes, Leibniz und später Boole aus den sprachlichen Präzisionsversuchen der mittelalterlichen Scholastik
- Der Vorteil formaler Texte liegt darin, dass zulässige Manipulationen nur einige wenige einfache Regeln erfüllen müssen
- Diese Regelhaftigkeit wird zu einem Mittel, viele Arten von Sinnlosigkeit auszuschließen, die sich in natürlicher Sprache kaum vermeiden lassen
- Die Verwendung formaler Symbole ist keine Last, sondern eher ein Privileg
- Dank formaler Symbole können heute auch Studierende Dinge lernen, die früher nur Genies möglich waren
- Der Satz aus dem Vorwort eines technischen Berichts von 1977, man habe „der Klarheit halber sogar die Standardsymbole der logischen Konnektoren vermieden“, zeigt, dass dieses Missverständnis nicht auf eine einzelne Person beschränkt war
- Die „Natürlichkeit“ natürlicher Sprache führt dazu, dass sich Sätze leicht bilden lassen, deren Sinnlosigkeit nicht offensichtlich ist
Informatik in einer Welt, in der nur natürliche Sprache erlaubt ist
- Wenn Ein- und Ausgabe von Informationsverarbeitungsgeräten von Anfang an nur in der Muttersprache möglich gewesen wären, dann wäre die Informatik wohl eher eine „black art“ gewesen, die sich mühsam in Richtung hinreichend definierter formaler Systeme bewegt
- Um die Schnittstelle auf ein brauchbares Maß zu verengen, wäre die Intelligenz der ganzen Welt nötig gewesen
- Mit Blick auf die Menschheitsgeschichte hätte das womöglich noch einmal Jahrtausende gedauert
- Hinzu kommt die Sorge, dass sich mit der westlichen Bildungsentwicklung weg von intellektuellem Training die Fähigkeit der Menschen, ihre eigene Sprache zu beherrschen, stark verschlechtert hat
- Als Beispiele werden wissenschaftliche Aufsätze, technische Berichte und staatliche Veröffentlichungen genannt, in denen sich bei genauer Lektüre viel Sinnloses findet
- Dieses Phänomen wird „The New Illiteracy“ genannt und dient auch jenen als Warnung, die Natural Language Programming unterstützen, ohne die technischen Einsichten zu besitzen, sein Scheitern vorherzusehen
- Abschließend steht der Zweifel, dass eine in natürlicher Sprache programmierte Maschine — ob auf Dutch, English, American, French, German oder Swahili — ebenso schwer zu benutzen wie zu bauen wäre
1 Kommentare
Hacker-News-Kommentare
Es ist gut, hier LLMs zu verteidigen, aber ich frage mich, wie es umgekehrt wäre. Man nimmt ein Projekt mittlerer Komplexität und lässt den Code vom bevorzugten LLM wieder in natürliche Sprache zurückverwandeln.
Würde es das im Quellcode enthaltene Verhalten und die Anforderungen vernünftig erklären, ohne so viele Details zu verlieren, dass man das Programm nicht mehr reproduzieren kann? Wäre diese Beschreibung in natürlicher Sprache leichter zu durchdenken?
Ich denke, es hat einen Grund, warum die Vibe-Coding-Apps, die Leute zeigen, meist simpel sind. Es gibt ein Maß an Komplexität und Präzision, das schwer zu beherrschen ist; selbst wenn man es in einfachem Englisch definieren kann, ist fraglich, ob diese Beschreibung aussagekräftiger ist als eine skalierbare, verständliche und präzise Sprache.
Ich glaube, dass juristische Dokumente nicht in einfachem Englisch verfasst sind, liegt an mehr als nur daran, künstliche Einstiegshürden zu schaffen.
METAR YSSY 031000Z 08005KT CAVOK 22/13 Q1012 RMK RF00.0/000.0Neue Pilotinnen und Piloten fragen fast ausnahmslos: „Warum schreibt man das nicht einfach in Worten?“, und tatsächlich wandeln die meisten Flugplanungs-Apps diesen Code in Prosa um.
Professionelle Pilotinnen und Piloten oder Fluglotsen bevorzugen das Codeformat aber deutlich. Es ist eine einzige Zeile und daher kompakt, das Format ist klar definiert, sodass man genau weiß, wo die benötigten Angaben zu finden sind, und es ist eindeutig und klar.
Bei Mathematik und Coding ist es ähnlich: Hat man ein bestimmtes Kompetenzniveau erreicht, verursachen Komplexität und Redundanz natürlicher Sprache mehr Kosten als Nutzen. Das scheint für alle Fachgebiete zu gelten.
Informationen aus Prosa wieder abzurufen kostet viel Zeit, und Menschen, die lange Texte lesen, fangen an, zu unterstreichen, Notizen zu machen und ihre eigenen Kurzformen zu entwickeln.
Komprimierte Formate und Abstraktionen reduzieren die Belastung durch Arbeitsgedächtnis und Informationssuche. Deshalb muss es nicht zwingend nur um die Präzision der Sprache gehen.
Man könnte meinen, dass von diesem Satz bis zu einer tatsächlich funktionierenden App unzählige Implementierungsdetails nötig sind, aber schon mit dieser Menge an Information besteht die Chance, zu einer funktionierenden Anwendung zu gelangen, die mein Bedürfnis erfüllt.
Und wenn man damit genug bauen kann, werden auch Wünsche wie „Kannst du das in Kornblumenblau ändern?“ einfach, und der Nutzer kann von dort aus iterativ verbessern.
Wenn man einem LLM nur eine ISA und einen Display-Treiber gibt und es bittet, eine Grafik-App in Assembly zu bauen, bekommt man gar nichts heraus.
Wenn aber ein Berg von Abstraktionen vorhanden ist, wird es wahrscheinlich möglich.
Ich will LLMs nicht verteidigen; ich meine nur, dass man dem Ziel viel näher kommt, wenn man die richtigen Abstraktionen und wiederverwendbare Komponenten bereitstellt.
Mir fällt ein altes Zitat von Hal Abelson ein:
„Unter unserem Zugang zu diesem Thema liegt die Überzeugung, dass ‚Computer Science‘ keine Wissenschaft ist und dass ihre Bedeutung nur wenig mit Computern zu tun hat. Die Computerrevolution ist eine Revolution in der Art, wie wir denken und wie wir Gedanken ausdrücken. Das Wesen dieses Wandels lässt sich am besten als das Aufkommen einer prozeduralen Epistemologie bezeichnen. Sie untersucht die Struktur von Wissen aus einer imperativen Perspektive, im Gegensatz zur stärker deklarativen Perspektive der klassischen Mathematik. Die Mathematik liefert einen Rahmen, um den Begriff ‚was ist‘ präzise zu behandeln. Berechnung liefert einen Rahmen, um den Begriff ‚wie man es macht‘ präzise zu behandeln.“
Egal wie viele beeindruckende Demos und Erklärungen à la „KI hat Coding getötet“ es gibt: Ein Großteil der tatsächlichen Arbeit verschiebt sich zu Vorverarbeitung, Nachverarbeitung und Evaluation rund um die KI.
Das ist gut, weil es Programmieren zugänglicher macht, aber es kann Programmieren nicht wirklich ersetzen.
Endlich hat es jemand so ausgedrückt. Natürliche Sprache hat inhärente Grenzen, die aus den mentalen Grenzen des Menschen stammen. Der menschliche Geist denkt manchmal zu abstrakt oder zu konkret und übersieht wichtige Details oder Verallgemeinerungen.
Aus meiner eigenen Erfahrung als Programmierer werden Probleme einer Aufgabe, oder sogar ihre Absurditäten, oft erst sichtbar, wenn man beginnt, den Code als Code umzusetzen, also in einem strengen Symbolsystem.
Außerdem dauert es oft länger, etwas in natürlicher Sprache exakt zu beschreiben, als einfach den Algorithmus als Code zu schreiben.
Wie oft schreiben wir Sätze um, sagen „Eigentlich meinte ich ...“ oder formulieren eine E-Mail vor dem Absenden noch einmal neu? Wir sind Menschen, und beim ersten Versuch ist es selten perfekt.
Jetzt verwandeln wir diese unvollkommene Kommunikationsform, natürliche Sprache, in Code: die Sprache von Maschinen, die notorisch dafür sind, genau das auszuführen, was gesagt wurde, nicht das, was beabsichtigt war.
Natural Language Processing ist enorm nützlich, um beim Schreiben von Apps oder Skripten in die richtige Richtung zu starten. Am Ende kann aber trotzdem an vielen Stellen Refactoring nötig sein.
Man muss kein Code-Guru sein, um aus LLMs Wert zu ziehen, aber Programmierkenntnisse helfen weiterhin und sind manchmal notwendig.
/s: Weil wir noch nicht weit genug gegangen sind. Menschen erzeugen Computerprogramme in natürlicher Sprache, aber stattdessen sollten sie Prompts direkt ausführen
„Du bist ein Grafiksystem. Du verwaltest, was auf dem Bildschirm zu sehen ist. Du kannst von allen Programmen Anfragen erhalten, ‚Fenster‘ zu erstellen und zu entfernen, und auch weitere Anfragen, in zuvor erstellten Fenstern Text, Linien, Kreise usw. zu zeichnen. Elemente können jede beliebige Farbe haben.
Außerdem musst du der Seite, die das Fenster erstellt hat, auf das der Nutzer mit der Maus geklickt hat, weitere Klickinformationen senden.
Der Fenstermanager ist ein besonderes Programm und kann dir mitteilen, welche Fenster wo auf allen an das System angeschlossenen Monitoren angezeigt werden.“
Und „Du bist ein Tic-Tac-Toe-Programm. Es gibt ein Grafiksystem, das verwaltet, was auf dem Bildschirm zu sehen ist. Du kannst diesem System befehlen, ‚Fenster‘ zu erstellen und zu entfernen, und in zuvor erstellten Fenstern Text, Linien, Kreise usw. zu zeichnen. Elemente können jede beliebige Farbe haben.
Die Grafiken, die du zeichnest, sollen ein Tic-Tac-Toe-Spiel zeigen, bei dem der Nutzer per Mausklick seine Züge macht. Wenn der Nutzer gewinnt …
Füge dem Spiel Werbung hinzu, sofern der Nutzer kein Pay-per-Click-Abonnement hat.“
Das sollte reichen, damit das Spiel läuft
Zum Speichern braucht es noch einen weiteren Prompt. „Du bist ein Dateisystem. Du persistierst Daten auf der Festplatte …“
Und „Du bist ein Multitasking-Betriebssystem. Du vermittelst mehreren LLMs den Eindruck, vollständige Kontrolle über CPU und Speicher des Systems zu haben. Du …“ braucht man ebenfalls
Ich freue mich darauf, das nächstes Jahr Anfang April zu sehen
„Maschinensprache ist von nahezu jeder Form von Redundanz frei und wurde daher bald als unnötig gefährliche Schnittstelle zwischen Mensch und Maschine erkannt. Als teilweise Reaktion auf diese Erkenntnis wurden sogenannte ‚höhere Programmiersprachen‘ entwickelt, und mit der Zeit lernten wir, den Schutz vor törichten Fehlern in gewissem Maß zu verstärken. Dass viele törichte Fehler nun zu Fehlermeldungen statt zu falschen Antworten führen, war eine wichtige Verbesserung.“
Ich habe das Gefühl, dass wir uns kollektiv zu schnell in die LLM-Programmierung gestürzt haben. Mir gefiel wirklich, wie sich Rust dahin entwickelt hat, törichte Fehler aufzuzeigen und viel klarer zu machen, wie man sie behebt
Als Entwickler habe ich weiterhin den Kontext und das Verständnis des Codes, an dem ich arbeite, und der Compiler weist mich auf offensichtliche Fehler und Korrekturen hin. Die Nutzung von LLMs fühlt sich dagegen wie ein halbintelligentes Ratespiel an
Der Rust-Compiler ist ein Meister, der seinen Schüler unterrichtet, während ein LLM wie ein selbstbewusster Absolvent wirkt, der den Meister korrigiert. Ich bevorzuge den Rust-Ansatz deutlich und würde mir wünschen, dass er sich, wenn möglich, weiterentwickelt
Natürliche Sprache ist ein schlechtes Medium, um Regeln und Befehle zu übermitteln. Die aktuelle Lage in den USA ist ein gutes Beispiel
Wir streiten immer noch darüber, was bestimmte Gesetze und Verfassungszusätze bedeuten. Die Bedeutung von Wörtern verändert sich mit der Zeit, und historischer Kontext geht verloren
Es wäre schön, Maschinen in natürlicher Sprache bedienen zu können, aber aus der Perspektive von jemandem, der seit Mitte der 80er programmiert, schafft die Starrheit von Computersprachen von BASIC bis Go ein gutes Gleichgewicht. Sie legt der befehlenden Seite genug Verantwortung auf, genau auszudrücken, was die Maschine tun soll
Ich stimme dieser Behauptung nur bedingt zu. In realen Unternehmen beginnen Ideen für neue Funktionen oft im Kopf irgendeiner Person aus dem Business. Diese Person wird keine formale Sprache sprechen
Daher ist, wie man es auch betrachtet, für die Implementierung einer Funktion eine Übersetzung von natürlicher Sprache in Maschinensprache nötig
Üblicherweise übernehmen Business-Analysten und Programmierer den ersten Schritt, die Übersetzung von natürlicher Sprache in eine formale Sprache. Warum sollte man sich dabei nicht vom Computer helfen lassen?
Deshalb wendet er sich nicht nur gegen die Idee, Programme in natürlicher Sprache zu spezifizieren, sondern auch gegen die Vorstellung, dass unsere Fähigkeit zum Bau komplexer Systeme wächst, wenn man die Notwendigkeit beseitigt, formale Sprachen zu verstehen
Vieles an „Übersetzung“ ist in Wahrheit keine Übersetzung, sondern das Beheben von logischer Mehrdeutigkeit, Inkonsistenzen und falschen Annahmen. Wenn man Dijkstra ernst nimmt, ist vieles davon auch innerhalb natürlicher Sprache möglich. Denn dort sitzen Programmierer, die ihr Leben lang formalisiert haben
Es gibt auch andere Berufe, die erhebliches formales Denken erfordern, wie die Mathematik. Außerdem wurden beim Überführen alter Beweise in Computerbeweise in vielen weithin akzeptierten Beweisen Löcher und Lücken entdeckt
Vieles wurde nicht auf den Kopf gestellt, aber wir haben noch immer keinen vollständigen Beweis für Fermats letzten Satz https://xenaproject.wordpress.com/2024/12/11/fermats-last-th...
Wenn man nicht innerhalb eines formalen Systems denkt, werden die Ideen schlechter. Denn man behandelt seine eigenen Gedanken nicht als etwas Formales
Zur Frage, wie man die Idee der „Business-Person“ aus dem Beispiel übersetzt, hätte er vermutlich wenig zu sagen. Aus seiner Sicht ist die Idee der Business-Person bereits flach und schlecht, weil sie keinem Formalismus folgt, und daher nicht übersetzenswert
Wenn man „den Computer zwischendurch helfen lässt“, stößt man sehr schnell auf das Problem, dass immer formalere natürliche Sprache nötig wird, um ausreichend gute Ergebnisse aus der Maschine zu bekommen
Auch wenn sie nicht so formalisiert ist wie eine Programmiersprache, existiert sie eindeutig
Sobald man versucht, irgendeinen Prozess zu definieren, neigt man am Ende zur Formalisierung, auch wenn man sich dessen selbst nicht bewusst ist
„Dass viele dumme Fehler statt zu falschen Antworten zu Fehlermeldungen führten, war eine wichtige Verbesserung. Nicht einmal diese Verbesserung gefiel allen. Manche empfanden Fehlermeldungen, die man nicht ignorieren konnte, als ärgerlicher als falsche Ergebnisse, und bei der Beurteilung der relativen Vorzüge von Programmiersprachen scheinen einige bis heute ‚Leichtigkeit des Programmierens‘ mit der Leichtigkeit gleichzusetzen, unentdeckte Fehler zu machen.“
Wenn man nicht wüsste, wer das geschrieben hat, würde es wirken wie ein direkter Seitenhieb auf Leute, die Rust hassen
Nachdem ich eine Weile Scala benutzt hatte, eine Sprache, in der sich stärkere Invarianten über Typen ausdrücken lassen als in Rust, sehe ich diese Eigenschaft nicht mehr in jeder Situation als klaren Sieg. Ich denke nicht mehr: „stärkere Typen == automatisch besser“
„Keine Fehler zulassen“ hat seinen Preis. Wenn ein Typsystem wirklich strikt ist, wird exploratives Arbeiten ziemlich schwierig. Schnelle Iterationen können unmöglich werden
Wegen einer kleinen Änderung muss man unter Umständen die Hälfte des Programms neu entwerfen, nur um das Typsystem wieder zufriedenzustellen
Das ist ein Trade-off. Wie alles andere auch. Gut für ein robustes Endprodukt, aber hinderlich für schnelle Experimente
Jemand hat dieses Problem im Kontext von Rust und Spieleentwicklung gut erklärt: https://loglog.games/blog/leaving-rust-gamedev/
Es ist aber kein Problem, das nur Rust oder Spieleentwicklung betrifft
Manche Arten von Dummheit scheinen zeitlos zu sein
Wovon er hier spricht, sind interpretierte Sprachen
Außerdem gehört er zu jenen Mathematikern, die man heute Informatiker nennt; seine „Algorithmen“ sind im Grunde nur neu formulierte Mathematik und benötigen keine Geräte. Er ist jemand, der der peinlichen Tätigkeit, echte Computer zu programmieren, vom Naturell her feindlich gegenübersteht
Eine Anwendung in natürlicher Sprache zu spezifizieren und zu bauen, ist ziemlich ähnlich dazu, vor dem Start eines Spielprototyps ein Game Design Document zu haben
Sobald man aber den Großteil dessen umgesetzt hat, was man wollte, wird die Implementierung zum Maßstab, und das GDD wird meist weggeworfen, weil es nicht mehr zum tatsächlichen Spiel passt
Darauf zu bestehen, bei jeder Änderung das GDD zu lesen, das Feature zu implementieren und danach das GDD wieder zu synchronisieren, ist umständlich und funktioniert in der Praxis nicht gut. Ich habe noch nie gesehen, dass das wirklich passiert
Wenn KI/LLMs eines Tages nur anhand einer Reihe von Prompts die nächste Version von Linux oder Windows von Grund auf codieren können, ändern sich alle Voraussetzungen; derzeit sind wir eindeutig noch nicht so weit, und ob wir je dorthin kommen, ist offen
Natürliche Sprache eignet sich ziemlich gut, um technische Anforderungen komplexer Systeme zu beschreiben. Also nicht die aktuelle Code-Implementierung selbst, sondern warum die aktuelle Implementierung gegenüber anderen möglichen Implementierungen gewählt wurde
Sie eignet sich dafür festzuhalten, was Code tun soll, nicht was er tut – also für die fehlenden Teile, die eher an Orten wie Jira stehen als im Repository
Außerdem könnte sie bessere Refactoring-Fähigkeiten bieten, wenn das gesamte System durch externe Regeln beschrieben wird und diese Regeln über die gesamte Codebase hinweg erzwungen werden können
Wir haben Programmiersprachen verwendet, weil sie im Kontext von Automatisierung und Computern leicht zu nutzen sind, und ehrlich gesagt war das vor LLMs auch die einzige Möglichkeit
Programmiersprachen bieten auf lokaler Ebene Eindeutigkeit, aber sobald jemand einen Teil des Codes kopiert und einfügt, hört das auf globaler Ebene auf zu funktionieren
Kann man sicher sein, dass dieser Teil ein korrektes Programm ist und alle übergeordneten Constraints einhält, denen er folgen muss? Wenn es kompiliert, ist es zwar ein ausführbares Programm, aber die Definition von Ausführung ist ziemlich locker. In C++ kann auch ein Programm laufen, das den gesamten Speicher ruiniert