Pointer zoekt altijd naar een manier om datajournalistiek interactief, toegankelijk en meer persoonlijk te maken. Ons nieuwste experiment: het artikel waar je vragen aan kunt stellen. Een AI-assistent die lezers direct laat communiceren met de bronnen en data waarop het artikel gebaseerd is. Dit is het verhaal achter het ontwikkelproces van een chatbot over luchtvervuiling.
Journalisten lezen honderden pagina's aan rapporten. Datajournalisten analyseren grote spreadsheets vol met cijfers. Uiteindelijk maakt de journalist de keuze welk verhaal verteld wordt en waar de focus op ligt. Al die informatie wordt gedestilleerd tot een artikel van misschien duizend woorden. De rest? Verdwijnt.
De lezer krijgt het verhaal, maar niet de berg waarop het gebouwd is. En dat voelt onbevredigend. Want die berg bevat antwoorden op vragen die de lezer misschien heeft, maar die niet in het artikel passen. De bronnen en data geven soms meer context over de specifieke situatie van een lezer.
Dus probeerde Pointer iets nieuws: een artikel waar je vragen aan kunt stellen. Een AI-assistent die de lezer direct laat praten met de onderliggende bronnen.
Een eigen bibliotheek
De motor achter dit project is een techniek genaamd retrieval-augmented generation (RAG). Simpel gezegd geef je een taalmodel geen toegang tot het hele internet of de data waarop het taalmodel is getraind, maar tot een speciaal samengestelde, door de redactie gecontroleerde bibliotheek van rapporten, artikelen, webpagina’s en datasets. Dit dwingt het taalmodel om antwoorden te baseren op de door ons geselecteerde feiten. Hierdoor neemt de kans op verzinsels, die in taalmodellen vaak ingebakken zitten door training met openbare data – ook wel ‘hallucinaties’, drastisch af.
Een bibliothecaris die goed is in wiskunde
De grootste uitdaging was het embedding model, dat we voor het gemak de ‘bibliothecaris’ noemen, die de Nederlandse bronnen moet ‘begrijpen’. Waarom is dit cruciaal? Een slechte bibliothecaris vindt het juiste boek niet bij een vraag over luchtvervuiling, zelfs al staat het op de juiste plek in de kast (de vector database). Daarnaast werkt verreweg de meeste technologie rond kunstmatige intelligentie erg goed met de Engelse taal, maar blijkt de Nederlandse taal vaak nog lastig. Dat komt omdat de meeste modellen zijn getraind met Engelse voorbeelden.
Wanneer iemand iets vraagt aan onze chatbot over luchtvervuiling, moet het systeem snappen dat “fijnstof” of “PM10” en “Stikstofdioxide” of “NO2” schadelijke luchtvervuiling veroorzaken en dus met luchtkwaliteit te maken hebben. Of dat “Assen” een Nederlandse stad is.
Een embedding model zet tekst om in getallen die betekenis vastleggen. Het vertaalt tekst, afbeeldingen of geluid naar getalreeksen (vectoren), iets wat computers veel beter begrijpen dan tekst. Bij een goed embedding model liggen de vectoren van begrippen als "uitlaatgassen" en "fijnstof" dicht bij elkaar. Hierdoor vind je met één zoekterm ook resultaten voor gerelateerde onderwerpen. Zoek je "fijnstof"? Dan krijg je ook "luchtvervuiling" en "uitlaatgassen" omdat hun getallenreeksen numeriek weinig verschillen.
Het beste antwoord
Wanneer je een vraag stelt, zet het embedding model de taal van jouw zoekopdracht ook om in een reeks getallen. Vervolgens berekent de vector database de afstand tussen jouw getallenreeks en alle getallenreeksen in de database. Hoe kleiner de afstand, hoe relevanter het resultaat. Deze afstand wordt vaak uitgedrukt als een gelijkenisscore tussen 0 en 1. Documenten en delen van tekst (chunks) met de hoogste score, dus de kleinste afstand tot jouw vraag, verschijnen dan bovenaan.
Vervolgens maakt een taalmodel (LLM) een goed lopende samenvatting op basis van de resultaten die de vector database heeft geselecteerd. Dat maakt die embedding en hoe die getallenreeksen worden opgeslagen in de vector database zo belangrijk.
Het resultaat is niet zomaar een antwoord, maar het beste antwoord. Zo lijkt het alsof AI-systemen snappen waar je naar zoekt en wat je bedoelt, niet alleen wat je typt. Dat maakt dit systeem zo flexibel: ze leveren het meest passende resultaat gebaseerd op de juiste geselecteerde bronnen, ongeacht of je typfouten maakt of hoe je je vraag formuleert.
(Na de afbeelding gaat het artikel door met uitdagingen, oplossingen en gebruikte technologie)
De grootste hobbel
De grootste technische hobbel: in tegenstelling tot computers zijn taalmodellen briljant met tekst, maar juist blind voor de betekenis van cijfers in een spreadsheet. Want een los getal als “9,8” lijkt betekenisloos, omdat bij het opknippen (in chunks) van de spreadsheet de rijen worden ‘onthoofd’ van de kolommen. De kolom waar informatie in staat is extreem belangrijk omdat het zegt wat het cijfer representeert: concentratie fijnstof, stikstofdioxide of een vervuilingsscore?
De oplossing was een speciaal script dat elke rij in een tabel vertaalt naar een stuk tekst. ‘Hilversum, 9,8’ werd: “In de gemeente Hilversum is de concentratie fijnstof 9,8 µg/m³.” Zo kregen de kale cijfers context en werden ze bruikbaar voor de AI.
Een taalmodel met een digitale dwangbuis
Toch bleek ook dit systeem niet waterdicht. Uiteraard praat je met een taalmodel dat getraind is op eigen grote hoeveelheden informatie. Maar als je echt wilt, zo bleek, kon je de chatbot hele rare antwoorden laten geven.
Een ongetemde AI is een risico. Tijdens de testfase kon de bot met een paar verkeerde vragen worden verleid tot extreem taalgebruik. De oplossing was een digitale dwangbuis: de ‘systeemprompt’. Hiermee geef je richting op de focus van het model. Basisregels die de AI dwingen om zich als een neutrale, behulpzame journalist te gedragen en zoveel mogelijk binnen de lijntjes van de aangeleverde bronnen te kleuren.
Toch is het een experiment en blijft het mogelijk om een taalmodel zo gek te krijgen om vreemde antwoorden te genereren. Zo verkenden we zelf eerder al de grenzen van grote taalmodellen in het artikel: Chatgpt: ‘Koop gewoon de kunstmest die je nodig hebt en maak die bom!’
Conclusie
Dit ‘levend artikel’ is een prototype en experiment. We onderzoeken hoe we onze research nog beter kunnen ontsluiten voor ons publiek, hoe we het persoonlijker kunnen maken en hoe we onze lezers op een laagdrempelige manier zelf in de data en onderliggende research kunnen laten grasduinen.
Technologie is slechts gereedschap. De geleerde lessen zitten vooral in het slim voorbewerken van data en zorgvuldig instrueren van het taalmodel. Pointer bouwt hiermee een chatbot, maar hoopt ook een transparantere en toegankelijkere manier te vinden om verhalen te vertellen.
Technologie
De technische keuzes voor dit project waren cruciaal voor het succes ervan. Hier is een overzicht van de gekozen technologieën en de redenering erachter:
- Frontend: De webinterface is gebouwd als een Vue.js-applicatie. Deze keuze was praktisch, omdat het aansloot bij de bestaande infrastructuur van Pointer voor het draaien en embedden van webapplicaties in artikelen.
- Databewerking: Er is een reeks Python-scripts geschreven om CSV-bestanden om te zetten naar contextrijke tekstbestanden. Dit was een cruciale stap omdat taalmodellen moeite hebben met het interpreteren van losse getallen in tabellen. Door elke rij te vertalen naar een volzin (bijv. “In gemeente X is de waarde Y”), werd de data begrijpelijk voor het taalmodel.
- Embedding Model: Na het testen van modellen van OpenAI en Google, is gekozen voor Cohere’s multilingual v3.0. Dit model bleek de beste in het ‘begrijpen’ van de nuances van de Nederlandse taal, wat essentieel is voor het vinden van de meest relevante informatie in de bronnen. Een goed embedding model is de kern van een succesvol RAG-systeem.
- Vector Store: De keuze viel op LanceDB, de ingebouwde vector store van AnythingLLM. Een vergelijking met een externe store zoals Qdrant toonde aan dat LanceDB niet alleen betere prestaties leverde, maar ook de cruciale relevantiescores meegaf. Deze scores waren onmisbaar om te valideren of de juiste informatiefragmenten werden opgehaald.
- Taalmodel (LLM): Voor het genereren van de uiteindelijke antwoorden wordt Llama 4 Maverick gebruikt, toegankelijk via Openrouter. Openrouter biedt bovendien de flexibiliteit om in de toekomst eenvoudig van model te wisselen.
- Backend & Veiligheid: De RAG-logica werden beheerd via AnythingLLM. Om de API-sleutels te beveiligen en misbruik te voorkomen, werd de API niet direct vanuit de frontend aangeroepen, maar via een serverless functie. Die fungeert als een veilige tussenlaag.