Case study
AI op de basisschool na OK20: een Leidse bijles-rebuild
Een Leidse schoolkoepel trok haar bijles-agent van vier vestigingen offline in de week dat Noorwegen het OK20-besluit nam. Wij bouwden hem terug als docent-in-the-loop RAG. Dit veranderde.

Het is een dinsdag in februari. Groep 7 op een van de vier vestigingen in Leiden-Zuid werkt aan breukrekenen. De Snappet-bijles-agent heeft zojuist een oefenset naar de tablet van een tienjarige gepusht die de SLO-leerlijn stevig in groep 8 plaatst. De juf swipet 'm weg en noteert het moment in een schriftje dat ze sinds kort bijhoudt. Eind van die week staan er elf aantekeningen in. Eind van de maand tweeënvijftig.
De maandag erna valt het OK20-besluit van Noorwegen: een bijna-verbod op autonome AI-bijles in de barneskolen, hun basisonderwijs. Het bestuur van de koepel komt die vrijdagochtend bijeen. De woensdag erop staat de Snappet-bijles-agent op alle vier de vestigingen uit.
Dit hebben we ervoor in de plaats gebouwd, en dit liet veertien weken parallel draaien daadwerkelijk zien.
Waarom de koepel niet pauzeerde, maar uitschakelde
De koepel telt negentien mensen, vier vestigingen en zo'n 720 leerlingen. Ze hebben de agent niet gepauzeerd. Ze hebben hem eraf gehaald. Twee redenen.
Ten eerste was de Inspectie van het Onderwijs bij een van de vestigingen al begonnen met scherpe vragen over bewijslast rond differentiatie. Onder de Wet primair onderwijs moeten scholen kunnen laten zien hoe ze hun instructie per leerling aanpassen. Het eerlijke antwoord was op dat moment: "het algoritme kiest." Dat antwoord overleeft een inspectiebezoek niet, en het bestuur van de koepel wist het.
Ten tweede konden de docenten niet uitleggen wát de agent deed. Elf swipes in het schriftje in één week zijn elf momenten waarop een docent het systeem overrulede zonder te kunnen aanwijzen waarom het systeem voorstelde wat het voorstelde. Noorwegen was de trigger; de lokale aanleiding bouwde zich al maanden op.
De vraag die we kregen, de donderdag na de bestuursvergadering, was dus niet "kun je een veiliger agent leveren." Het was: "kun je een agent leveren die de docenten begrijpen en de Inspectie kan auditen, voor het begin van de tweede helft van het schooljaar."
Wat het nieuwe systeem echt moest kunnen
Drie eisen, alle drie niet onderhandelbaar.
Elke oefenset die werd voorgesteld aan een leerling onder de twaalf, moest een concreet leerdoel uit de SLO-leerlijn citeren voor het leerjaar van die leerling. Geen parafrase. De letterlijke kerndoel-tekst, met identifier en de URL van het brondocument. Was er geen passend leerdoel, dan weigerde de agent iets voor te stellen.
Een docent moest het voorstel goedkeuren voordat de leerling het te zien kreeg. Docent-in-the-loop, niet docent-on-top. Een "reviewqueue die je later wel opruimt" was geen docent-in-the-loop; dat patroon was precies wat de koepel net had laten vallen. De leerling ziet niets tot een mens heeft afgetekend.
Elke beslissing — voorstel, goedkeuring, afwijzing, docent-override, uitkomst — moest worden gelogd in een formaat dat de Inspectie zonder vertaler kan lezen. Geen screenshots. Gestructureerde records, doorzoekbaar, met de modelversie op elke regel gestempeld.
Generatiekwaliteit kwam op de vierde plek. Het doel van deze build was niet betere antwoorden. Het waren verdedigbare antwoorden.
De architectuur, in één tekening
Een leerling levert een opdracht in en doet 'm fout. Een kleine classifier tagt het foutpatroon — bijvoorbeeld noemers_niet_gelijk of kommagetal_verschoven. Dat patroon, plus het huidige leerjaar van de leerling, gaat de retrieval-laag in.
Retrieval raakt eerst de SLO-leerlijn, niet de oefenset-bibliotheek. De leerlijn is de canon; de oefeningen volgen uit het leerdoel, nooit andersom. Het bovenliggende leerdoel — hard gefilterd op het leerjaar van de leerling en lager — wordt de citatie die alles verderop moet verdedigen.
Pas daarna pakt het systeem een oefenset die bij dat leerdoel hoort. Het voorstel komt in de queue van de docent terecht, mét de letterlijke kerndoel-tekst eraan. De leerling ziet niets tot de docent goedkeurt.
def suggest_oefenset(leerling_id: str, opdracht_id: str) -> Suggestion:
leerling = pupils.get(leerling_id)
mistakes = recent_mistakes(leerling_id, window_days=14)
topic = topic_of(opdracht_id)
# Retrieval over the SLO-leerlijn, NOT the exercise library.
leerdoelen = slo_index.search(
topic=topic,
mistake_tags=mistakes.tags,
k=8,
)
# Hard ceiling at the leerling's current leerjaar.
leerdoelen = [d for d in leerdoelen if d.leerjaar <= leerling.leerjaar]
if not leerdoelen:
return Suggestion.skip(reason="geen_passend_leerdoel")
target = leerdoelen[0]
oefenset = exercise_db.match(
leerdoel_id=target.id,
mistake_pattern=mistakes.primary,
)
return Suggestion(
leerling_id=leerling_id,
oefenset_id=oefenset.id,
leerdoel_id=target.id,
leerdoel_citation=target.source_quote, # literal SLO text
leerdoel_url=target.source_url,
model_version=MODEL_VERSION,
status="awaiting_docent_review",
)
Het leerjaar-plafond in het tweede filter is de lijn die de oude Snappet-bijles-agent telkens overschreed. Het nieuwe systeem weigert werk boven leerjaar voor te stellen, zelfs als de recente prestaties van een leerling het pedagogisch zouden rechtvaardigen. Vindt een docent dat een leerling toe is aan een stap omhoog, dan gebeurt die beslissing expliciet, in de docentqueue, met de naam van de docent op de override.
De re-ranker die kandidaat-leerdoelen scoort tegen de opdrachttekst, is een kleine bi-encoder die we hebben fine-tuned op drie jaar eigen oefensets van de koepel, geen frontier-model. Een groter model hielp niet; de bottleneck was domeintaal, geen redenering. Inference per voorstel kost effectief niets, en dat doet ertoe als één vestiging in een drukke week tweeduizend voorstellen produceert.
Log de citatie, niet alleen het antwoord. Een audit trail zonder de bron die het model gebruikte, is waardeloos voor de Inspectie. En waardeloos voor jou de volgende keer dat een docent het oneens is met het systeem.
Het parallelle cohort van veertien weken
Van half februari tot eind mei draaiden twee cohorten op twee van de vier vestigingen parallel. Cohort A — 184 leerlingen — bleef op de oude autonome Snappet-bijles-agent. Cohort B — 178 leerlingen — draaide op de nieuwe RAG met docent-in-the-loop. Dezelfde openings-rekentoets, dezelfde sluit-rekentoets, hetzelfde lesplansjabloon, dezelfde zes docenten die elke drie weken tussen de cohorten wisselden. De rotatie was vervelend om te organiseren en onvermijdelijk: zonder die rotatie zou elk verschil tussen de cohorten vertroebeld worden door welke docent je toevallig trok.
We verwachtten een klein verlies op de ruwe rekentoets-delta voor cohort B, in ruil voor hanteerbare Inspectie-bewijslast en lagere variantie. Dat is grofweg wat we kregen.
De gemiddelde rekentoets-delta voor cohort A lag over die veertien weken ongeveer een punt hoger dan cohort B. De standaarddeviatie in cohort B was merkbaar smaller: de agent stelde nooit een bovenleerjaar-oefenset voor aan een leerling die al achterliep, dus de lange staart van gefrustreerde kinderen die het oude systeem doorgaans liet groeien, ontstond niet. Twee leerlingen in cohort A moesten aan het einde van de periode in bijwerken; cohort B had er nul.
Niets daarvan is een knock-out voor het ene cohort boven het andere. Het is bewijs dat de afweging die de koepel écht wilde — een bescheiden vooruitgangsondergrens, geen overschrijdingen van het plafond, een verdedigbaar dossier per leerling — haalbaar was zonder de onderliggende techniek op te geven. Het bestuur tekende voor het uitrollen van het systeem van cohort B over alle vier vestigingen vanaf september.
Het Inspectie-dossier
Het minst sexy deel van deze build was de audit log. Het is ook het deel dat de rest betaalde.
Elk voorstel, elke goedkeuring, elke afwijzing, elke docent-override en elke leerling-uitkomst is één regel in een Postgres-tabel die het bestuur van de koepel aan het einde van iedere schoolweek als Parquet exporteert. De kolommen zijn saai: timestamp, leerling-id (gepseudonimiseerd), docent-id, leerdoel-id, leerdoel-citation, oefenset-id, model-version, decision, decision-reason. Het schema is sinds week drie niet veranderd.
Zestien kolommen in totaal: identifiers voor het event, de school, de vestiging, de gepseudonimiseerde leerling, de docent, het voorstel, het leerdoel en de oefenset; de letterlijke citatie-tekst; de bron-URL; de modelversie-string; het event-type; en drie kolommen voor de beslissing en haar redencode. Eén regel per event, één Parquet-bestand per schoolweek. Een gemiddelde week komt onder de negen megabyte. Een volledig schooljaar aan audit-bewijs past op een USB-stick.
Toen de Inspectie in mei langskwam, gaf de koepel de inspecteur een query mee die hij zelf kon draaien: "geef me elke leerling van wie het voorgestelde werk in de afgelopen twaalf weken boven leerjaar lag." Het antwoord was nul regels. Vervolgens: "geef me elke override van de docenten, gegroepeerd per docent en reden." Dat antwoord had ruim driehonderd regels en een nette verdeling over de docenten. Het inspectiebezoek was rond de lunch afgerond.
Wat brak, wat we veranderden
Drie dingen gingen niet volgens plan.
De eerste week liep de docentqueue over. De agent genereerde meer kandidaat-oefensets dan de docenten tijdens lesuren konden reviewen; voorstellen stapelden zich 's nachts op en de docenten kwamen 's ochtends binnen op een lijst die ze vóór de eerste pauze niet leeg kregen. We hebben een batch-goedkeuringsmodus toegevoegd voor laag-risicovoorstellen: zelfde leerdoel als het vorige goedgekeurde voorstel voor die leerling, identieke oefenset-structuur, geen nieuw foutpatroon. De docent keurt de batch goed met één tik en een steekproef. De mediane tijd tussen voorstel en beslissing daalde van 47 minuten naar 11.
De tweede was retrieval-drift. Sommige onderwerpomschrijvingen in de SLO-leerlijn zijn los genoeg dat de retriever af en toe een bijna-passend leerdoel uit een ander subdomein bovenhaalde — bijvoorbeeld een meetkundig kerndoel voor een leerling die op een verhoudings-opdracht was vastgelopen. We hebben een re-ranker toegevoegd die elk kandidaat-leerdoel scoort tegen de daadwerkelijke opdrachttekst, niet alleen tegen de onderwerptag, en de drempel voor "geen voorstel" verschoven van 0.6 naar 0.7. De agent slaat nu vaker over. De docenten waarderen dat.
De derde waren de docenten zelf. Twee van de zes wisselende docenten zeiden na drie weken dat ze het nieuwe systeem minder vertrouwden dan het oude — juist omdat ze nu kónden zien wát het koos. Dat namen we serieus. De fix was het herontwerpen van de UI van de docentqueue: de leerdoel-citatie bovenaan, niet de oefenset-preview. Als de docent eerst de curriculumregel ziet, leest het voorstel als een curriculumbeslissing waarvoor de agent de bron aandraagt, niet als een agent die kiest en om toestemming vraagt. Dezelfde data, een andere framing, een totaal andere vertrouwenshouding.
Vier weken later opnieuw gemeten. De twee docenten die wantrouwen hadden aangegeven, keurden in hetzelfde tempo goed als hun collega's en overruleden minder vaak. Het leerdoel vooraan zetten was niet alleen het herordenen van een queue-UI; het veranderde wie in de kamer zich verantwoordelijk voelde voor de pedagogische beslissing. Die verantwoordelijkheid hoorde de hele tijd al bij de docent. De agent droeg 'm stil mee, en dat is het deel dat niemand had kunnen benoemen tot ze het weg zagen.
Het kleinste wat je vandaag kunt doen
Draai je een AI-agent in een gereguleerde context — onderwijs, zorg, financieel, publiek domein, overal met een inspecteur — pak dan één beslissing die jouw systeem vandaag heeft genomen en vraag: kun je de bron aanwijzen die het gebruikte? Niet de prompt. De bron. Is het antwoord "het model wist het gewoon," dan ligt er een audit-probleem op je te wachten. Voeg de citatie-kolom toe aan je log voordat je de volgende feature toevoegt.
Toen we de docent-in-the-loop RAG voor de Leidse koepel bouwden, zat het lastige niet in de retrieval en niet in het model. Het zat in het audit-schema en de queue-UI. We leveren AI-agents in gereguleerde context inmiddels meestal op dezelfde manier: eerst citeren, dan genereren, alles loggen, en een mens op de goedkeuringsstoel met een citatie-eerst-view.
Kern
Bij AI in gereguleerde context: log de bron die het model gebruikte, niet alleen het antwoord. De audit trail die je vandaag bouwt, is de enige die je morgen kunt verdedigen.
FAQ
Leerden de leerlingen langzamer door het nieuwe systeem?
De gemiddelde rekentoets-delta van cohort B lag over veertien weken ongeveer een punt onder die van cohort A, maar de variantie was smaller en geen enkele leerling hoefde in bijwerken.
Waarom specifiek de SLO-leerlijn citeren?
Dat is het canonieke curriculumdocument waarop Nederlandse basisscholen worden afgerekend. Citeren geeft de Inspectie een directe lijn van elk voorstel terug naar een landelijke standaard.
Hoeveel tijd voegt docent-in-the-loop-goedkeuring per voorstel toe?
Na het uitrollen van de batch-goedkeuringsmodus was de mediane tijd tussen agent-voorstel en docentbeslissing 11 minuten. Daarvoor liep de queue regelmatig door naar de volgende dag.
Kan dit ook zonder RAG-laag?
Ja, maar dan verlies je de citatie. Het draait niet om generatiekwaliteit. Het draait om traceerbaarheid: een verdedigbare bron voor elke output die de leerling en de Inspectie ooit te zien krijgen.