Waarom AI-code alsnog nagekeken moet worden.
5 min lezenBijgewerkt
Code laten schrijven door AI gaat verbazend goed. Je beschrijft wat je wilt, er komt iets terug, en het werkt.
Precies daar begint het gedoe. Werkend is niet hetzelfde als juist, en het verschil zie je niet aan de code. Je ziet het pas als iemand iets doet wat jij in je voorbeeld niet bedacht had.
Wat er goed aan is
Ik laat AI meeschrijven aan code en ga er niet omheen draaien: het scheelt uren. Een formulier met validatie, een script dat bestanden hernoemt, een tabel die sorteert en filtert, de zoveelste variant op iets dat ik al eerder bouwde.
Voor werk waarvan ik precies weet hoe het eruit moet zien is het sneller dan zelf typen. En het is een bruikbare sparringpartner: "wat gaat hier stuk?" levert soms een geval op dat ik niet had bedacht.
Waar het misgaat
Het gewone geval gaat meestal goed, want dat is het geval dat in je vraag stond. De fouten zitten aan de randen, en het zijn er vier die ik steeds opnieuw controleer.
- Het lege geval. Nul resultaten, een lijst zonder items, een meting die niet gedraaid heeft. De code toont "0 fouten" waar hij had moeten zeggen dat er niets gemeten is. Dat lijkt hetzelfde en is het tegenovergestelde. In het beheer van deze site heeft daarom elke uitkomst drie standen: in orde, aandacht nodig, en niet vast te stellen. Een kaart die groen staat omdat de meting stilstaat vertelt iets onwaars op precies het moment dat er iets mis is.
- Twee dingen tegelijk. Twee mensen die op hetzelfde moment op verzenden drukken. Een model schrijft lezen-wijzigen-schrijven zonder erbij na te denken, en dan verlies je er een. Het contactlogboek van deze site bewaart daarom elk bericht als eigen record en niet als lijst: een lijst vraagt om lezen, aanpassen en terugschrijven, en bij twee aanvragen tegelijk raak je er één kwijt.
- Rechten. Een lijst ophalen zonder te controleren wie hem opvraagt. Dat werkt perfect zolang jij de enige gebruiker bent. Bij ProjectControl, de webapp die bij een bedrijf in gebruik is, draaien bij elke wijziging testreeksen op rechten en rollen, onder meer of een medewerker niet bij personeelsgegevens komt, ook niet via de URL. Dat is het soort test dat een model zelden uit zichzelf schrijft, omdat het alleen iets bewijst wanneer het mislukt.
- Wat er gebeurt als het misgaat. Een fout die wordt weggeslikt zodat er niets rood wordt. Dat is de gevaarlijkste, want stille storingen vind je maanden later. Bij het wegschrijven van sitescans zit er daarom een regel in de serverlog als dat schrijven mislukt, ook al krijgt de bezoeker er niets van te zien.
Wat deze vier gemeen hebben: alles doet het als je het uitprobeert. Je moet ze zoeken.
Waarom een model dit niet zelf ziet
Het weet niet wat jouw systeem moet betekenen. Het kent het patroon van code die op jouw vraag lijkt, en dat is iets anders dan begrijpen wat er in jouw geval waar moet zijn.
Een model kan feilloos code schrijven die precies doet wat je vroeg, terwijl je iets anders bedoelde.
Daarom helpt het als vastligt wat een status betekent, wie wat mag zien en wat er niet tegelijk waar kan zijn. Dat is het werk van het datamodel. Met die afspraken op papier is code die ervan afwijkt zichtbaar fout. Zonder is elke variant even plausibel.
Wat ik doe voordat het live gaat
Ik lees het, ook de stukken die er saai uitzien, want daar zitten de randgevallen.
Verder: een test op het lege geval en op het dubbele geval, niet alleen op het voorbeeld uit de vraag. Een blik op wat er gebeurt als de externe dienst niet antwoordt. En de vraag of ik dit over een half jaar nog begrijp, want onderhoud houdt niet op en dan is er niemand die de oorspronkelijke prompt nog heeft.
Code opleveren die ik zelf niet snap doe ik niet. Niet uit principe, maar omdat ik hem dan ook niet kan repareren op de dag dat een klant belt.
Als het model zelf iets doet
Alles hierboven gaat over code die een model schrijft en een mens daarna leest. Het wordt een andere vraag zodra het model niet meer alleen schrijft, maar in de toepassing zelf een stap zet.
Een model dat een concept-antwoord klaarzet dat iemand nog goedkeurt: prima. Een model dat de mail zelf verstuurt, de factuur zelf goedkeurt of de aanvraag zelf afwijst: daar wordt het iets anders. Niet omdat het niet kan, maar omdat de fout dan niemand meer passeert.
Een rekenvoorbeeld maakt duidelijk waarom. Stel dat een model in 95 van de 100 gevallen goed zit. Dat klinkt uitstekend. Zet het op een handeling die honderd keer per dag gebeurt, en je hebt vijf fouten per dag. Elke dag. Zonder dat iemand ze ziet, want ze zien er precies zo uit als de andere vijfennegentig.
Vergelijk dat met een gewone berekening. Een btw-optelling zit er nul keer naast, ook op de honderdduizendste regel. Waar een deterministische functie volstaat, is een taalmodel niet vooruitstrevend maar onbetrouwbaar.
Komt er toch een model in zo'n keten, dan zou ik het zo inrichten: een goedkeurstap bij alles wat naar buiten gaat, alles wat onomkeerbaar is langs een mens, en een antwoord dat niet klopt van vorm naar een wachtrij in plaats van door. Voorstellen mag automatisch, versturen niet.
Wanneer minder nakijken genoeg is
Niet alles verdient dezelfde aandacht. Een script dat ik eenmalig draai op een kopie van mijn eigen bestanden lees ik vluchtig en controleer ik aan de uitkomst. Daar is de schade van een fout klein en meteen zichtbaar.
Hoe meer mensen er op rekenen, hoe meer er aan de randen hangt. Een formulier dat aanvragen binnenhaalt, een scherm met rechten, een koppeling met een betaaldienst: daar kost een gemiste rand een klant of een lek, en daar is nakijken het eigenlijke werk. Hoe ik dat voor een eigen webapp aanpak, staat bij wat ik bouw voor webapps. Waar ik zelf de grens trek bij AI in mijn eigen teksten, staat in Ik gebruik AI om te schrijven.
De vraag die daarbij helpt: als dit een keer fout gaat, wie merkt het dan, en hoe lang duurt dat? Kun je die twee niet beantwoorden, dan is het te vroeg om het zonder controle te laten draaien.
Het antwoord is dus geen "altijd alles nalopen" en ook geen "het model zal het wel weten". Je kijkt het meest waar een fout het duurst is en het minst zichtbaar.