De laatste tijd lijkt het alsof al mijn tweets alleen nog maar over LLM's gaan. Zo verslaafd ben ik eraan. Als ik even niets te doen heb, vraag ik LLM's meteen om hulp of stel ik ze vragen. Vooral het laten schrijven van code door agents voelt alsof ik me stort op een gloednieuw sociaal spel, waarbij ik elke minuut optimaal benut.

Het is leuk om agents te gebruiken om code te schrijven. Ik ben bezig met het maken van een RDBMS, en met een gevoel van "Wat zullen we nu doen?", "Zullen we een PostgreSQL-compatibele interface toevoegen?", "Echt? Kan dat?", "Klaar!" worden er de ene na de andere implementatie toegevoegd. Natuurlijk is het niet meteen perfect, dus tijdens het schrijven van unit tests komen er steeds meer gebreken aan het licht, maar de ontwikkelingssnelheid is nog steeds overweldigend. Het meest indrukwekkende is dat er met de belasting van ongeveer één extra gesprekspartner naast mijn werkzaamheden, zo'n 100.000 regels code verschijnen, wat verder gaat dan bewondering en neigt naar ontzag.

Zoals degenen die mijn uitspraken op sociale media volgen wellicht weten, heb ik de software engineering-wetenschap lange tijd niet vertrouwd. Het is niet iets wat een individuele programmeur kan leren en toepassen; het is een wetenschap voor het bestuderen van het gedrag van een groep mensen die samen programmeren, en ik betwijfelde sterk of het toepasbaar was op alle verschillende programmeeromgevingen. Maar als je meerdere agents gebruikt, realiseer je je dat je bugs kunt opsporen zonder de code te lezen, en dat je het gevoel nodig hebt om betrouwbare plaatsen geleidelijk uit te breiden, waardoor je onvermijdelijk een software engineering-achtige aanpak hanteert. Ik neem geen bugdichtheid of convergentiecurves over, maar ik ben me ervan bewust dat ik me niet ver van die benadering bevind.

Zelfs in situaties waarin een amateur tegen een agent zou schreeuwen "Maak software zonder bugs!!", kun je de meeste problemen oplossen door met software-expertise hardnekkig instructies te geven, afgedankte taken via dialoog te scheiden en opnieuw instructies te geven. Door dergelijke taken te herhalen, ben ik opgelucht dat de inzichten die ik tot nu toe heb opgedaan niet nutteloos zijn geweest, maar ik voel tegelijkertijd dat het slechts een kwestie van tijd is voordat de agent dit soort dingen zelfstandig kan oplossen. In dit opzicht ben ik vrij pessimistisch over de toekomst van het programmeursvak.

De code die door agents is geschreven, is eerlijk gezegd een beetje griezelig, en ik heb niet veel zin om het te onderhouden, maar de basisveronderstelling is dat software engineers geen code willen onderhouden. Ze onderhouden de code alleen omdat het geld oplevert, en het lezen van code is de laatste redmiddel voor onderhoud (vakmensen-programmeurs mogen naar believen specifieke code bewerken, ik neig daar zelf ook naar). Programmeren is het werk van de constructie, terwijl software engineering een continu proces is om ervoor te zorgen dat het continu waarde creëert, en om geen misverstanden te creëren, is het een kristallisatie van de inspanningen die de afgelopen decennia zijn verricht om de kwaliteit te waarborgen zonder code te hoeven lezen die je niet wilt lezen.

De regels zijn aanzienlijk veranderd, dus sommige dingen kunnen worden gebruikt en andere niet. Hieronder beschrijf ik de tips die ik op dit moment voel, voor zover ik kan bedenken:

Context engineering is organisatietheorie

