In sommige van mijn projecten gaan er miljoenen tokens naar gesprekken, onderzoek, analyse en documentatie voordat er één regel productiecode wordt geschreven. Van buitenaf kan dat overdreven lijken. Als AI zo snel software kan genereren, waarom leg je het idee dan niet gewoon uit en laat je het bouwen?
Omdat de kwaliteit van AI-ondersteunde softwareontwikkeling allang bepaald is voordat de eerste regel code verschijnt. Voordat ik de snelheid van ontwikkelen opvoer, wil ik weten wat er gebouwd moet worden, wat niet mag veranderen, welke standaarden het project moet volgen, en hoe we straks vaststellen of het resultaat daadwerkelijk klopt.
Ik gebruik ChatGPT en modellen zoals Astra tijdens onderzoek, systeemontwerp, implementatie, testen en verfijning. Mijn proces begint niet met "bouw deze applicatie voor mij." Het begint met het vastleggen van de omgeving waarin AI mag bouwen: codeerstandaarden, schrijfstandaarden, regels voor infrastructuurstabiliteit, UI- en UX-principes, SEO-werkwijzen, Git-conventies, teststandaarden, herbruikbare skills, projectgrenzen en beslisregels. Pas daarna bepalen we het eigenlijke product. AI doet een groot deel van het werk. De verantwoordelijkheid voor het resultaat blijft van mij.
Ik ontwerp het ontwikkelproces vóór ik het product ontwerp
Mijn achtergrond ligt in de civiele techniek, en dat kleurt hoe ik naar software kijk. Voordat je iets bouwt, moet je weten wat de constructie moet dragen, welke beperkingen er gelden en waar een storing het meest waarschijnlijk optreedt. Zo benader ik software ook: een scherm dat er goed uitziet, of een functie die lijkt te werken, is niet genoeg. Ik wil weten hoe de data wordt opgeslagen, wat er gebeurt als een ander onderdeel van het systeem verandert, en welke delen stabiel moeten blijven terwijl een functie wordt aangepast.
Daarom splits ik het werk in twee lagen. De eerste laag bepaalt hoe we bouwen: codeerconventies, documentatieregels, UI- en UX-standaarden, testverwachtingen, regels voor infrastructuurstabiliteit, Git- en wijzigingsbeheer, SEO-onderzoeksprocessen, AI-bevoegdheden en -beperkingen, en herbruikbare skills voor terugkerende workflows. De tweede laag is projectspecifiek: het bedrijfsprobleem, de gebruikers, functionele eisen, grenzen, beperkingen, datamodellen, acceptatiecriteria en architectuurkeuzes.
Herbruikbare standaarden voorkomen dat we het ontwikkelproces bij elk project opnieuw uitvinden. Projectspecifieke keuzes voorkomen dat we dezelfde oplossing op elk probleem plakken. Deze werkwijze, en mijn eigen achtergrond, staan verder uitgewerkt op Sina Esfahani — over de oprichter.
"Schrijf goede code" is geen standaard
Een veelvoorkomende zwakte in AI-ondersteunde ontwikkeling is een vage instructie: "schrijf schone code," "volg best practices," "maak het schaalbaar." Dat klinkt redelijk, maar is niet precies genoeg om AI-gegenereerd werk consequent te sturen. Een bruikbare standaard moet specifiek genoeg zijn om het resultaat er later tegen af te zetten: scheiding van verantwoordelijkheden, verwachtingen rond foutafhandeling, afhankelijkheidsregels, acceptabele complexiteit, modulegrenzen, achterwaartse compatibiliteit en de voorwaarden waaronder refactoren is toegestaan. Code die vandaag werkt maar morgen de halve applicatie laat herschrijven voor een kleine functie, is voor mij geen goede code.
Documentatie volgt hetzelfde principe. Ik wil geen documentatie die herhaalt wat de code al zegt. Goede documentatie legt de redenering vast: waarom deze architectuur, welke aannames zijn gedaan, welke alternatieven zijn overwogen en wat nog onzeker is. Die uitleg wordt belangrijker zodra AI meedoet, omdat AI veel sneller code genereert dan een mens een mentaal model van het systeem kan opbouwen.
Stabiliteit van de infrastructuur heeft eigen regels nodig
AI-modellen zijn vaak erg bereid om dingen te verbeteren — soms te bereid. Vraag om een kleine functie en het model reorganiseert misschien een map, vervangt een dependency, herschrijft een component of moderniseert een deel van de architectuur. Sommige van die wijzigingen zijn misschien zelfs verbeteringen, maar verbetering is niet het enige doel; stabiliteit telt ook mee. Een verzoek om een functie aan te passen is geen automatische vrijbrief om het hele systeem opnieuw te ontwerpen. Wijzigingen aan deploymentconfiguratie, kernafhankelijkheden, API's, datacontracten, authenticatielogica of projectstructuur hebben een duidelijke reden nodig. "Dit is nieuwer" is niet genoeg, en "deze architectuur is schoner" is dat ook niet per se. De echte vraag is of de wijziging het project genoeg verbetert om het extra risico en de extra complexiteit te rechtvaardigen.
UI-, UX- en teststandaarden gaan over gedrag, niet alleen over uiterlijk
Interfacestandaarden moeten niet stoppen bij kleur, ruimte, lettertypes en componenten. Een goede interface is ook gedrag: wat gebeurt er tijdens het laden van data, wat ziet een gebruiker als er nog niets bestaat, wat gebeurt er na een geslaagde of mislukte actie, en blijft de workflow logisch op mobiel. Dat zijn geen vragen die je pas aan het einde stelt — ze horen bij wat "af" betekent.
Teststandaarden werken hetzelfde. Correct gedrag moet vóór de code worden gedefinieerd, niet erna: wat moet werken, wat moet veilig falen, welke edge cases en faalcondities ertoe doen. Tests schrijven is niet hetzelfde als tests uitvoeren, en een geslaagde testset bewijst alleen dat de geteste scenario's slagen — nooit dat de vergeten scenario's kloppen. Als een test faalt, is de juiste reactie om te begrijpen waarom, niet om de test af te zwakken of te verwijderen zodat de build weer groen wordt.
Een skill is een herbruikbare procedure, geen vage prompt
Een van de belangrijkste onderdelen van mijn werkwijze is het vastleggen van herbruikbare skills — geen vage prompt zoals "je bent een SEO-expert," maar iets dat meer op een procedure lijkt: wanneer moet hij starten, welke informatie heeft hij nodig, welke tools mag hij gebruiken, welke controles moet hij uitvoeren, wat moet de output bevatten, en wat mag AI niet aannemen. Ik wil niet dat de kwaliteit afhangt van of ik toevallig eerder in een gesprek de juiste instructie heb genoemd. Belangrijke standaarden en gevalideerde keuzes moeten in blijvende projectbronnen staan waar AI op kan terugvallen, en de output moet er achteraf nog steeds tegen worden afgezet — een standaard die alleen in een document bestaat maar nooit een keuze beïnvloedt, is gewoon een ongebruikt bestand.
SEO is daar een goed voorbeeld van. Ik maak niet eerst pagina's aan om me achteraf af te vragen waarop ze moeten scoren. Voordat een contentstructuur wordt voorgesteld of tekst wordt geschreven, moet AI controleren of er genoeg bewijs is over zoekwoorden, intentie en zoekvolume voor de markt en taal in kwestie. Zo niet, dan moet AI dat bewijs verzamelen in plaats van een strategie te verzinnen of een aanname als gemeten data te presenteren. Dat onderzoek wordt een herbruikbaar naslagwerk waar latere content op terugvalt, geen eenmalige exercitie die voor elke pagina wordt herhaald. En zoekwoordenonderzoek mag nooit keyword stuffing worden: het gaat om begrijpen wat een lezer eigenlijk wil bereiken, niet om tellen hoeveel termen er op een pagina passen.
Onderzoek moet uitmonden in beslissingen, niet eindeloos doorgaan
Tegen de tijd dat de implementatie begint, is er vaak al enorm veel AI-werk verzet — bij grote projecten kunnen alleen al het onderzoek en de documentatie in de miljoenen tokens lopen. Maar het aantal tokens is geen kwaliteitsmaatstaf, en ik besteed ze niet zomaar omdat meer analyse grondig oogt. Het doel is het wegnemen van betekenisvolle onzekerheid, niet perfecte kennis. Wat bouwen we, voor wie, op welke architectuur, met welk risico, en welke aannames moeten nog worden gevalideerd? Zodra dat voldoende beantwoord is, moet de implementatie beginnen.
Hier wordt scope ook eerlijk vastgesteld. Scope is niet alleen een lijst van functies die gebouwd moeten worden — het is ook een lijst van dingen die nog niet gebouwd moeten worden. Een functie kan nuttig zijn en toch niet in de huidige versie thuishoren. Dat iets gebouwd kán worden, is op zichzelf nooit een reden om het te bouwen. En acceptatiecriteria moeten er zijn vóór de implementatie, niet erna: wat gebeurt er bij een dubbele indiening, een mislukte netwerkoproep, een ontbrekend veld, een mislukte autorisatie. Als die vragen pas worden beantwoord nadat de code al bestaat, maakt AI aannames — soms terecht, soms stilletjes verkeerd, en in beide gevallen door niemand in het bijzonder besloten.
Het probleem kiest de technologie, en de database is een menselijke keuze
Het is makkelijk om gehecht te raken aan tools, en AI-modellen vertonen dezelfde neiging omdat bepaalde patronen veel voorkomen in hun trainingsdata. Ik begin liever bij wat het systeem daadwerkelijk moet doen, hoe vaak het verandert en wie het onderhoudt — en kies pas dan de technische structuur. Soms is het juiste antwoord geavanceerd. Vaak is het extreem eenvoudig. Complexiteit moet verdiend worden.
Databaseontwerp krijgt van mij extra voorzichtigheid. AI is hier echt nuttig: het kan structuren voorstellen, relaties herkennen, edge cases benoemen en vragen stellen die iemand anders vergeten was. Maar een mens moet de bedrijfsrealiteit inbrengen — wat gebeurt er met een historische bestelling als het adres van een klant verandert, moeten records verdwijnen of geanonimiseerd worden bij accountverwijdering, welke wijzigingen moeten auditeerbaar blijven. Dat zijn bedrijfsbeslissingen vóór het databasebeslissingen zijn, en het terugdraaien van een destructieve migratie is fundamenteel iets anders dan het terugdraaien van applicatiecode — nog een reden waarom schemawijzigingen hun eigen niveau van controle verdienen.
Nadat de tests slagen, lees ik de code regel voor regel
Zodra implementatie en geautomatiseerd testen klaar zijn, lees ik de gegenereerde code zelf, regel voor regel — niet alleen op zoek naar syntaxfouten, maar met vragen als: waarom bestaat deze conditie, waar komt deze waarde vandaan, wat gebeurt er als deze functie faalt, en zou ik dit over zes maanden nog begrijpen. Soms haal ik AI er tijdens de review weer bij, om de implementatie te bekritiseren of edge cases te zoeken, maar AI die AI beoordeelt, maakt menselijk oordeel niet overbodig: een overtuigende uitleg is geen bewijs, en de code moet nog steeds kloppen met de eis, de architectuur en het gedrag dat we in de praktijk verwachten. Als ik de code moet onderhouden, moet ik hem zelf kunnen begrijpen, uitleggen en aanpassen.
De grootste waarde van AI in mijn proces is niet dat het sneller typt dan ik. Het is dat ik meer mogelijkheden kan onderzoeken: sneller research doen, aanpakken vergelijken, aannames uitdagen, edge cases vinden en grote codebases doorzoeken. Dat is een echte productiviteitswinst — maar die wordt pas echt waardevol binnen een gedisciplineerd systeem, want zonder dat systeem genereert AI net zo efficiënt complexiteit, technische schuld en verkeerde aannames als werkende functies.
Ik denk dus niet dat de toekomst van softwareontwikkeling is: "vertel AI wat je wilt en laat het alles bouwen." Ik denk dat het bruikbaardere model is om een technische omgeving te ontwerpen waarin AI effectief kan werken, en het daarbinnen steeds meer autonomie te geven: standaarden vóór het coderen, onderzoek dat herbruikbare projectkennis wordt, aannames die expliciet worden gemaakt, kritieke datastructuren die samen worden ontworpen, gedrag dat wordt getest tegen een vooraf afgesproken definitie, de scope van elke wijziging onder controle, wat al werkt dat behouden blijft, en het resultaat dat nog steeds met menselijk oordeel wordt beoordeeld.
Dat garandeert geen foutloze software, voorkomt niet dat eisen veranderen en neemt onzekerheid niet weg. Het zorgt er wel voor dat keuzes makkelijker te begrijpen zijn, wijzigingen makkelijker te controleren zijn en fouten eerder opvallen voordat ze diep in het product verankerd raken. Voor mij is een project niet af zodra AI stopt met het genereren van code. Het is af zodra het resultaat aan de eis voldoet, de belangrijke aannames gecontroleerd zijn, en ik de verantwoordelijkheid voor wat we gebouwd hebben op me durf te nemen — dezelfde maatstaf die ik aanhoud bij maatwerksoftware bij OmniTechs, en bij het bredere proces achter het bouwen van een AI-agent.
Ik gebruik AI om sneller te bouwen. Ik gebruik technische discipline om te zorgen dat we het juiste bouwen. Hoe ik leerde om modellen in echte systemen te zetten — API’s, geheugen, latentie en falen — staat in Ik bouwde al rond AI voordat AI er klaar voor was.
