Over LLM’s, AI, Github Copilot, en code typen

Large language models (LLM’s) zijn niet meer weg te denken uit de softwareontwikkeling. Ze worden steeds meer gebruikt en het aantal code-assistent tools groeit snel. Maar hoeveel helpen ze echt? Ik hoor aan de ene kant zowel dat ze veel helpen, als aan de andere kant dat ze helemaal niet helpen; en in feite de ontwikkeling vertragen. Dus waar staan we met grote taalmodellen, en helpen ze echt of zijn ze gewoon weer een nieuwe rage in software development?

Ik geloof in kunstmatige intelligentie in de zin dat ik er vrij zeker van ben dat er geen technische belemmeringen zijn om op een dag artificial general intelligence (AGI) (zo goed als of beter dan een mens) te bereiken. Wanneer die dag komt, en of dat goed of slecht is, weten we misschien niet – in ieder geval qua timing is het waarschijnlijk eerder dan we denken. Ik denk dat het bijna zeker binnen het leven ligt van de meeste mensen die dit vandaag lezen. Dat is zowel fascinerend als beangstigend. één ding is zeker, we zijn er nog niet. Maar zelfs voordat we op dat punt zijn, is AI nu al op een niveau dat ontwrichtend is, en die ontwrichting zal alleen maar sneller gaan. 

Hier wil ik me meer specifiek richten op het gebruik van kunstmatige intelligentie om ons te helpen bij het schrijven van code. De huidige generatie van LLM’s heeft veel mensen verrast, en het tempo van de veranderingen is nog steeds duizelingwekkend hoog, zelfs nadat een aantal van de recente overhypte dingen rond AI nu al een beetje zijn afgezwakt. Het is ook duidelijk dat we nog niet op het niveau van kunstmatige algemene intelligentie (AGI) zijn. De huidige generatie code-assistenten zijn bovenmenselijk en dom tegelijk. Ze zijn bovenmenselijk qua snelheid en geheugen, en soms lachwekkend naïef qua de code die ze produceren. Dat komt omdat ze iets belangrijks missen dat diep in de wortels van softwareontwikkeling zit, en naar mijn mening zullen ze dat essentiële onderdeel blijven missen totdat ze het niveau van kunstmatige algemene intelligentie bereiken waarbij ze in vrijwel alles minstens zo slim zijn als een mens. 

De ontbrekende component waar ik het hier over heb is dat er veel meer komt kijken bij softwareontwikkeling, dan alleen syntactisch correcte code kunnen maken. Dat was al nooit genoeg. Ik weet dat er een aantal organisaties zijn die software developers proberen te behandelen als een soort getrainde code typende apen… maar dat zijn niet de bedrijven waar echte – laat staan first-class – ontwikkeling plaatsvindt. Er is veel meer voor nodig dan alleen de vaardigheid om een variabele te structureren in een for-loop, of om een stream te verwerken. 

We zijn als professionele programmeurs niet aan het werk om code te typen; we zijn in dienst om problemen op te lossen. De code is het gereedschap dat we over het algemeen gebruiken om de problemen op te lossen. Dus of de code nu geschreven is door een LLM of door een junior ontwikkelaar – het vermogen om gedetailleerde instructies van een oplossing te vertalen naar code is niet het moeilijke gedeelte. Door het als zodanig te behandelen, loop je in de val om aan te nemen dat “no code” of “low code” het juiste antwoord is op alle problemen. Als je zo kijkt, kun je AI zien als de, naar ik aanneem, ultieme “no code” oplossing. (Wij vertellen de AI wat hij moet doen, en hij (zij?) schrijft de code). 

Een van de problemen die ik heb met deze benadering is: wat betekent het om de AI te vertellen wat hij moet doen, als DAT geen vorm van programmeren is? De manier waarop sommige bedrijven en mensen praten over LLM’s die code genereren, lijkt mij in dezelfde val te trappen als de “low-code” en “no coders”. De aanname hier is dat de bottleneck voor softwareontwikkeling ergens in het typen zit. 

