
Architectuur voor AI: hoe voorkom je ontspoorde code
We moeten het hebben over de "illusie van snelheid" in het tijdperk van AI.
In een tijd waarin elke post op LinkedIn lijkt te tonen dat al je concurrenten de overstap maken van traditioneel coderen naar 100% agentische softwareontwikkeling met AI, ligt de realiteit iets complexer. Hoewel AI-demo's en PoC's indrukwekkende eerste resultaten kunnen opleveren, is het inbedden van agentische softwareontwikkeling met AI in een langetermijnlevenscyclus van applicaties, met productieklare vereisten, nog altijd een heel ander spel.
Bij ACA vertrekken we vanuit het definiëren en meten van onze kwaliteitsnormen en doelstellingen, structuren, controles en guardrails. Vervolgens kunnen we, terwijl we agentische AI-capaciteiten toevoegen, de uitkomsten op een feitelijke en continu gemonitorde manier verifiëren en beheersen. Als onze AI-opzet ons helpt om binnen die grenzen te versnellen, is dat geweldig. Maar als AI onze guardrails raakt, merken we dat onmiddellijk en sturen we meteen bij.
Vandaag levert agentische softwareontwikkeling met AI ons daardoor efficiëntiewinsten op van 20 tot 50% ten opzichte van traditioneel coderen. En dat terwijl we onze kwaliteitsnormen op het vlak van performantie, veiligheid en onderhoudbaarheid behouden.
In dit artikel van Stijn Huygh gaan we dieper in op hoe we dat realiseren.

Waarom snel ogende AI-output in stilte de softwarekwaliteit kan ondermijnen
Elke ontwikkelaar heeft de eerste rush ervaren van werken met een coderende LLM. Je vraagt om een feature en seconden later heb je code. Die compileert, draait en ziet er grotendeels correct uit.
Maar snelheid kan bedrieglijk zijn.
Het grootste risico van AI-ondersteunde ontwikkeling is niet dat de code zal falen. Het is dat ze werkt terwijl ze in stilte je architectuur aantast. Zonder guardrails volgt AI je engineeringcultuur niet. Ze volgt het statistische gemiddelde van het internet. Dat is zelden wat je wilt in een productieklaar systeem.
Als je het systeem niet beheerst, beheers je de output niet.
Daarom is het belangrijk om een softwareontwikkelingslevenscyclus te ontwerpen die focust op het behouden van de integriteit van je codebase. Je wilt dat het eindresultaat performant, veilig en absoluut onderhoudbaar is.
Het echte probleem: door AI veroorzaakte technische schuld
AI begrijpt je architectuur niet; ze leest code, voorspelt patronen en geeft weer wat statistisch gezien het meest waarschijnlijke antwoord is.
Dat wordt een probleem wanneer je systeem steunt op een doordachte structuur. Het model kent je architecturale beslissingen of de redenering erachter niet. Het probeert gewoon zo goed mogelijk werkende code te genereren binnen de instructies die het krijgt.
Het resultaat is code die technisch werkt, maar langzaam wegdrijft van de architectuur die jij ontworpen hebt.
Die afwijking toont zich vaak op subtiele manieren:
- ongebruikte methodes
- hardcoded strings
- code importeren over logische grenzen heen
- DTO's die doorlekken naar de UI
- logica die compileert maar je regels schendt
Geen van deze problemen breekt de applicatie meteen. De code draait en de feature werkt, maar na verloop van tijd stapelen deze kleine afwijkingen zich op. Technische schuld die door AI wordt geïntroduceerd, kan sneller groeien dan menselijke code review realistisch kan bijbenen. En daar begint het echte probleem.
Dus hebben we de aanpak veranderd. In plaats van met AI te chatten, zijn we de beperkingen eromheen gaan engineeren.

