GoLearn
Gamified examentraining voor sociaal-werkstudenten: een dossier per onderwerp met quiz, een Space Invaders-spel en on-demand AI-uitleg via een lokale LLM, gebouwd op een Go-backend.
- QTI-XML
- Categorisatie
- Quiz & spel
- AI-uitleg (Ollama)
Probleem
De bestaande oefenomgeving voor sociaal-werkstudenten was een kale lijst met examenvragen: geen voortgang, geen feedback die iets uitlegt, geen enkele reden om langer te oefenen dan strikt noodzakelijk. De opdracht was die omgeving te vervangen door iets waar studenten daadwerkelijk in blijven hangen.
Aanpak
In plaats van kale vragenlijsten doorloopt een student een "dossier" per examenonderwerp: eerst een quiz met voortgangsbalk en score-tracking, daarna dezelfde stof terugspelen als een Space Invaders-achtige game (het juiste antwoord neerschieten in plaats van aanklikken), met een leaderboard tegen bots voor extra motivatie. Bij een lastige vraag kan de student on-demand AI-uitleg opvragen.
De backend is in Go geschreven: eigen REST-endpoints (net/http) voor
examens, vragen, antwoorden en AI-hulp, met CORS-middleware voor de
vanilla-JS-frontend. De brondata komt binnen als QTI-examen-XML (een
standaardformaat voor toetsvragen) en wordt door een zelfgeschreven
converter omgezet naar JSON dat de frontend rechtstreeks kan gebruiken.
De AI-uitleg draait op een lokale LLM (Ollama met Mistral) in plaats van een cloud-API. De game-rendering gebeurt met de Canvas API, zonder frontend-framework. Ik heb ook een samenhangend visueel systeem ontworpen, een "dossier"-thema dat de landingpagina, examenselectie, quiz en game bij elkaar houdt, in plaats van losse stijlen per pagina.
Stack
Bewuste keuze
Voor dit project koos ik bewust voor een lokale LLM (Ollama/Mistral) in plaats van een cloud-API zoals Groq. Examenvragen en studentinteracties blijven zo op eigen infrastructuur, zonder studiedata die naar een externe partij gaat en zonder kosten per aanvraag. De prijs: een merkbaar tragere en minder sterke AI dan een groot cloud-gehost model, en zelf verantwoordelijk voor het draaiend houden ervan.
Wat ik ervan leerde
De categorie-detectie (recht, welzijn, communicatie, …) bleek bij het testen vragen verkeerd te labelen. De matching-logica ging uit van vrij strikte string-vergelijkingen op onderwerpnamen, terwijl de QTI-brondata net genoeg variatie bevatte (hoofdletters, spatiëring, afkortingen) om dat stil te laten falen zonder een fout te gooien. Dat leerde me dat string-matching op externe brondata zelden luidruchtig faalt: hij faalt door quasi-correcte output die je alleen opmerkt als je de resultaten ook echt naloopt, niet alleen de code.
Om die reden heb ik dit project end-to-end getest met de echte QTI-data en een draaiende server, in plaats van alleen losse functies te unit-testen: de categoriebug was op functieniveau onzichtbaar en kwam pas naar boven toen ik de hele keten doorliep zoals een student dat ook zou doen.
Het was ook het eerste project waarin ik een volledig samenhangend UI-systeem over alle pagina's heen heb doorgevoerd, in plaats van een simpele losse frontend bovenop een API. Een goede oefening in denken vanuit de hele gebruikerservaring, niet alleen de backend.