Of het nu door AI wordt geschreven of niet, de universele waarheid van software is dat code altijd blijft groeien. De contextlengte van LLM's zal in de toekomst waarschijnlijk toenemen, maar de groeisnelheid van softwarecode zal dat altijd overtreffen. Zelfs als LLM's het contextprobleem kunnen vermijden, blijft het contextbereik waarop ze zich succesvol kunnen richten beperkt, en het probleem van het vinden van een speld in een hooiberg zal altijd aanwezig zijn. Natuurlijk kan niet het hele team de volledige productiecode in hun hoofd proppen, dus je verdeelt de taken zonder dat iemand het je vertelt. Deze taakverdeling is context engineering vanuit een ander perspectief. Kortom, als je het hele projectbeeld in de context gooit, wordt het te groot en kun je niet meer nadenken, dus de manier om het werk op te delen is om te zeggen: "Ik wil dat je deze functie aan deze module toevoegt, en je hoeft niets te weten over dingen die niet nodig zijn voor het uitvoeren van deze taak." Dit is wat er in de meeste beroepen wordt gedaan voor nieuwkomers, en het is niet beperkt tot AI-agents. Als je AI-agents gebruikt, zul je merken dat ze pathologisch snel zijn in het omzetten van 0 naar 1. Ze zijn getraind op basis van die benchmarkset, en het oplossen van bugs waar mensen mee worstelen is slechts een bonus. De reden dat ze snel zijn in het omzetten van 0 naar 1, is dat er geen bestaande code in hun hoofd zit die ze moeten kennen om de taak uit te voeren, dus ze hoeven zich niet veel zorgen te maken over contactpunten. Programmeurs met een kleine context willen ook microservices creëren, omdat microservices de context verkleinen die ze in hun hoofd moeten hebben. Microservices zijn een extreem voorbeeld, maar het opdelen van software is een manier om de reikwijdte te beperken waar anderen zich zorgen over moeten maken, en de "scheiding van concerns" is ook de scheiding van informatie die in het hoofd van de agent moet worden gestopt. Er is nog steeds geen volledige consensus over wat "software architectuur" is, maar voor mij is het de scheiding van de context die in het hoofd van de mensen die eraan werken moet worden gestopt. Zelfs als je met één pennestreek waardeobjecten introduceert, verandert de context die de programmeur in zijn hoofd moet stoppen niet, dus je kunt niet zeggen dat de architect goed werk heeft geleverd. Ik denk dat het opdelen van taken op een manier die het voor agents gemakkelijk maakt om te werken, erg lijkt op het opdelen van software op een manier die het voor mensen gemakkelijk maakt om te werken. Mijn huidige intuïtie is dat er op dat niveau meer te maken is dan ik had gedacht, dus ik denk dat we high-end modellen met een grote en intelligente context zullen gebruiken, maar misschien lukt het wel om goedkope modellen te gebruiken als we het uitbesteden aan onderzoeksagents.

LLM's zijn duur

Iedereen zegt dat high-end modellen duidelijk betere code genereren, maar de prijs van high-end modellen ligt in de orde van grootte van $10 of $20 per 1 miljoen tokens. Het werk dat met die context wordt gedaan, zal waarschijnlijk enkele uren van een programmeur in beslag nemen, dus het loont de moeite, maar het zou geweldig zijn als je het werk aan goedkopere modellen kon overlaten. Naarmate de prijsconcurrentie vordert, kunnen de huidige high-end modellen extreem goedkoop worden en overvloedig worden gebruikt, maar tegen die tijd zullen er high-end modellen zijn die beweren dat ze problemen kunnen oplossen die nergens anders kunnen worden opgelost. Het resultaat is dat de situatie waarin goedkope modellen worden gebruikt om taken te schrijven die niet zo moeilijk zijn, ook in de toekomst zal blijven bestaan. Lokale LLM's, die het uiterste zijn van goedkope modellen, zijn een aantrekkelijke optie voor offloading, en ik denk dat een groep lokale agents die taken uitbesteden die zijn gedefinieerd met high-end modellen, een realistisch verhaal is. Ik weet niet in hoeverre de huidige lokale LLM's complexe coderingstaken kunnen uitvoeren, maar het verhaal dat je ze laat schrijven met goedkope modellen, en als je niet kunt debuggen en de handdoek in de ring gooit, je de kennis overdraagt aan een slimmer model, zal waarschijnlijk gezond verstand worden. Lokale en high-end modellen werken samen in de vorm van sub-agent aanroepen, en softwareontwikkelingsbedrijven kunnen in feite een voltooid team zijn van een paar mensen die een groot aantal lokale LLM's draaiende houden. De prijs van AMD's Ryzen AI Max-serie zal waarschijnlijk ook sterk stijgen, omdat de concurrentie bestaat uit menselijke programmeurs van vlees en bloed.

AI-agents zijn instabiel

