1 Punkte von GN⁺ 4 시간 전 | 1 Kommentare | Auf WhatsApp teilen
  • Außerhalb des Coding-Agenten entwickelt sich die Harness-Level-Schleife, bei der Arbeits-Queues und ein Harness die Iteration steuern, zu einem neuen zentralen Muster des Agent Engineering
  • Je länger ein Modell autonom läuft, desto leichter fügt es statt starker Invarianten lokale Abwehrmechanismen und Fallbacks hinzu, wodurch bei langfristig gewartetem Code Designverständnis und Kontrolle ins Wanken geraten können
  • Umgekehrt funktionieren mechanische Iterationen bereits sehr gut in Bereichen, in denen Ergebnisse leicht verifiziert oder verworfen werden können, etwa beim Code-Porting, bei Performance-Experimenten, Security-Scans oder Forschung
  • Wenn Angreifer und Reporter Schleifen laufen lassen, geraten Maintainer unter Druck, ebenfalls Maschinen für Triage, Reproduktion und Reaktion einzusetzen; der Fall curl zeigt die Belastung durch AI-generierte Reports
  • Die künftige Aufgabe ist nicht, ob Schleifen eingesetzt werden, sondern wie sich darin menschliches Urteilsvermögen, Engineering-Regeln, verantwortliche Aufsicht und verständliche Architekturen erhalten lassen

Schleifen außerhalb des Coding-Agenten

  • Innerhalb eines Coding-Agenten gibt es bereits eine Agenten-Schleife, in der das Modell Tools aufruft, Ergebnisse einarbeitet, Dateien liest und verändert, Tests ausführt und dann antwortet
  • Das neu stärker hervortretende Muster ist die Harness-Level-Schleife außerhalb davon
    • Eine Aufgabe landet in der Queue
    • Die Maschine nimmt die Aufgabe auf und versucht sie
    • Nach einem Stopp entscheidet das Harness, ob die Aufgabe wirklich beendet ist
    • Wenn nicht, injiziert es Nachrichten in dieselbe Sitzung, startet mit verändertem Kontext eine neue Sitzung oder gibt die Aufgabe an eine andere Maschine weiter
  • Diese äußere Schleife hält eine Aufgabe auch über den Punkt hinaus am Leben, an dem das Modell normalerweise sagen würde: „fertig“
  • Die Schleife selbst ist nicht neu, taucht aber in letzter Zeit in Agent Engineering und im Diskurs auf Twitter deutlich häufiger auf
  • Auch auf Pi zeigt sich ein Teil dieses Ablaufs, und weil Pi ein Harness ist, steht es im Zentrum solcher Experimente

Das Unbehagen bei langlebigem Code

  • Für Code, der einem wirklich wichtig ist, passt dieser Ansatz noch nicht gut
  • Im Kern geht es um Geschmack und Kontrolle
    • Man möchte den Code verstehen, den man ausliefert
    • Unter Druck oder in Diskussionen mit anderen sollte man erklären können, wie ein System funktioniert, ohne zuerst die Maschine um eine Erklärung zu bitten
    • Derzeit ist Codeverständnis weiterhin wichtig
  • Bei freihändig erzeugtem Code, besonders aus Schleifen, treten wiederkehrende Probleme auf
    • zu defensiv
    • zu komplex
    • bleibt bei lokalem Schlussfolgern
    • vermeidet starke Invarianten
    • fügt Fallbacks hinzu, statt falsche Zustände unmöglich zu machen
    • erzeugt duplizierten Code und schlechte Abstraktionen und verdeckt unklare Designs mit noch mehr Mechanismen
  • Kombinationen wie Claude Code und Fable können über 30 Minuten ohne Unterbrechung an einem Problem arbeiten, wodurch human in the loop gegenüber früher weiter zurückgeht
  • Die Qualität von Code aus heutigen freihändigen Harness-Ansätzen fühlt sich sogar schlechter an als im letzten Herbst; zumindest aus dieser Perspektive ist kaum Verbesserung zu erkennen

Schleifen verstärken die Gewohnheiten des Modells

  • Modelle neigen dazu, bei lokalem Scheitern lokale Abwehrmechanismen hinzuzufügen
  • Andrej Karpathy sagte einmal, Modelle hätten „tödliche Angst“ vor Exceptions
  • In Systemen mit wichtigen Invarianten, besonders bei persistenten Datenformaten oder zentraler Infrastruktur, ist ein Ansatz nach dem Muster „jeden malformed case behandeln“ möglicherweise nicht die richtige Korrektur
    • Besser ist es, malformed cases gar nicht erst ausdrückbar oder von Anfang an unmöglich schreibbar zu machen
    • LLMs bringen solche Lösungen selbst mit viel manueller Steuerung nur schwer natürlich hervor und versuchen womöglich sogar Fehlerfälle zu behandeln, die bereits unmöglich gemacht wurden
  • Hinter einer Schleife wird dieses Muster verstärkt
    • Jede Iteration fügt eine weitere kleine Abwehr hinzu
    • Das System wirkt robuster, wird aber immer schwerer zu verstehen
    • Je mehr man loslässt, desto stärker wird diese Tendenz
  • Gibt man Junioren solche Tools ohne klare Leitplanken, könnten sie schlechte Praktiken erlernen
    • Fragt man nach dem Warum, können sie ihre Entscheidungen plausibel verteidigen

