Direct naar inhoud
Terug naar projecten
GenAI
RAG
Python
LLM

Strafrecht-RAG: semantisch zoeken in rechterlijke uitspraken

Eigen project

Eigen project, gebouwd om te laten zien hoe ik AI-systemen aanpak. De ontwerpkeuzes zijn het eigenlijke verhaal: die bepalen of een RAG-systeem betrouwbaar wordt of een black box.

Wat het is

Een RAG-systeem (Retrieval-Augmented Generation) over rechterlijke uitspraken: doorzoek uitspraken van Rechtspraak.nl semantisch en laat een taalmodel antwoorden formuleren — uitsluitend op basis van de gevonden passages, en altijd met verwijzing naar de bron.

De twee regels waar het hele ontwerp om draait:

  1. Elke bewering krijgt een ECLI-verwijzing. Van antwoord terug naar de exacte passage in de exacte uitspraak. Geen black box.
  2. Zonder relevante bron geen antwoord. Het model mag niets verzinnen; "geen bron gevonden" is een volwaardige uitkomst, geen foutmelding.

Dat zijn dezelfde eisen die ik aan elk AI-systeem stel. Juridische teksten zijn er alleen genadelozer in: een verzonnen verwijzing valt direct door de mand.

De opzet

Drie lagen, elk apart testbaar:

  • Ingest — uitspraken ophalen via de Open Data-interface van Rechtspraak.nl, met rate limiting en retries, en de ruwe XML parsen naar één genormaliseerd model: ECLI, instantie, datum, rechtsgebied en de tekstsecties.
  • Index — tekst opdelen in overlappende chunks mét behoud van sectie- en paragraafnummers, zodat elke chunk exact terug te voeren is op zijn plek in de bron. Chunks worden batchgewijs geëmbed en opgeslagen in een vector store, inclusief metadata om op instantie, datum en rechtsgebied te filteren.
  • Query — de vraag embedden, de best passende passages ophalen, en een prompt die het model dwingt uitsluitend op basis van die passages te antwoorden — met een expliciet "geen bron gevonden"-pad.

De hele keten draait vanaf de commandline: ingest, index en ask als losse commando's, van ophalen tot antwoord.

Kwaliteit wordt gemeten, niet gehoopt

De vraag "werkt het?" is bij RAG-systemen berucht vaag, dus die is vervangen door een meting. Een vaste evaluatieset — vragen met de ECLI's die het systeem hoort te vinden — draait in CI bij elke wijziging en meet twee dingen: vindt de retrieval de juiste uitspraken (recall), en kloppen de bronverwijzingen in het antwoord met de aangeleverde passages. Een wijziging aan chunking, embeddingmodel of prompt is daarmee geen kwestie van "het voelt beter", maar van een cijfer dat omhoog of omlaag gaat — de meetlat ligt er vóór de eerste regel code.

Het resultaat

Elk antwoord is klikbaar herleidbaar tot de onderliggende passages, per bewering. Vragen zonder relevante bron krijgen netjes "geen bron gevonden" in plaats van een overtuigend verzinsel — en die weigering wordt in de evaluatieset net zo goed getest als de antwoorden zelf. De kwaliteit van de keten is daarmee uit te drukken in een getal, bij elke commit opnieuw.

Aandachtspunten

  • Uitspraken zijn openbaar, maar bevatten geanonimiseerde persoonsgegevens — de omgang daarmee is onderdeel van het ontwerp, niet een bijlage achteraf.
  • Antwoorden zijn geen juridisch advies; bronvermelding is verplicht in elke output.

In de repo

  • Ingest: ophalen en parsen van uitspraken, met rate limiting en retries
  • Index: chunking met behoud van sectienummers, embeddings en vector store
  • Query: retrieval en antwoordgeneratie met verplichte bronvermelding
  • CLI voor de hele keten: ingest, index, ask
  • Evaluatieset met recall- en bronjuistheidsmeting in CI

Technologie

Python, embeddings en vector store, Rechtspraak.nl Open Data, GitHub Actions