Ik weet niet precies waar de implementatie slecht is, dus ik kan er geen definitieve uitspraken over doen, maar onverklaarbare stops, intermitterende fouten en andere onverklaarbare dingen gebeuren voortdurend. Het is niet ongebruikelijk dat de kernel niet crasht, maar de reactiesnelheid van de editor 1 minuut duurt. De kwaliteit van het herschrijven is ook erg variabel, en de regelnummers van de herschrijfbestemming zijn vaak een puinhoop, waardoor het erg destructief is. Ze merken zelf dat ze kapot zijn en gaan het repareren, dus het is niet zo erg, maar er zijn tips om instabiele dingen instabiel te gebruiken, en voor zover ik weet is de Lale-lus en de bijbehorende voortgangsregistratie effectief.

De Lale-lus is, in een notendop, het in een lus plaatsen van het opstarten van de agent zelf. Instrueer de prompt echter om de voortgang ergens op te schrijven en lees de voortgang bij het begin van de lus. De agent ontvangt dan de "vorige voortgang" als context en voert de "huidige taak" uit. Het voordeel hiervan is dat de agent blijft werken, zelfs als hij halverwege stopt of sterft door OOM. Het voortgangslogboek kan te groot worden, maar je kunt het op de een of andere manier oplossen door een prompt te schrijven om het naar behoefte samen te vatten en te comprimeren. Omdat alle taken in één lus worden uitgevoerd door één duur model, kan de inhoud van de lus zelf zo complex worden als je wilt door stappen toe te voegen, zoals het toewijzen van de ontwerpfase, het opdelen van taken aan dure modellen en het laten uitvoeren van eenvoudig ogende taken door goedkope agents. Het programmeren van het al dan niet aanroepen van een coderingsagent is dus een prima vorm van metaprogrammering. Ik heb dat stadium nog niet bereikt... Het is te verwachten dat het verbeteren van de lus zelf door LLM's op een gegeven moment de norm zal worden.

Het is interessant dat antirez, in de prompt die hij gaf om de code te versnellen, instrueerde om "5. Use this file to track progresses". Aangezien het werk halverwege kan worden beëindigd, maar de tekst wordt gebruikt om verder te gaan, is het heel logisch dat de tekst de vorige voortgang bevat.

5 keer zelf-evaluatie

De code die door de coderingsagent wordt uitgevoerd, werkt in 90% van de gevallen, maar naarmate de hoeveelheid toeneemt, worden er bij elke zelf-evaluatie verbeterpunten gevonden. Ik wil dat ze vanaf het begin perfecte code schrijven waarvoor geen beoordeling nodig is, maar aangezien dat voor mensen moeilijk is, zijn er waarschijnlijk gebreken die LLM's niet kunnen vinden, tenzij ze in een andere context worden beoordeeld. Het kan lang duren voordat mensen de code die ze hebben geschreven, reflecteren, maar buitenlandse engineers schrijven dat coderingsagents vaak na 5 keer convergente resultaten opleveren.

De kosten zijn natuurlijk enorm, maar ze zijn nog steeds veel goedkoper dan mensen, en als je het in het systeem stopt, is er geen ruimte meer voor menselijke tussenkomst. Ik weet niet zeker of het getal 5 een concrete betekenis heeft, en het zal in de toekomst waarschijnlijk een ander getal zijn, maar mijn ervaring is dat er, zelfs als de code die door de agent is geschreven een paar keer wordt beoordeeld, nog steeds veel verbeterpunten zijn. De specialiteit van LLM's is reflectie. (Ik zie ook beoordelingscommentaren die worden toegevoegd als kritiek om een dialoog tot stand te brengen, dus een beoordeling van de beoordelingscommentaren zelf kan nodig zijn). Het ziet ernaar uit dat het nog wel even zal duren voordat mensen de code die door coderingsagents is geschreven, beoordelen als deze in productie wordt gebruikt, maar het zal gebruikelijk worden dat de machine zelf N keer beoordeelt voordat mensen beoordelen. Het lijkt erop dat degenen die creëren en degenen die bekritiseren elkaar versterken. Het beoordelen van agents van meerdere bedrijven kan ook nieuwe perspectieven opleveren.

Het is een beetje te lang geworden, dus ik ga het hier publiceren.