Het framework voor AI-engineering met hoge integriteit
1. Dwing architectuur fysiek af, niet alleen in documentatie
De allereerste stap om de kwaliteit van de codebase te verbeteren, zelfs zonder AI te gebruiken om code te genereren, is bepalen hoe je wilt dat je project gestructureerd wordt. Het doel is om consistentie af te dwingen binnen je project, maar ook over al je andere projecten heen. Wanneer een ontwikkelaar de codebase opent, moet die op basis van je conventies meteen kunnen weten waar alles zich bevindt. Bepaal je applicatiearchitectuur!
De meest voorkomende fout die teams maken is vertrouwen op PDF-documentatie of een wikipagina om architectuur af te dwingen. AI (en mensen) zullen vergeten dat er een standaard is en die gewoon negeren. Het wordt een stuk makkelijker om een hoogwaardige codebase te onderhouden wanneer je architectuur ook in code wordt afgedwongen en niet alleen in documentatie.
Een van de manieren waarop wij dit afdwingen, is door onze gelaagde architectuur op te splitsen in verschillende projecten/packages. Als code niet blootgesteld wordt aan een andere laag, of de laag waarin je zit geen toegang heeft tot een specifiek package, dan zal die code niet gebruikt worden door die laag.
Zie mappen als geschilderde lijnen op een weg: het zijn suggesties waar je per ongeluk gemakkelijk overheen rijdt. Aparte projecten (of packages) zijn betonnen muren. Door je lagen te structureren als afzonderlijke packages met pubspec.YAML-regels voorkomen fysiek dat AI-code uit de verkeerde laag importeert.
Als AI probeert om de API-laag rechtstreeks in de UI te importeren, dan blokkeert de compiler dat onmiddellijk, niet een menselijke reviewer.
Onze gelaagde architectuur ziet er zo uit:
- _p4_ui: Puur presentatief. Geen businesslogica toegestaan, MVVM-patroon.
- _p3_application: Orkestreert use cases. Genereert nooit exceptions. Geeft Response-objecten terug.
- _p2_data: Beheert DTO's. Regel: DTO's verlaten deze laag nooit; ze worden onmiddellijk gemapt naar het domein. DTO's lekken dus nooit door naar andere lagen.
- _p1_domain: Pure businesslogica.
p0*: Gedeelde fundamenten zoals DI, vertalingen, utilities, en design system.
Als iets de architectuur schendt, markeert de compiler het. Dat haalt ambiguïteit weg en vermindert discussies tijdens code review.
2. Definieer strikte codeerstandaarden en dwing ze af
Je applicatiearchitectuur moet ook verrijkt worden met codeerstandaarden om kwaliteit en consistentie verder te verbeteren. Enkele voorbeelden van codestandaarden die wij afdwingen:
Benaming
- Interfaces beginnen met I
- Services eindigen op Service
- DTO's eindigen op Dto
- Enums beginnen met E
Complexiteitslimieten
- Maximaal 3 geneste if-statements
- Maximaal 75 lijnen per file
- Maximaal 500 lijnen per file
Volledigheid
- Alle switch cases afgehandeld
- Geen gebruik van dynamic
Regel voor de applicatie laag
- Geen exceptions. Alleen Response-objecten.
Volgorde
- Properties, fields, constructor, public en private functions staan altijd in een specifieke volgorde in je klasse.
De meeste van deze regels worden afgedwongen via linters en statische analyse. Het gaat hier niet om strengheid omwille van de strengheid. Het gaat om voorspelbaarheid. Wanneer de structuur voorspelbaar is, vallen afwijkingen meteen op.
3. Gebruik een mechanisch stappenplan
Een les die we snel geleerd hebben: laat een LLM nooit je boilerplate genereren. Het wordt dan "creatief" met bestandsnamen en mapstructuren, wat leidt tot een rommelige projectboom.
Wij gebruiken "domme tools" voor structuur zodat de "slimme tools" (AI) zich op logica kunnen focussen. Tools zoals Mason laten je deterministische templates genereren met behulp van het Mustache-templatesysteem. Een commando zoals “mason make viewmodel” creëert in enkele seconden de perfecte mapstructuur, bestandsnamen en klassedefinities. De view, viewmodel, interfaces en services worden allemaal aangemaakt met exact onze projectstructuur en codeerrichtlijnen in gedachten.
De strategie: wanneer je AI integreert, vraag haar dan niet om "het bestand te schrijven". Geef AI in plaats daarvan toegang tot je CLI via het Model Context Protocol (MCP) of rechtstreeks via de terminal. AI wordt dan de operator van je scaffoldingtools en voert het mason-commando uit om 100% consistentie te garanderen nog voor ze één enkele lijn logica schrijft.