Bereiche, in denen Schleifen gut passen

  • Das Schleifenmuster funktioniert in manchen Bereichen bereits sehr gut
  • Code-Porting ist ein typisches Beispiel
  • Auch für Performance-Exploration passt es gut
    • Die Maschine probiert Experimente aus
    • führt Benchmarks aus
    • verwirft Fehlschläge
    • und sucht weiter
  • Auch für Security-Scans und fast jede Form von Forschung ist es ein natürlicher Fit
    • Man kann komplexe Problemräume erkunden und sich Ergebnisse berichten lassen
    • Es ist nicht nötig, zwingend langlebigen Code zu committen
  • Gemeinsamer Nenner erfolgreicher Beispiele ist, dass die Artefakte nicht langfristig bestehen müssen oder eher bestehende Software transformieren oder einem Proof of Concept, einer Idee, einer Entdeckung oder einer mechanischen Transformation ähneln
  • Das Harness braucht kein vollständig objektives oder binäres Signal, sondern ein ausreichend nützliches Signal, das die nächste Iteration antreibt
    • Viele erfolgreiche Beispiele nutzen ein anderes LLM als Judge oder Orchestrator
    • Mechanische Übersetzungen lassen sich per binärem Testfall validieren oder von einem LLM bewerten
  • Claude Code wird zunehmend fähig, ganze Experiment-Workflows zu erstellen und auszuführen
    • Auch wenn der generierte Code unordentlich ist, liegt das eher am Modell als an der Urteilsfähigkeit des Harness

Der Wandel, Software eher wie einen Organismus als wie eine Maschine zu behandeln

  • Code, der bestehen bleiben soll, auf dieselbe Weise in Schleifen zu schreiben, fühlt sich noch nicht gut an
  • Das bisherige Ideal lag näher daran, Software als deterministische Maschine zu verstehen
    • Schälte man eine Schicht ab, konnte man tieferes Verständnis gewinnen
    • Eine Maschine, die sich nur nichtdeterministisch beobachten lässt, galt kaum als optimal
    • Architektur sollte sich idealerweise in Richtung größerer Determiniertheit bewegen
    • Gutes Design bedeutete auch, dass neue Engineers sich in komplexen Codebasen zurechtfinden können
  • In gut entworfenen Systemen gab es Engineers, die wussten, wo die Invarianten liegen, welche Teile load-bearing sind und welche Änderungen sicher sind
  • Große Software passt Menschen schon heute nicht mehr vollständig in den Kopf, und verteilte Systeme werden teils eher diagnostiziert wie von Ärzten, die Symptome betrachten, Hypothesen bilden und weitere Tests anordnen
  • LLMs beschleunigen diese Entwicklung weiter
    • In Produktionsproblemen liest die Maschine Logs
    • schlägt root causes vor
    • reicht Patches ein
    • und eine andere Maschine reviewt sie und bringt sie manchmal ohne menschliche Aufsicht nach main
  • Das ist mächtig und attraktiv, aber Menschen verstehen das Gesamtsystem womöglich nicht mehr auf die frühere Weise
    • Sie behandeln, überwachen und stabilisieren es, ohne es notwendigerweise zu verstehen
  • Nicht jeder Code muss menschlich verfasst sein, und auch früher wurde womöglich schlechterer Code geschrieben

Ein Druck, dem man sich kaum vollständig entziehen kann

  • In einer vollständig maschinengetriebenen Zukunft könnte es schwer sein, sich opt out zu leisten
  • Security ist das klarste Beispiel
    • Auch wenn man selbst keine Schleifen zum Bauen von Software nutzt, lassen andere Schleifen auf diese Software los
    • Angreifer lassen Maschinen dauerhaft laufen
    • Und auch Sicherheitsforscher führen automatisierte Arbeit aus
    • Das Ergebnis ist ein Zustrom aus echten Problemen und Rauschen
  • Daniel Stenbergs curl-bezogener Bericht summer of bliss zeigt den Druck, unter dem Maintainer bereits stehen
    • AI scheint in der Kernentwicklung von curl keine große Rolle zu spielen
    • Trotzdem werden die Maintainer von Reports überrollt, von denen die meisten AI-generiert sind
  • Wenn Angreifer und Reporter Schleifen betreiben, müssen Verteidiger nachziehen
    • Nicht unbedingt, um direkt Patches zu schreiben
    • Aber wegen des Drucks bei Triage, Reproduktion und Reaktion könnten sie Maschinen einsetzen müssen
  • Ähnlich wirkt Wettbewerbsdruck
    • Manche Teams können allein durch Geschwindigkeit mehr liefern als andere
    • Kleine Gruppen, die Maschinen gut orchestrieren, können Projekte plötzlich stark beschleunigen
    • Manche Startups können mit 5 Personen leisten, wofür früher 50 nötig waren
    • Jemand könnte Schleifen auf ein Produkt ansetzen mit der Anweisung, es „wie etwas anderes zu bauen“
  • Nicht jede Software ist gleichermaßen betroffen
    • Manche Bereiche bestrafen Schlampigkeit und verlangen Vertrauen und Verantwortung
    • In viel Software sind Geschwindigkeit, schnelle Experimente und breite Abdeckung enorm wichtig