Ik denk dat dat helemaal niet waar is. Hun conclusie is dat als we de hoeveelheid typewerk bij al dat programmeren maar kunnen verminderen, dat dat veel geld zal besparen dat anders “verspild” zou worden aan programmeurs. Het probleem is dat dat een enorme misvatting is van waar softwareontwikkeling echt om draait – en wat er nodig is om vaardig te zijn in softwareontwikkeling. Het gaat niet om sneller kunnen typen (ja, we kunnen allemaal af en toe blijven hangen in de syntax) of om het begrijpen van het programmeermodel van een framework of tool. 

LLM’s kunnen opmerkelijk behulpzaam zijn bij het beantwoorden van sommige, of ons op zijn minst helpen met sommige van die vragen. “Hoe codeer ik dit stukje” soort vragen. Ik heb GitHub co-pilot hiervoor gebruikt, en ik vind de manier waarop het dingen suggereert fijn. In deze mode is het meer een soort slimmere autocomplete dan iets dat al het werk voor me doet. Ik heb niet het gevoel dat ik de controle verlies als het op die manier werkt; soms raadt het de verkeerde dingen aan, maar het is vrij eenvoudig om die aanbevelingen te negeren als ik dat wil. Tot nu toe, in mijn ietwat beperkte gebruik van co-pilot, vond ik het prettig dat het advies vrij beperkt is gehouden. Het is er niet op gericht om grote blokken code aan te raden als het zo werkt, of als ik zo werk, maar het geeft alleen suggesties over wat er daarna komt en vaak was dat wat ik toch al van plan was om te typen. Dus het bespaart me wat typewerk. 

Ik heb sommige mensen dit een soort “geautomatiseerd pair programming” horen noemen. Zo ver zou ik niet willen gaan, maar ik begrijp wat ze bedoelen. Het doet me denken aan sommige aspecten van pair programming die ik goed vind – het kleine duwtje in de rug om me eraan te herinneren of aan te bevelen wat er nu komt, wanneer ik pauzeer of duidelijk vastzit. Ik neem aan dat dit is wat mensen bedoelen die aanzienlijke productiviteitswinst melden. Ik ben nu geen fulltime programmeur. Ik schrijf vooral code voor de lol, of om mijn werk te ondersteunen en ideetjes te proberen. Dat is niet hetzelfde, dus ik kan niet beweren dat het mij tot nu toe een enorme productiviteitswinst heeft opgeleverd – maar ik waardeer de hulp van AI en ik denk dat het iets toevoegt aan mijn productiviteit. 

Er is een veelgebruikte grap: “moderne software ontwikkeling is voornamelijk het opzoeken van het antwoord op Stack Overflow, en het plakken ervan in productie code”… Dat is natuurlijk niet echt zo, maar ik denk wel dat het internet, stack Overflow en soortgelijke sites, en open source, de dingen ingrijpend hebben veranderd. We kregen toegang tot veel meer code en veel meer ervaring. Misschien nog wel belangrijker, gezien de hoeveelheid code die nu beschikbaar is om te delen, was dat we ook hulp kregen bij het vinden van de code die voor ons het meest interessant was. Ik denk dat LLM’s in de co-pilot mode ongeveer hetzelfde probleem oplossen.

Dat is in wezen heel slim zoeken naar relevante dingen die gebeuren terwijl we typen. Dat sluit mooi aan bij een interessant idee dat ik onlangs tegenkwam en dat LLM’s en wat ze doen beschrijft als hetzelfde als lossy beeldcompressie. Als je een set gegevens invoert, behoudt de LLM de globale inhoud, maar geen perfecte kopie. de LLM doet dit door een soort vage kopie te maken van de voorbeelden uit hun trainingsset, net zoals lossy beeldcompressie dat doet. Genoeg in ieder geval om de voorbeelden waarmee ze getraind zijn opnieuw te benaderen; gebaseerd op de context voor zover zij die begrijpen. 