4. Structureer documentatie voor AI: het drielagig documentatiesysteem
"Generieke trainingsdata produceren generieke code." Als je wilt dat AI code schrijft die eruitziet alsof ze door jouw team is geschreven, moet je de juiste context aanreiken.
Wij gebruiken een drielagig documentatiesysteem om het contextvenster efficiënt te voeden.
Laag 1: golden rules (altijd aan)
Een lichtgewicht bestand met niet-onderhandelbare regels. Bijvoorbeeld:
- De Application-laag gooit nooit exceptions.
- DTO's verlaten de datalaag nooit.
- Nieuwe views worden gegenereerd via de goedgekeurde scaffoldingtools.
Laag 2: Architecture deep dive
Referentiedocumenten die uitleggen:
- Verantwoordelijkheden van lagen
- Testingpatronen
- Gebruik van het design system
- Codeerrichtlijnen
Laag 3: Workflows en instructies voor agents
Stap-voor-stapinstructies over hoe AI-agents moeten werken. Duidelijke documentatie vermindert ambiguïteit. Minder ambiguïteit leidt tot consistentere output.
5. De Agentic Workflow: verdeel het denkwerk
De grootste sprong in kwaliteit komt voort uit het loslaten van één enkel chatvenster ten gunste van gespecialiseerde AI-agents. Die scheiding van verantwoordelijkheden voorkomt hallucinaties door de scope van elke agent te beperken.
In plaats van één "Coder" zetten we een team in:
-
De architect (de denker)
- Beperking: NO CODING.
- Rol: Leest de user story, verkent de codebase en schrijft een plan.md. Dit is een stapsgewijs uitvoeringsplan (bv. "1. Create DTO, 2. Map Domain").
- Voordeel: “Human in the loop” - Je beoordeelt het plan vóór de code geschreven wordt, waardoor over-engineering voorkomen wordt.
-
De coder (de doener)
- Beperking: Werkt één stap tegelijk.
- Rol: Leest plan.md, implementeert stap 1, voert tests uit, werkt het plan bij en STOPT voor goedkeuring. Hij kan geen stappen overslaan.
-
De reviewer (de bewaker)
- Beperking: Maximaal 15 opmerkingen, gerangschikt naar ernst.
- Rol: Gespecialiseerd in het opsporen van schendingen van lagen en copy-pastefouten die mensen vaak missen.
Van code schrijven naar systemen ontwerpen
AI-engineering met hoge integriteit draait niet om betere prompts te schrijven, maar om betere systemen te bouwen.
Wanneer AI herhaaldelijk dezelfde fout maakt, is de oplossing geen betere prompt. Het is een beter systeem.
- Versterk architecturale grenzen
- Voeg linterregels toe of verfijn ze
- Verbeter het stappenplan
- Verduidelijk documentatie
Na verloop van tijd creëert dat een omgeving waarin AI een betrouwbare versneller wordt in plaats van een bron van ruis.
Belangrijkste inzichten
- AI versnelt ontwikkeling. Ze kan ook technische schuld versneld opbouwen.
- Architectuur moet in code afgedwongen worden, niet alleen beschreven in documentatie.
- Deterministische scaffolding verbetert consistentie.
Geautomatiseerde kwaliteitscontroles beschermen de onderhoudbaarheid op lange termijn. - Duidelijke documentatie en gestructureerde workflows verbeteren AI-output.
AI is krachtig. Maar het presteert het best binnen goed afgebakende systemen.
Structuur vertraagt je niet. Ze laat je toe om snel te bewegen met vertrouwen.
Op zoek naar manieren om AI-ontwikkeling op te schalen zonder in te boeten op kwaliteit?