Neue Abhängigkeiten durch Schleifen

  • Werkzeuge, die aus Schleifen entstehen, verursachen nicht nur einmalige Kosten, sondern können dauerhafte kognitive Abhängigkeiten schaffen
  • Frühere Softwareentwicklung hing von teuren Tools wie Compilern ab, doch heutige Werkzeuge ähneln eher Systemen, auf die fortlaufend zugegriffen werden muss
  • Wenn eine Codebasis durch Schleifen erstellt, durch Schleifen reviewed, durch Schleifen gepatcht und durch Schleifen gewartet wird, entstehen Probleme, sobald derselbe Zugang zu solchen Systemen wegfällt
    • Handelsbeschränkungen könnten den Zugang zu den stärksten Modellen kappen
    • Die Kosten könnten untragbar werden
    • Ein Team könnte die letzte Fähigkeit verlieren, den Code ohne Maschinen zu verstehen
  • Es könnten Codebasen entstehen, die nicht nur für Menschen schwer wartbar sind, sondern maschinelle Beteiligung als Teil des Wartungsmodells voraussetzen
  • Ein Teil dieser Veränderung ist bereits sichtbar
    • Mehr Menschen mergen Code, den sie nicht vollständig erklären können
    • Issue-Reports oder Chat-Diskussionen werden mit maschinell geliefertem Kontext angereichert oder umgeschrieben
    • Für Zusammenfassungen und Kontextualisierung verlässt man sich auf Maschinen
    • Menschen unterhalten sich häufiger über den Umweg eines LLM
  • Das ist nicht zwangsläufig falsch, aber es ist eine große Veränderung gegenüber der bisherigen Arbeitsweise

Harnesses und Tools, die als Nächstes gebraucht werden

  • Es reicht nicht, einfach nur mehr Schleifen zu orchestrieren
  • Selbst wenn Änderungen, Orchestrierung und Agenten besser visualisiert werden, kehrt Verständnis nicht automatisch zurück
  • Die nötige Richtung ist eine von zwei
    • Wege, Menschen wieder mit Nachdruck in die Schleife zu holen und Änderungen aus Schleifen langfristig lesbar zu machen
    • oder Wege, immer komplexere Systeme besser zusammenzusetzen
  • Auch der Blick auf Pi verändert sich
    • Pi war vorsichtig, und diese Vorsicht ist gut
    • Niemand will eine Zukunft, in der jede Interaktion zu Veränderungen durch schwer nachvollziehbare Maschinenschwärme wird
    • Niemand will, dass Pi zu einem unwartbaren Chaos wird, nur um den Wettbewerb mit selbstgeschriebener Software zu gewinnen
    • Niemand will, dass Pi genau diese Art von Engineering fördert
  • Trotzdem ist Pi ein Harness, und Harnesses stehen im Zentrum neuer Experimente
  • Coding-Task-Queues, Agenten-Orchestrierung, Subagents und durable sessions werden immer wichtiger werden
  • Auch wer Schleifen nicht blind akzeptiert, sollte anfangen zu experimentieren
    • Denn man muss verstehen, wie sich diese Zukunft innerhalb von Leitplanken beherrschbar machen lässt

Das Problem, Schleifen zu kontrollieren

  • Akzeptiert man Harness-Schleifen, entscheidet das Harness, wann die Arbeit beendet ist
  • In der Agenten-Schleife sagt das Modell irgendwann „done“, und ein Mensch reviewt
    • Schon vorher steuert in der Regel ein Mensch zwischendurch nach
    • Der Mensch ist beteiligt und lernt dabei
  • In Schleifen, die vom Harness betrieben werden, wird die Rolle des Menschen unklar
    • Selbst das Signal „done“ verliert an Bedeutung und wird zu einer Nachricht, die eine andere Maschine beurteilen soll
    • Die Rolle des Menschen kann sich der eines Boten annähern
  • Viel von dem Code, der derzeit auf diese Weise entsteht, gefällt nicht, und auch die Interaktion mit AI-unterstützt gebauter Software macht wenig Freude
  • Schleifen sind mächtig, entfernen aber zunehmend Verantwortung und drängen derzeit teils dazu, sich der Maschine zu beugen
  • Trotzdem scheint die Zukunft der Schleifen zu kommen
    • Es gibt bereits Beispiele winziger Teams, die in scheinbar unmöglichem Tempo bauen
    • Codebasen verwandeln sich in unklarere, chaotischere Organismen
    • Solche Codebasen sind zugleich nützlich und unordentlich
  • Die künftige Frage ist nicht „Soll man Schleifen fahren?“, sondern eher folgende
    • Wie man in Schleifen das Urteilsvermögen nicht aufgibt
    • Wie man gute Engineering-Regeln bewahrt
    • Wie sich verantwortliche Menschen weiterhin mit Aufsicht befassen können
    • Wie sich Code-Architekturen neu denken lassen, damit man bei Verstand bleibt