Dat klinkt misschien een beetje esoterisch, en dat is het misschien ook, maar dit lijkt me relevant voor hoe LLM’s omgaan met code. Als je vraagt om iets – simpels; alledaags – waarvan er duizenden voorbeelden in de trainingsdata zitten, dan krijg je waarschijnlijk een vrij accuraat antwoord. Probeer je favoriete AI voor het genereren van code te vragen om Fizzbuzz op te lossen, en het zal je een aantal goede opties bieden met weinig of eigenlijk helemaal geen uitleg van jouw kant. Vraag het echter iets meer aparts, en het zal meer informatie nodig hebben. Het zal je vragen om suggesties, zelfs voor de beschrijvingen die je schrijft van de code die je wilt. Onthoud dat een LLM altijd alleen maar statistisch gokt welk woord erna komt, gebaseerd op de trainingsdata. Of de suggestie nu voor de beschrijving in het Engels is, of voor de code zelf. 

Wat ik eigenlijk doe, is programmeren. Ik programmeer gewoon in het Engels een soort Engelse pseudo code, en ik probeer het resultaat in de code te krijgen zoals ik dat wil. Ik pruts en probeer verschillende benaderingen opnieuw op een vergelijkbare manier als wanneer ik dat in een programmeertaal zou schrijven. Ik probeerde de oplossing die de AI genereerde in de richting te sturen die ik graag zou willen. Het probleem is dat elke menselijke taal een veel rijkere syntax heeft en tegelijkertijd veel minder precies is dan een programmeertaal. Dus als ik een oplossing in gedachten heb, kan het voor mij sneller en preciezer zijn om deze gewoon meteen in code te schrijven, in plaats van eerst te proberen deze in een menselijke taal te beschrijven aan de AI – en de AI vervolgens de code te laten schrijven. Dus als ik het punt kan vinden waarop ik moet overschakelen van a) de AI die me helpt en suggesties geeft, en b) van een Engelse beschrijving naar code, dan kan AI me helpen om een deel van het werk voor me te doen – “hier is de code die je wilt”.  Ik kan me voorstellen dat het heel makkelijk is om aan te nemen dat het de taak van de AI is om de code te schrijven, en dan ben ik veel te lang bezig met het bedenken van een soort prompt om de code te schrijven die ik echt wil – en dan duurt het langer

Er is nog iets waarvan ik denk dat het makkelijk te missen is bij de huidige generaties van LLM code-assistenten: dat is het incrementele karakter van software development. Net als “low” en “no” code oplossingen, doet AI het niet geweldig om een systeem stap voor stap op te bouwen. Het negeerde ook een aantal van de vereisten in mijn test en had andere helemaal verkeerd. Dus het doet niet wat ik vroeg om te doen, en het voegde ook een bug toe…. een fout die ik waarschijnlijk niet zou hebben gemaakt. Als ik met iets veel complexers bezig was dan een simpele test, hoe makkelijk zou het dan zijn geweest om over dit soort fouten heen te lezen? Vooral omdat ik geen test heb die me vertelt wat ik probeer te bereiken, en de resultaten die de AI genereerde niet echt gespecificeerd waren – behalve qua die cyclus van een wollige beschrijving in het Engels en de AI gegenereerde onzincode. 

Mijn indruk is dat beide groepen mensen die beweren dat AI een grote hulp is, en AI géén grote hulp is, waarschijnlijk allebei gelijk hebben. Ik denk dat als je AI gebruikt als een soort slimmere zoekmachine, een slimme helper, dat het dan vrij snel gaat. Maar als je vertrouwt op de AI om de code voor jou te genereren, dan zal dat waarschijnlijk langzamer zijn dan wanneer je gewoon de code zelf schrijft. 

Wat me ook opviel, was dat wanneer ik de AI gebruikte, ik minder tijd besteedde aan het nadenken over de code, vergeleken met de tijd die ik besteedde aan typen. Ik had de neiging om het gewoon vluchtig te lezen en te zeggen “nou, dat ziet er wel ongeveer ok uit”, en dan verder te gaan. En dat was niet goed genoeg, want er zaten bugs in. Maar toen ik zelf weer de code schreef, ging ik langzamer werken en meer nadenken; ik besteedde nu meer tijd aan denken, en minder tijd aan typen. En dat is zeker een deel van de manier waarop ik in het algemeen code schrijf. Ik denk graag even na, en dan is daarna het typen van de code eenvoudig.

Nadenken is het tijdrovende deel in softwareontwikkeling. 

En dat geldt of je nu zelf de code schrijft, of dat een AI het voor je doet.