Waarom je AI-code in Dev wél werkt en in Productie breekt
Waarom je AI-code 's nachts om 3 uur in de fik kan vliegen
Iedereen die weleens met vibe coding heeft gewerkt, kent dat moment: je typt wat je wilt, de AI bouwt het, de tests groenen, en je shipped. Het voelt bijna magisch.
Tot het dat niet meer doet.
Meestal gebeurt dat om een ongelegen moment. Je app draait prima tijdens het testen, verwerkt zelfs een paar honderd requests zonder te klagen, en dan — knal —OOM killer. Of je server die opeens tienduizenden file descriptors opent en crashh. Of dat ene moment waarop echte gebruikers arriveren en je applicatie smelt als sneeuw voor de zon.
Het gekke? De code was correct. De logica klopte. Het loste precies op wat je had gevraagd. Alleen ging de code ergens stilzwijgend van uit: oneindig veel geheugen, oneindig veel resources, want dat had niemand ooit tegengesproken.
De onzichtbare grenzen die niemand benoemt
Dit is het vervelende aspect van vibe coding waar we op conferenties nauwelijks over praten. Wanneer je zelf code schrijft, draag je automatisch een mentaal model van alle beperkingen met je mee. Je weet dat je op een laptop met 16GB RAM draait. Je kent de limieten van je productieserver. Je beseft dat die 400GB CSV niet zomaar in het geheugen past.
Maar als een AI je code schrijft? Die constraints bestaan niet. De AI leest "laad het bestand, sorteer het, schrijf het resultaat" en denkt: oké, ik laad het hele bestand. En dat werkt perfect. Tijdens het testen. Waar het testbestand 50KB was.
Zelfs code reviews pikken dit niet op. De verdachte regels zien er volkomen redelijk uit. Niets dat een alarmbel doet rinkelen, want er zijn geen logische fouten. De bug zit niet ín de logica — de bug zit in de onzichtbare doos waar de logica in ontworpen is.
En als de compiler nu eens mee kon kijken?
Hier wordt het spannend. Er wordt geëxperimenteerd met een radicaal idee: wat als resource-beperkingen geen备注 waren, maar types?
Stel je voor dat je niet hoeft te hopen dat AI-gegenereerde code netjes omgaat met geheugen. Wat als de compiler letterlijk weigert om code te compileren die de limieten overschrijdt? Wat als "deze functie houdt nooit meer dan 100 records in het geheugen" geen wens was, maar een feit dat de compiler kan verifiëren?
Dit is geen abstracte gedachte-oefening. Het experiment gebruikt Lean 4 — dezelfde Lean die furore maakt in de formele wiskunde — om resource-budgetten direct in functietypes te coderen. De compiler wordt een resource-auditor die automatisch controleert of je code binnen de grenzen blijft, nog voordat er ook maar iets draait.
Resources als bouwsteen van het type-systeem
De kern van deze aanpak is verrassend elegant: je weeft resource-tellers door het hele type-systeem. In plaats van bij te houden "hoeveel bestanden zijn open" als een runtime variabele die misschien wordt genegeerd, volgt het type-systeem het als een verplicht parameter die moet kloppen.
Open je een bestand? Je type-signatuur verandert mee: je komt de functie binnen met N bestanden open en vertrekt met N+1. Sluit je het? Dan ga je van N+1 terug naar N. De compiler volgt dit bij elke stap, en je kunt letterlijk geen code compileren die een bestand opent zonder het te sluiten, of die het aantal open bestanden boven een bepaald maximum laat komen.
Geheugen werkt vergelijkbaar, maar dan met een draai. Records zweven niet vrij in het geheugen — ze leven in een begrensde pool met een vast aantal plekken. Je houdt geen Event-object vast; je houdt een referentie naar die pool. Het type telt hoeveel levende referenties er op elk moment zijn, en allocatie vereist bewijs dat er plek is.
Het mooie zit hem in het startpunt: je programma moet beginnen met nul resources in gebruik en eindigen met nul. Je kunt geen handles lekken. Je kunt caps niet overschrijden. De compiler staat het simpelweg niet toe.
Waarom dit uitmaakt voor vibe coding
Deze aanpak verandert hoe we nadenken over het aanspreken van AI-assistenten. Tegenwoordig voeg je misschien een vage notitie toe als "pas op met geheugengebruik" of "sluit alle file handles" — in de hoop dat de AI erop let. Met resourcebewuste types specificieer je constraints formeel, en de implementatie moet zich herschikken om eraan te voldoen.
De AI krijgt eerst de ongeconstrained versie. Tests slagen. Dan schakel je de limieten in. De compiler wijst de implementatie direct af. De AI moet haar aanpak herstructureren — misschien door het bestand in chunks te verwerken in plaats van alles in één keer te laden, of door een connection pool te gebruiken in plaats van bestanden direct te openen.
De implementatie werkt niet zomaar toevallig — het bewezen werkt binnen het budget.
De praktische realiteit
Laten we eerlijk zijn: dit is nog geen productieklare tooling voor de meeste teams. De Lean 4-aanpak vraagt om flinke setup, en er zit overhead in het denken in geïndexeerde types. Maar de onderliggende insight is waardevol, ongeacht de implementatie.
Bij vibe coding draag je niet alleen het codeerschrijven uit, maar ook het mentale model van je systeem. Je AI-assistent kent je productieomgeving niet. Die weet niet dat je container 512MB RAM heeft. Die weet niet dat je Linux-kernel file descriptors beperkt tot 1024.
Totdat we betere manieren hebben om deze constraints te coderen, zijn er een paar praktische opties:
Wees specifiek in je prompts — "Het inputbestand kan tot 10 miljoen rijen bevatten" werkt beter dan "ga efficiënt om met grote bestanden"
Test met productie-schaal data — Als je trainingsdata miniem is, leert je AI geen resource-patronen
Gebruik begrensde API's — Architectuur die resourcegebruik natuurlijk beperkt (connection pools, streaming in plaats van laden) is moeilijker om verkeerd te gebruiken
Houd resource-bewuste tooling in de gaten — De industrie begint manieren te verkennen om constraints expliciet te maken in AI-gegenereerde code
De conclusie
Het vuile geheim van vibe coding is niet dat het bugs schrijft — het schrijft code die correct is binnen een onzichtbare constraint-ruimte. Die ruimte omvat toevallig je laptop, je testomgeving, en misschien je eerste duizend gebruikers. Hij omvat beslist niet "productie op schaal."
Resource-bewuste type-systemen, zoals dit Lean 4-experiment, wijzen naar een toekomst waarin "correct" meer betekent dan "logisch kloppend." Het betekent "bewezen binnen de grenzen die er daadwerkelijk toe doen."
Dat is een toekomst om naartoe te bouwen. Tot die tijd: houd je testdata dicht bij productie-grootte, en voeg misschien een extra notitie toe in je prompts over die file descriptor-limieten.
Je toekomstige on-call zelf zal je dankbaar zijn.