Wat engineers nog steeds moeten weten wanneer AI-agents coderen
Inderdaad. App.tsx bestaat uit ongeveer 30 regels code, behalve dat 15 van die regels eigenlijk volledige componenten zijn die Codex had besloten om elk op een enkele regel te schrijven. Dat op zich zou oké zijn; gewoon door Prettier halen en we zijn klaar. Maar dat verklaart de cyclomatische complexiteit niet. Elk van deze componenten was vrij complex, met een aanzienlijke hoeveelheid weergave- en businesslogica. Mijn oude ik zou het zorgvuldig hebben gerefactord en ervoor hebben gezorgd dat de code leesbaar was. Codex daarentegen maakte zich geen zorgen dat volledige componenten op één regel stonden, en belangrijker nog: het had geen enkel probleem met de complexiteit. Het was gelukkig en betrouwbaar aan dat bestand blijven werken tijdens de implementatie van verschillende features.
De CI-tool signaleerde een probleem, wellicht correct, wellicht incorrect. Maar omdat dit een echt systeem is, moest ik erin duiken. Na het formatteren van de bestanden heb ik de componenten en de logica gecontroleerd. Was Codex verder gegaan dan een typische developer zou doen wat betreft het afdekken van edge cases, en had het de boel een beetje over-engineered? Ja, maar het was allemaal correct. Geen klachten van mijn kant. Al die complexiteit was gerechtvaardigd door de business requirements. Dus ik vertelde Codex om SonarQube tevreden te stellen, wat het deed door de boel te refactoren en op te splitsen in 10 bestanden. De CI was goedgekeurd; de wijzigingen zijn shipped. Hoewel dit specifieke incident snel was opgelost, kun je je waarschijnlijk voorstellen hoe het veel slechter had kunnen lopen. Dit was immers code die ik zelf nog nooit had gezien.
Dit is de richting waarin onze industrie zich beweegt: het beheren van een softwaresysteem zal veel minder afhangen van het feit of je het (of soortgelijke systemen) met de hand hebt geschreven. In plaats daarvan wordt het belangrijkste: precies genoeg weten om te herkennen wanneer er iets mis is, en bereid en in staat zijn om zo diep te graven als nodig, wanneer dat nodig is.
Duikbots en goudklompjes
Stel je voor dat je op een boot bent en je baan is om kleine goudklompjes van de bodem van de oceaan te verzamelen. Tot voor kort moest je, als je je zak met goud wilde vullen, in het water springen, naar de bodem zwemmen, rondkijken en je zak vullen. Makkelijk genoeg in helder, ondiep water, maar je kunt je voorstellen hoe snel dit kan escaleren tot iets veel moeilijkers. Naarmate de ondiepe mijnen opdroogden, bouwden jij en je collega-engineers allerlei machines en tooling om goud uit steeds dieper en gevaarlijker water te winnen. Dit werkte grotendeels goed; jij en je team stelden de machines zorgvuldig samen, onderhielden ze en roteerden ze, en doken constant af naar de mijnbouwoperatie op de zeebodem om deze draaiende te houden. Af en toe hoorde je over het instorten van sommige operaties, soms door de enorme onderwaterdruk, andere keren door ongelukken of incompetentie van de operator. De uitdaging is dat dit een geologisch actieve wereld is, waardoor de zeebodem constant verandert: sommige mijnen drogen op en nieuwe duiken op andere plekken op.
Het goede nieuws is dat de afgelopen jaren steeds geavanceerdere "duikbots" zijn ontwikkeld die zelfstandig kunnen afdalen en een mijnbouwoperatie kunnen opzetten. Je vertelt ze alleen waar ze moeten bouwen, waarna ze duiken en alleen bovenkomen om je updates en goudklompjes te geven. Alles is geweldig; je kunt nu ontspannen op je boot terwijl je duikbots hun werk doen, en je enige zorg is hoeveel goud je in je boot kunt proppen. Dit is het kamp van de Optimisten.
Totdat...
"Wacht maar tot je duikbots te diep gaan en verdwalen." "Haha, je duikbots hebben je spullen gebracht die op goud lijken, maar eigenlijk glimmende octopuskak zijn." Naarmate de duikbots prolifereren, zie je steeds meer horrorverhalen. Duikbots die verdwalen en vergeten wat ze zouden moeten bouwen. Duikbots die iets bouwen dat zo complex en grotesk is dat ze er moeite mee hebben het te onderhouden, om het vervolgens te laten weggooien door de volgende generatie duikbots. Alle onderwatermijnbouwoperaties veranderden van zorgvuldig ontworpen en gebouwde kathedralen in iets dat meer lijkt op willekeurige villa's, met verborgen gangen en sluimerende verschrikkingen. Hoe meer je losgekoppeld bent van de operatie, hoe spectaculairder de mislukkingen. Dit is het kamp van de Sceptici.
Hier wonen monsters
De software engineering-industrie (en ik vermoed dat veel andere industrieën dat snel zullen volgen) beleeft een versie van het bovenstaande scenario. Je weet waarschijnlijk al of Scepticus of Optimist jou beter beschrijft, zelfs als je er nog niet zeker van bent bij welk kamp je wilt horen.
De traditionele wijsheid is dat je een adequaat werkmodel van een systeem moet hebben om een niet-triviaal systeem te kunnen ontwikkelen en onderhouden. Ik denk dat weinig mensen daar tegenin zouden gaan. In software engineering zou je dat werkmodel verkrijgen door direct met de code te werken. Jaren en decennia van praktijk in het schrijven en lezen van code geven je de kennis en instrumenten die nodig zijn om de systemen waar je verantwoordelijk voor bent te begrijpen. Elk productie-incident, elke nachtelijke debugging-sessie, elke succesvolle release: al deze ervaringen geven je het perspectief dat nodig is om eigenaarschap over een systeem te hebben. In de context van dit artikel betekent eigenaarschap dat jij degene bent die wordt gebeld als er iets kapot gaat.
Agents (duikbots) zetten dit volledig op zijn kop. Duikbots produceren output veel sneller dan iemand kan absorberen. Waar je bij complexe systemen uit het verleden kon aannemen dat de code op een bepaald moment door de handen van een mens was gegaan, is dat niet langer waar. Het is nu mogelijk voor ervaren practitioners om vloten van duikbots te beheren en software op een ongekende schaal te creëren. Deze operators kennen het vak en brengen hun aanzienlijke ervaring in om grote systemen te beheren en te architectureren die in het verleden teams nodig zouden hebben gehad om te bouwen. Maar dat legt bloot wat waarschijnlijk de grootste uitdaging is voor onze industrie: hoe leiden we de volgende generatie engineers op?
Op hun extremen hebben de Optimisten en de Sceptici wild verschillende antwoorden op deze vraag. Aan de ene kant heb je gerespecteerde stemmen die zeggen dat de enige manier om controle over deze systemen te behouden, is door elke regel code die de duikbots produceren te lezen. In staat zijn om het met de hand te coderen. In staat zijn om uit te leggen wat elk stukje code doet en hoe het past in de context van de applicaties. In het andere kamp heb je evenzeer gerespecteerde stemmen die zeggen dat je niet eens de moeite hoeft te doen om naar de code te kijken. Focus je energie op het uitzoeken van wat er gebouwd moet worden en vergeet hoe het gebouwd wordt. De modellen regelen het wel. Ik denk dat geen van beide juist is.
Het feit is dat de manier waarop de senior engineers van vandaag hebben geleerd — namelijk door met de hand te coderen, eindeloze uren te debuggen, productie-incidenten, etc. — geen levensvatbaar pad is voor juniors vandaag. Om duidelijk te zijn: het is economisch niet levensvatbaar. Het is zeer onwaarschijnlijk dat bedrijven bereid zullen zijn om juniors jarenlang te sponsoren terwijl ze "leren het met de hand te doen". Dat is wensdenken. Een alternatief dat vaak wordt gepresenteerd, is het advies "zorg dat je elke regel die je agent schreef begrijpt", of "pair met een senior", of "voer zorgvuldige code reviews uit". Opnieuw: wensdenken voor bijna alle bedrijven. Als je denkt dat de industrie in het algemeen deze praktijken zal overnemen, dan heb ik een brug te verkopen.
Om een levensvatbaar pad naar een zekere mate van meesterschap te vinden, moeten we kijken naar wat het betekent om een niet-triviaal softwaresysteem te bezitten. Als je kijkt naar je typische architect/lead/CTO en hoe zij opereren, wordt duidelijk dat ze een model van het systeem in hun hoofd moeten hebben, een kaart van de wateren. De echte vraag is: op welk granulariteitsniveau? Stel je een legacy codebase van 1 miljoen regels voor, geschreven en uitgebreid over de jaren door een aantal mensen. De CTO heeft misschien zelfs delen ervan geschreven. Stel je nu voor dat er een productieprobleem is en jij bent de ongelukkige SRE die dit om 02:00 uur probeert op te lossen, terwijl je boze berichten krijgt van mensen in verschillende tijdzones. Welke kaart van het systeem heb je dan nodig? Je hebt een high-level, overzichtelijke kaart van het hele systeem nodig, en je moet precies genoeg weten om te weten waar je moet duiken, waar de monsters wonen, en je moet in staat zijn om in elke onbekende codebase te springen, uit te zoeken wat er gebeurt, een hotfix te pushen en duidelijk te beschrijven wat er is gebeurd in je incidentrapport.
Let op dat dit geen gedetailleerde kennis van het hele systeem is. De enige manier waarop we complexe systemen kunnen beheren, is door abstracties op te bouwen. Elke laag stelt ons in staat om iets meer te bouwen, maar welke kaart je ook hebt, het is belangrijk om te onthouden dat het abstracties zijn tot op de bodem, en niemand begrijpt echt alle lagen. Er is een groot verschil tussen "Ik heb module X geschreven en ken deze door en door" en "Ik heb een adequaat model van de systeemabstracties en kan in elke module duiken en deze repareren als hij kapot gaat". Coderen met de hand geeft ons het eerste, maar de eigenaar van een systeem, de persoon die wordt gebeld, heeft het laatste nodig.
Hoe wordt dit beeld dan opgebouwd? En hoe kan iemand worden verwacht in onbekende wateren te duiken en de puinhoop die de duikbots hebben gemaakt op te ruimen, als ze nooit met de hand goudklompjes hebben gewonnen?
Fundamenten, Breedte en Just-in-Time Diepgang
Sommige van de meest verraderlijke fouten in complexe systemen zijn stille fouten. Het soort waarbij dingen grotendeels werken, maar er iets niet klopt aan het systeem. Misschien is het plotseling trager, of zijn de foutmarges gestegen, of werkt het de meeste tijd perfect maar faalt het elke 19e poging. Niet tot het punt dat je om 02:00 uur wordt gewekt, maar genoeg om het gevoel te krijgen dat er iets mis is. Als eigenaar van een systeem moet je de faalmodi van het systeem begrijpen. Als industrie hebben we de instrumenten om mensen te leren hoe ze deze fouten kunnen detecteren en analyseren: fundamenten. En het goede nieuws is dat we dit al decennia lang onderwijzen aan onwetende CS-studenten. Ik heb het over datastructuren & algoritmen, netwerken, concurrency, gedistribueerde systemen, etc. Dit hoeft niet uit een formele opleiding te komen; dit zijn onderwerpen waar je over kunt lezen en die je zelfstandig kunt leren.
Om een simpel beeld te schetsen: stel je voor dat je je duikbot op een missie stuurt. Je bent in ondiep water en je stuurt hem 2 meter onder water om wat goudklompjes te verzamelen. Hij komt terug in 4 seconden en alles is goed. Daarna stuur je hem 4 meter diep. Dit keer duurt het echter 16 seconden. Dat is vreemd. De volgende missie is 16 meter diep, en het duurt 256 seconden. Je ziet het patroon. Er is overduidelijk iets mis. In de computerwetenschap zou dit kwadratische complexiteit worden genoemd, en de beste manier om dit te herkennen is door de theorie te begrijpen en te weten dat zo's iets bestaat.
Dit brengt me bij de volgende pijler van eigenaarschap: breedte. De meeste succesvolle engineers en engineering leaders met wie ik het genoegen heb gehad om te werken, waren in staat om een discussie te voeren over bijna elk onderwerp, of dat nu technisch was of niet. Ze waren misschien specialisten in bepaalde zaken, maar wat het meest indrukwekkend was, was hun vermogen om schijnbaar ongerelateerde concepten uit verschillende disciplines samen te weven en die kennis te gebruiken om problemen op te lossen. Dit is de high-level kaart van de wateren. Dit is wat je vertelt dat bepaalde zeeën gevaarlijker zijn dan andere. De breedte van de kennis is wat je in staat stelt om te zeggen: "laten we hier duiken". En om duidelijk te zijn, ik heb het niet over expert-niveau kennis in elk denkbaar domein, maar gewoon genoeg om te weten wat je moet opzoeken wanneer er iets niet klopt. De boeien die je oceaanexploratie begeleiden.
Iemand vroeg me: "hoe leren we breedte? een survey-cursus over alles?" en ik had op dat moment geen goed antwoord. Maar na er langer over na te hebben gedacht, lijkt het me dat dit niet iets is wat je kunt onderwijzen. Er is geen "Alles 101" cursus die je kunt volgen. Het meeste wat we kunnen doen is mensen aanmoedigen om te lezen/exploreren/nieuwsgierig te zijn. Absorbeer zoveel mogelijk informatie als je kunt. Onthoud de vreemde incidenten, de "oh nee"-momenten, en denk na over hoe ze verbonden zijn met je werk. En naarmate je meer ervaring opdoet, maak dan een bewuste inspanning om je dagelijkse ervaringen te verbinden met je werk. Ik ben het tellen kwijt van hoe vaak dat ene stukje kennis dat ik jaren geleden leerde tijdens het werken aan een willekeurig project, op het laatste moment de dag heeft gered. Deze ervaring en breedte stapelen zich op, maar ze moeten worden onderhouden.
De laatste pijler van eigenaarschap is wat ik "just-in-time diepgang" noem. Dit is het vermogen en de bereidheid om in elk probleem te duiken en het uit te zoeken. Zelfs als je in onbekende wateren bent. Zelfs als je in de kooi moet stappen en een tijdje met de haaien moet zwemmen. Zelfs als je je team moet verzamelen, de grote echte onderzeeboot moet laden en diep voorbij de reuzeninktvissen moet duiken om uit te zoeken wat er mis is met het systeem. Dit is de bereidheid om te leren wat er ook nodig is om de klus te klaren. Het is ook de nederigheid om te weten wanneer een duik buiten je vermogen ligt en je hulp moet zoeken. Niet elke duik kan solo worden gedaan; niet elke duik is de moeite waard.
Een paar maanden geleden, terwijl ik werkte aan mijn agent-orchestrator, liep ik tegen stabiliteitsproblemen en lifecycle-bugs aan met mijn agents en subagents. Ik wist wat ik van ze wilde, maar de duikbots die het ding hadden gebouwd, hadden dat nogal lukraak gedaan en alle bugs kwamen tegelijk naar boven. Terwijl ik naar mijn scherm staarde en mijn agents voor de n-de keer in een uur zag crashen, en na verschillende mislukte pogingen om de duikbots hun eigen puinhoop te laten opruimen, herinnerde ik me dat ik jaren geleden een boek over Kubernetes had gelezen (ja, ik ben een nerd) en de woorden "level-triggered state machine" staarden me plotseling aan. Dus ik maakte een duik, dieper dan ik oorspronkelijk van plan was, zelfs tot aan de elektrische engineering-oorsprong van "level-triggered". Ik nam mijn duikbots mee en herontwierp de kernarchitectuur vanaf de grond af aan. Sindsdien is het rotsvast. Deze succesvolle rewrite was hoofdzakelijk mogelijk omdat ik toevallig iets herinnerde wat ik jaren eerder had gelezen, en bereid was om diep te duiken en te leren wat er nodig was om de klus te klaren.
Je begint dus met een high-level kaart van de oceaan (het systeem), en begrijpt dat het lagen van abstracties zijn tot aan de bodem. En omdat al die abstracties lekken, is jouw baan als systeemeigenaar om te weten waar je moet duiken en hoe diep. Het gaat niet langer om generalist versus specialist, of zelfs de mythische T-shaped personen.
De nieuwe manier van bouwen vereist een generalist die diep in het onbekende kan duiken, een "snelle leerling onder druk" — en dan niet op de manier waarop dat in een opgepoetst cv staat. Je zult daadwerkelijk in staat moeten zijn om snel te leren terwijl je vecht met zeemonsters. Ik heb door de jaren heen veel mensen geïnterviewd en wanneer mensen "snelle leerling" in hun cv zetten, vraag ik hen graag om me te vertellen over een keer dat ze een complex systeem snel moesten leren; hoe deden ze dat? Wat zou jouw antwoord zijn?
De eigenaren van de toekomst
Fundamenten kunnen worden geleerd en breedte wordt verzameld. Just-in-time diepgang kan echter worden geoefend. Deze drie pijlers zijn wat iemand in staat stelt om hun aandeel in het eigenaarschap van een systeem te vergroten. Misschien begin je in ondiep water, stuur je je duikbots naar beneden. Je hebt solide fundamenten, een redelijke breedte, dus ga iets bouwen. Wees alleen bereid om het pak aan te trekken en met de monsters te zwemmen wanneer er iets kapot gaat.
Wie zal in de toekomst verantwoordelijk zijn voor de uitgestrekte onderwatermijnbouwoperaties? Niemand weet het, maar ik wed dat het die individuen zullen zijn die in staat zijn de drie bovenstaande pijlers te hanteren. Het zal het kind zijn dat een oude radio uit elkaar heeft gehaald en heeft gerepareerd, zonder het minste te weten van radio's, enkel uit een verlangen om naar muziek te luisteren — zelfs als ze uiteindelijk met een paar extra schroefjes bleven zitten na het in elkaar zetten.
Groetjes,