1 Kommentare

 
GN⁺ 4 시간 전
Hacker-News-Kommentare
  • Loops funktionieren, wenn man sich vorher genug Zeit genommen hat, wirklich zu verstehen, was man will. Die Voraussetzung ist Klarheit, und zwar so weit, dass man eine Spezifikation sorgfältig genug schreiben könnte, um sie an einen Junior-Kollegen zu übergeben.
    Bis man das versteht, muss man normalerweise 5–6 kaputte, schlampige Versionen durchlaufen. Diese 5–6 Iterationen des Trial-and-Error lassen sich nicht beschleunigen, und keine Agenten-Technologie kann die Denkzeit des menschlichen Gehirns umgehen. Deshalb verbringt man die meiste Zeit damit, zwischen „Ich weiß nicht, was ich will, ich muss den Code lesen, schreiben und daran herumprobieren“ und „Jetzt ist genug Zeit vergangen, ich glaube, ich weiß, was ich will“ hin und her zu wechseln. Man kann sich dabei sehr leicht selbst täuschen, aber Loops kann man erst einsetzen, wenn man wirklich weiß, was man will. Viele glauben, sie könnten mit Agenten diesen Schritt überspringen, aber Verständnis und Klarheit lassen sich nicht imitieren, und bei Leuten, die diese Phase übersprungen haben, fällt das schmerzhaft deutlich auf

    • Ich habe Codex ein Tool bauen lassen, das alle meine pi-Sessions extrahiert. Ich musste Prompts und Subagenten-Gespräche herausfiltern und es dann die Muster analysieren lassen, die ich erzeuge, und sie in ein Flussdiagramm des äußeren Guide-Generation-Prompts umwandeln.
      Ich musste nicht lange darüber nachdenken, was ich wollte, ich wollte einfach, dass es das tut. Das Ergebnis ist noch gemischt, und ich vertraue ihm noch nicht genug, um ihm eine feingliedrige Codebase zu überlassen, aber in dem Spiel, an dem ich arbeite, ist die Zeit für Verifikation auf ein Fünftel von früher gesunken. Das ist nicht unbedingt nur gut. Wahrscheinlich verbringe ich weniger Zeit damit und übersehe dadurch gute Ideen. Vorher waren die Prompts aber mechanisch zu #now-do-this, #now-review-that geworden und bei einem Zustand stehen geblieben, in dem 90 % der Vorschläge richtig waren. Jetzt erinnert es automatisch erst daran, „mit den schwierigen Dingen zu beginnen und währenddessen aufzuräumen und zu refaktorieren“, und nach der ersten Rückgabe daran, „die Arbeit zu reflektieren“, lässt die verbleibenden Probleme aussprechen und steckt das dann in den Guide-Generation-Prompt, um neue Aufgaben auszuwerfen
    • Ich stimme vollkommen zu, dass man 5–6 kaputte Versionen durchlaufen muss. Aber sobald ich ein Harness gefunden habe, dem ich zutrauen kann, den Großteil auf eine Art zu erledigen, die ich mag (Prompt + Skills + Modell), ist der Coding- und Erkundungsteil dieses Prozesses schneller geworden.
      Die Iteration ist schneller geworden, aber der Aufwand, durch diese schlampigen Versionen zu gehen, ist fast gleich geblieben. Ich muss immer noch verstehen, welche Ideen, Prinzipien und Designs zur Lösung passen, was ich als Nächstes versuchen soll, und mein mentales Modell anpassen. Am Ende fühlt es sich so an, als würde ich in kürzerer Zeit mehr mentale Anstrengung aufwenden und nur ein wenig beim Schreiben von Code sparen. Wenn man geübt ist, war das Tippen von Code ohnehin nie der große Brocken. Es wirkt, als würde man „nur“ Prompts schreiben und Code lesen, aber man ist trotzdem genauso erschöpft oder wegen der komprimierten Iterationszyklen sogar noch erschöpfter
  • Ich erlebe so etwas inzwischen jeden Tag, und es ist entmutigend und besorgniserregend. Ich glaube, der Grund, warum wir mehr Code mergen, den wir nicht vollständig erklären können, ist, dass wir das mentale Modell, das früher durch Schreiben von Code und kollaborative technische Planung entstand, jetzt dem Code-Review überlassen.
    Code-Review ist für diesen Zweck nicht geeignet. Ich denke aber, dass man durch strukturierte Übungen aus der Pädagogik, die an Code-Reviews angehängt werden, ein besseres Gleichgewicht zwischen Reibung und Verständnis finden könnte. Ich suche Hilfe, um solche Übungen zu testen

    • Die Fähigkeit, effektiv Code-Reviews zu machen, ist viel schwieriger, als Code zu schreiben. Ohne eine gute Karte davon, wie sich eine Änderung auf andere Teile des Systems auswirkt, ist es praktisch eher ein Ritual des Abnickens.
      Auch die dürftige PR-UI von GitHub hilft nicht. Es gibt nur begrenzte Werkzeuge, um in den nicht direkt geänderten, aber betroffenen Bereichen der Codebase herumzustreifen, Probleme zu finden und hervorzuheben
    • https://pages.cs.wisc.edu/~remzi/Naur.pdf
    • Ich frage mich, was dein Produkt ist. Ich würde wirklich gern sehen, wie ein Produkt aussieht, das von einem Agenten-Schwarm im Umfang des 100-Fachen menschlicher Entwicklung gebaut wurde. Klingt beeindruckend
    • Solcher Code ist oft voller Sicherheitslücken. Es ist wie Hack auf Hack auf Hack, und am Ende landet man bei 100.000 Zeilen Code voller seltsamer Fallback-Pfade für etwas, das man mit 1.000 Zeilen stabiler hätte bauen können.
      Der Punkt im Original, dass man Systeme bevorzugen sollte, die falsche Randbedingungen unmöglich machen, statt sie mit Fallback-Pfaden zu behandeln, ist enorm wichtig. Der Fallback-Ansatz führt dazu, dass man Fallbacks auf Fallbacks implementiert, und jeder Fallback vergrößert die Code-Menge exponentiell und erzeugt irgendwie immer neue Probleme. Man könnte das fast ein „allgemeines Gesetz des Systemdesigns“ nennen. Fallbacks senken das Risiko des Scheiterns, machen das Scheitern aber, wenn es tatsächlich eintritt, komplexer und schädlicher. Als Softwareentwickler gefällt mir die neue Coding-Umgebung, die AI schafft. Big Tech erzeugt für mich dadurch unendlich viel Arbeit. Menschliche Entwickler sind zu einem zentralen Bestandteil der Code-Ausführung geworden und müssen ständig bereitstehen, um die fast unendlich vielen schwierigen unbehandelten Exceptions zu bearbeiten, die zwangsläufig gelegentlich auftreten. Softwareingenieure sind jetzt weniger Arbeiter als eher Sicherheitskräfte, die die meiste Zeit am Schreibtisch sitzen und Kaffee trinken und nur selten eingreifen, wenn ein Problem auftritt
  • Das knüpft an das an, was ich seit Monaten sage. LLMs sind hervorragend darin, Aufgaben zu erledigen, aber schwach bei Ästhetik und Geschmack.
    Es gibt zwei Arten von Arbeit. Die eine ist zielorientierte Arbeit: Es gibt ein Ziel, das erreicht werden soll, und der Weg dorthin ist nicht besonders wichtig. Security ist das perfekte Beispiel. Wenn man ein System exploiten will, interessiert es einen kaum, ob der Exploit schön ist; man will einfach Zugriff auf streng geheime Nuklearpläne. Forschung ist ähnlich, denn „Research-Quality“-Code war schon lange vor dem AI-Zeitalter berüchtigt chaotisch. Die andere ist geschmacksorientierte Arbeit. Wenn man einer großen Codebase ein Feature hinzufügt, denkt man, das Ziel sei dieses Feature, aber oft ist das nicht der Fall. Dass die Codebase für künftige Änderungen aufnahmefähig bleibt, ist viel wichtiger als dieses konkrete Feature, und dafür braucht es Geschmack. Wartbarkeit und Code-Qualität sind keine Synonyme; Code-Qualität ist nur ein Mittel, und ihr Zweck ist Wartbarkeit

    • Viele Organisationen bewegen sich schnell in eine Welt, in der Code-Qualität und Wartbarkeit überhaupt keine Priorität mehr haben. Wenn Claude den Code schreiben wird, ist es dann wichtig, ob dieser Code „wartbar“ ist oder „gute Qualität“ hat? Aus dieser Perspektive nein. Hauptsache, es funktioniert und ist schnell
  • Das Problem, dass ein LLM selbst Fälle behandeln will, die eigentlich auf natürliche Weise falsch sind, ist etwas, worüber in vielen PR-Reviews schon gestritten wurde. Vor allem nachdem so etwas einmal geschrieben wurde, ist es sehr schwer zu vermitteln, dass übermäßige Null-Checks schädlich sind.
    Wenn man nicht besser modelliert oder eine Sprache verwendet, die Summentypen zulässt, habe ich noch kein allgemein überzeugendes Gegenargument gegen solches „Shotgun Parsing“ gefunden. Vielleicht ist es auch gar kein wirklich großes Problem. Aber wenn man eine Codebasis tatsächlich liest und refaktoriert, ist das Verwalten solcher unnötigen Prüfungen immer frustrierend. Sobald sie einmal drin sind, lassen sie sich manchmal kaum noch sicher entfernen, ohne zuerst Logging oder eine breit angelegte Untersuchung hinzuzufügen.

    • Ein Argument, das oft funktioniert, ist, dass optionale Werte den möglichen Zustandsraum eines Programms praktisch verzweigen. Je größer der Zustandsraum wird, desto schwerer wird es, über den Code nachzudenken und ihn zu warten.
      Genau das ist auch der Kern der Aussage, dass man unerwünschte Zustände nicht ausdrückbar machen sollte.
    • AI-Code-Reviews fördern eine überzogene, wahnhafte defensive Paranoia. Dreifache Null-Checks tief in einer Funktion können technisch gesehen ein reales Risiko adressieren, in der Praxis sind es aber oft Fälle, die niemals erreichbar sein sollten, weil der Null-Check bereits in allen aufrufenden oder aufrufbaren Funktionen erfolgt ist, und deshalb womöglich keine Verteidigung wert sind.
    • Entscheidend ist, von wie unmöglichen Fällen man spricht. Ich programmiere selbst ziemlich defensiv.
      Selbst wenn aktuell nichts negative Werte an diese Funktion sendet: Wie schwer wäre es, dass eine zukünftige Codeänderung diese Annahme bricht? Ich fand immer, dass ein klarer Fehler am besten ist. Dann können auch Leute, die mit dem Code nicht vertraut sind, erkennen, welche Annahmen über den gültigen Eingabebereich gelten, und müssen keine unmöglichen Ausreißerfälle mitdenken.
  • Mein Engpass liegt bei der Spezifikation. Die Agenten-Loop ist für mich inzwischen ein weniger wichtiges Problem.
    Wenn ich mir ein klares Verständnis dessen verschaffe, was ich bauen will, und das Ziel als umsetzbare Spezifikation formuliere, die ich im Planungsmodus von Claude Code übergebe, liefert der Agent bei der Implementierung meist sehr gute Ergebnisse. Diese effektive Strategie verlagert die Last des Spezifikationsschreibens jedoch stark auf mich. Der Agent verarbeitet jede Spezifikation in der Regel hervorragend, und auch code-review-basierte Folgearbeiten brauchen meist nur 2 bis 3 Durchläufe, aber schon bald ist man wieder an dem Punkt, an dem eine neue Spezifikation nötig ist. Und selbst wenn ich nicht am Platz bin und der Agent seine Arbeit abgeschlossen hat und eine bestehende Spezifikation starten könnte, die keine Dateikonflikte erzeugt, weil sich die Dateien nicht überschneiden, weiß er nicht, dass er einfach einen neuen Branch erstellen und anfangen darf. Vor dem Schlafengehen sage ich oft: „Erledige Aufgabe X und beginne nach Abschluss und Push mit Aufgabe Y“, aber viel weiter reicht das nicht. Häufig taucht beim Start von Y eine Frage auf, und danach steht der Agent den Rest der Zeit still. Das letzte Problem sind Abhängigkeiten in Kombination mit dem Obigen. Heute habe ich zum Beispiel einen Background-Job-Worker geschrieben, und natürlich brauchen die Jobs späterer Aufgaben dieses System. Solche Dinge passieren ziemlich oft. Auch die Spezifikation selbst muss nach der Implementierung aktualisiert werden, damit dort während der Umsetzung getroffene Detailentscheidungen reflektiert werden. Trotzdem ist es jetzt fast an dem Punkt, an dem eine äußere Loop nötig wird. Das Nadelöhr liegt fast vollständig beim Schreiben von Spezifikationen und bei PR-Reviews. Dort, wo dieses Nadelöhr nicht wichtig ist, möchte ich, dass der Agent einfach weiterläuft. Außerdem bin ich stark davon überzeugt, dass wir anfangen sollten, Werkzeuge zu verwenden, die vielleicht für uns schlechter, für LLMs aber besser sind. Rust ist zum Beispiel wegen seines überstrengen Compilers für mich lästig, für LLMs aber großartig.

    • Genau so sollte es sein. Großartig. Das ist der wichtigste Teil des System Engineering, der in den letzten 20 Jahren im Drang, alles schneller zu bauen, zurückgedrängt wurde.
      Jetzt, da das Bauen stärker automatisiert wird, können Spezifikation und Systemdesign wieder die führende Rolle einnehmen. Vielleicht kommen Engineering und Qualität zurück.
    • Das passt auch zu meiner eigenen Programmerfahrung und zu meiner seit Jahren geäußerten Erwartung, dass AI noch einen weiten Weg vor sich hat, bevor sie Coding wirklich löst. Der schwierige Teil des Programmierens ist nicht, Tasten zu drücken und Code in Dateien zu schreiben, sondern das Verstehen des Problems und das Finden einer guten, sauberen und skalierbaren Lösung.
      AI ist hervorragend darin, brauchbare Lösungen zu erzeugen, die technisch funktionieren, aber ziemlich schwach darin, eine gute Vision für die Lösung zu haben. Sie ist weiterhin sehr nützlich, um Ideen hin- und herzubewegen und das Verständnis explorativ zu vertiefen, aber eine gute Spezifikation zu schreiben, die ein LLM dann umsetzen kann, ist nicht viel leichter, als den Code direkt selbst zu schreiben.
    • Das hier könnte das Problem lösen.
      https://www.aihero.dev/skills-handoff
      /handoff ist inzwischen mein neues Lieblings-Skill.
      https://www.youtube.com/watch?v=dtAJ2dOd3ko
    • Ich frage mich, wie „sehr gute Ergebnisse“ definiert werden. Gehört sauberer, wartbarer Code zur Erfolgsdefinition? Ich muss ständig in der Loop bleiben. Mein Code wird an Tausende Nutzer ausgerollt, daher wird jedes Problem verstärkt.
    • „Spezifikationen schreiben“ ist die inhärente Komplexität des Programmierens. Am Ende heißt das nur: Es gibt keine Silberkugel.
      Ob mit Agenten oder ohne, mit Lochkarten oder mit Interpretern: Am Ende bleibt Programmierung eben Programmierung.
  • Der größte Code-Geruch bei LLMs ist, dass sie versuchen, „alle Fehlerfälle zu behandeln“, und inzwischen sogar Fehler behandeln wollen, die unmöglich sind. Ich verstehe nicht, warum sie so darauf fixiert sind
    In Python zeigt sich das in vollständig typgeprüften Codebasen oft dadurch, dass sie hasattr-Prüfungen an Typen anhängen, bei denen definiert ist, dass das betreffende Attribut existiert. Warum passiert das? Ich frage mich, ob das an Pretraining oder Reinforcement Learning liegt. Falls Letzteres, hoffe ich, dass die Labs das beheben

    • Vermutlich, weil sie lieber in Richtung unnötiger Fehlerbehandlung irren als in Richtung fehlender Fehlerbehandlung. Es ist gut möglich, dass Laufzeitfehler im Training stark bestraft werden
    • Ich denke, es liegt größtenteils an den Trainingsdaten. Ich gehöre auch zum Team „Mach es unmöglich, ungültige Zustände darzustellen“
      Auf HN kommt das oft zur Sprache, aber es überrascht mich immer noch, wenn ich in Open-Source- oder Arbeits-Codebasen, die ich nicht selbst geschrieben habe, sehe, dass das wirklich gut gemacht wurde. Die meisten Programmierer denken nicht so, dass sie Fehler unmöglich machen und die Daten diese Tatsache widerspiegeln lassen; stattdessen sammeln sie an der Stelle, an der eine Fehlermeldung herausfällt, die Scherben auf und flicken sie zusammen. Ich sage „die meisten“, weil ich glaube, dass auch die aktuelle AI genau dieses Denkproblem hat. Das Niveau, auf dem Menschen eine Codebasis am Ende verstehen — also den gesamten Fluss der Garantien insgesamt erfassen — ist etwas, das AI derzeit nur schwer gegeben werden kann. Auf der Ebene des Rohcodes erstrecken sich solche Garantien oft über so viel Code, dass sie leicht das Kontextfenster sprengen. Auch eine Zusammenfassung in einer Art Speicherdatei hat Probleme. Nur weil irgendwo Text über Garantien steht, heißt das nicht, dass AI die richtigen Informationen hervorholt; bei Menschen gilt beim bloßen Lesen von Code Ähnliches. Ich würde nicht sagen, dass es „unmöglich“ ist, AI dieses Verständnis zu geben, aber selbst wenn man es ihr vermittelt, arbeitet die Art, wie AI Dinge erledigt, diesem Verständnis oft entgegen. Meine Lösung war meistens, aufzugeben, dass AI das wirklich versteht. Ich formuliere die Problemlösung stattdessen als Prompt, wie Menschen es gewöhnlich tun, und wenn ich ungültige Zustände unrepräsentierbar machen will, lasse ich die AI die nötigen Refactoring-Schritte nacheinander ausführen. Wenn es sehr klein ist, mache ich es selbst. Wenn man sie schrittweise anweist, Code voller Maps/Dictionaries, Arrays, Strings und Integer gründlicher zu typisieren, macht sie das tatsächlich ziemlich gut. Selbst mit sehr detaillierten Anweisungen kam aus einem einzelnen Prompt nur selten ein gutes Design. Es funktioniert besser, das als zwei getrennte Aufgaben zu behandeln. Und man muss die Unterschiede zwischen Typen sorgfältig beobachten. AI schmuggelt gern Methoden wie .JustSetItAndIgnoreAllThePreAndPostConditions(string) hinein. Vermutlich gibt es in den Trainingsdaten viele Fälle von „ein gut strukturierter Typ, der ungültige Zustände unmöglich machen soll, und später kommt ein Maintainer vorbei und fügt eine JustEffingDoIt-Methode hinzu, die alles kaputtmacht“. Eine der besten Abwehrmaßnahmen ist, solche Typen in eigenen Dateien zu halten und jede hinzugefügte Methode leicht überfliegen zu können, damit man so etwas sofort korrigiert. Ich habe massenhaft Warnungen in die Dokumentation geschrieben, was man nicht tun soll und welche Vor- und Nachbedingungen erhalten bleiben müssen, aber das hat kaum etwas verändert
    • Weil die überwältigende Mehrheit der Codebasen im Trainingssatz nicht vollständig typgeprüft oder schlicht nicht sauber ist. Oder weil es Stack-Overflow-Schnipsel sind, bei denen der bestehende Kontext fehlt, sodass man nicht annehmen kann, dass ein Null-Check ungültig wäre
    • Das fühle ich sehr. getattr bei jeder Dataclass zu verwenden, ist eine merkwürdige Entscheidung
    • Weil es zu den gelernten Mustern passt. AI versteht keinen Code. Sie kann keinen tatsächlichen logischen Fluss herleiten, sondern nur mit Mustern umgehen
  • Code ist Teil des geteilten und angesammelten Verständnisses eines Informationssystems
    Wenn uns diese Schleifen alle in den stetig anschwellenden Wellen von Software in Bewegung halten, dann läuft auf der höchsten Ebene des logischen Entwurfs von Informationssystemen am Ende alles auf menschliches Urteilsvermögen und das Austarieren von Geschäftsanforderungen hinaus. Um zu einer bestimmten Nische eines Unternehmens oder Markts zu passen, müsste jeder Programmierer zugleich Business-Analyst, Marktforscher und Unternehmer sein. Ausnahmen wären nur bestimmte Nischen, in denen AI-Tools nicht gut „klappern“ können, oder der Fall, dass das Zeitalter subventionierter AI-Tokens endet und all diese Schleifen zu teuer werden. Das fühlt sich an wie eine Wiederholung von Expertensystemen und Symbolics-Lisp-Maschinen. Für einen kurzen Moment war die Realität, auf die wir gestoßen sind, nicht so sehr, dass Code selbst etwas nicht kann, sondern dass die Organisationsstruktur eines Unternehmens am Ende direkt in die Software eingeschrieben wird; wenn man also die Unternehmensorganisation nicht ändern kann, gibt es auch Grenzen für die Flexibilität der Software. Datenflüsse und Domänenwissen, Domain Modeling und Ubiquitous Language können zu der Metasprache werden, mit der wir Qualität, Funktionalität sowie nichtfunktionale Standards und Konventionen festlegen. Wir müssen dafür sorgen, dass die „clanker“, die „durch die Schleife laufen“, Daten-, Verhaltens- und Performance-Verträge erfüllen, bevor sie „fertig“ sagen. „Fertig“ bedeutet nun nicht mehr nur Code, der kompiliert, gebaut, deployed oder sogar in Produktion ist. Es muss Code sein, der die Anforderungen von Nutzern, Operatoren und Maintainern gleichermaßen erfüllt. Die Sprache, die wir verwenden, könnte uns daher alle eher zu Business-Analysten und Softwarearchitekten machen als zu Menschen, die nur die Syntax kennen. Ist das die Rache von UML und die Rückkehr von deklarativem/logischem Design und BDD?
    Die Rechtschreibprüfung wurde mit gemma4-12b gemacht, aber ich habe mir die Botschaft nicht umschreiben lassen

  • Ich frage mich ständig, ab wann ich nicht mehr zwangsweise selbst in der Schleife sitzen muss. Als Entwickler mag ich es wirklich, die Struktur von Code zu verfeinern, ihn klarer zu machen, über gute Abstraktionen nachzudenken und ihn in Module aufzuteilen
    Daran habe ich Freude, aber irgendwann verstehe ich auch, dass ich zum limitierenden Faktor werde. Wenn der Zweck von Software darin besteht, Menschen Nutzen zu bringen, sollte es mir dann noch wichtig sein, wie der Code aussieht? Im Moment denke ich, die Antwort ist „ja“ — aber in 3 Jahren? In 10 Jahren?

    • Wenn du willst, dass Software den Menschen weiterhin Nutzen bringt, lautet die Antwort ja
    • Es kann hart sein, wenn man an einem Ort ist, an dem außerhalb von Technik kaum etwas Bedeutung hat. Ich glaube, bald kommt eine existenzielle Wende hin zu Arbeit, die mehr Erfüllung bietet. Vielleicht ist das naiv gedacht, oder einfach etwas, das ich selbst gerade zu brauchen glaube
    • Refactoring kann man jederzeit an einen Agenten delegieren. Selbst Refactorings, die schon beim bloßen Gedanken daran ermüdend groß wirken, kann er schaffen
  • Wenn etwas viele Urteile erfordert und „Code ist, der mir wirklich wichtig ist“, dann fällt es mir schwer, der hier beschriebenen Richtung zuzustimmen. Entscheidungen, die einem wirklich wichtig sind, sollte man nicht delegieren.
    Die Unterscheidung zwischen Agenten-Loop und Harness-Loop gefällt mir, aber delegieren sollte man nur Dinge, die sich im Voraus präzise spezifizieren lassen. Bei mir sind das meist wiederholbare Aufgaben, zum Beispiel: „Schau, wie X gemacht wurde, und mach Y genauso.“ Das ist im Kern vorhersehbare Arbeit. Wenn es am Ende etwas ist, bei dem ich ohne mein eigenes Urteil sowieso „nein“ sagen würde, dann sollte man wieder auf Zusammenarbeit innerhalb des von Armin beschriebenen Agenten-Loops zurückgehen. Das ist völlig in Ordnung. Schnell und zugleich sicher. Schon vor AI-Coding-Assistenten kam gelegentlich ein extrem produktiver Engineer ins Team. Die Kolleg:innen waren dann neidisch und sagten: „Klar habt ihr das alles geschafft, ihr hattet ja X im Team!“ Aber sie haben den Fluch nicht erlebt, so jemanden in der Nähe zu haben. Wenn die Ausrichtung nicht perfekt stimmt, rasen solche Leute mit enormer Geschwindigkeit in die falsche Richtung.

    • Entscheidungen, die einem wirklich wichtig sind, sollte man nicht delegieren. Oder man findet einen deterministischen Weg, diese Entscheidungen einzubauen.
    • Exakt. Wenn du es nicht einmal an jemanden auslagern würdest, den du für hochqualifiziert hältst, warum dann an eine Maschine?
  • Ich weiß nicht, was das in der Praxis eigentlich bedeuten soll. Es wirkt einfach wie ein wortreicher Text, der mit abstrakten Begriffen hantiert, um ein größeres Bild anzudeuten, und am Ende geht es doch nur darum, AI Code schreiben zu lassen.
    Läuft es jetzt darauf hinaus? In Wirklichkeit werden wir keine Thought Leader, sondern eher Pseudolehrkräfte, die eine Horde AI-Idioten irgendwie in Richtung richtiger Antwort treiben, müssen aber unsere Rolle weiter mystifizieren, damit wir noch wie Vordenker wirken? Ohne dass auffällt, dass das alles nur Tech-Posing ist?

    • Das ist weder ein wortreicher noch ein abstrakter Text. Es geht hier um Effekte zweiter Ordnung davon, „AI Code schreiben zu lassen“, und zwar auf eine Weise mit weniger Aufsicht.
      Der Autor hätte es vielleicht knapper formulieren können, aber nur weil ein Leser es auf dem jetzigen Niveau nicht versteht, heißt das nicht, dass hier etwas mystifiziert wird.
    • Wenn man den AI-Hype schluckt, redet man eben so. Yegge ist ein noch schlimmeres Beispiel.
    • Ich bin überzeugt, dass sich Software Engineering gerade in zwei Lager aufspaltet. Das sind reale Sorgen, und für Entwickler, die mit dem Agenten-Loop und stark AI-gestützten Workflows gearbeitet haben, ergibt das eine schlüssige Logik.
      Ich sehe im Job und in meinen privaten Projekten exakt das, wovon der Originaltext spricht, und es ist beängstigend, dass jemand das als „wortreichen Text voller abstrakter Begriffe“ liest. Das gibt mir das Gefühl, dass die meisten überhaupt nicht mitbekommen, was gerade passiert.
    • Früher lasen sich Tech-Blogs wie sofort umsetzbare README-Anleitungen. Bei diesem Text dachte ich beim Lesen nur: „Und was genau soll ich mit dieser Information anfangen?“ Deshalb habe ich ihn nicht zu Ende gelesen.
      Im AI-Bereich liegt die Haltbarkeit des aktuellen State of the Art bei ungefähr zwei Wochen. Ich habe den Ralph-Wiggum-Loop nicht mitgenommen, und inzwischen bin ich froh, dass ich es gar nicht erst versucht habe.
      https://news.ycombinator.com/item?id=46682325
    • „Was das in der Praxis bedeutet“ heißt: mehr Token verwenden.