RAG
RAG-aansprakelijkheid: drie clausules na Duits vonnis
Een Duitse rechter hield Google aansprakelijk voor AI Overview-hallucinaties. Binnen zeven dagen herschreven wij drie clausules voor elke Nederlandse klant met een RAG-agent op externe content.

De ochtend dat het vonnis viel
Het was een dinsdag begin juni, net na negenen op ons kantoor in Eindhoven. Een van onze engineers pingde het teamkanaal met één zin: "We moeten nu naar onze RAG-agents kijken." Eronder een Hacker News-thread, 527 punten en stijgend, met als kop dat een Duitse rechter Google aansprakelijk had verklaard voor foute antwoorden in AI Overviews.
Binnen veertig minuten hadden we de klantenlijst erbij gepakt en geteld: elf live agents die wij voor Nederlandse klanten hebben gebouwd op content van derden. Productcatalogi, regelgevende teksten, leveranciersspecificaties, kennisbanken van partners. Elf contracten die nog niet voorzien waren op wat de rechter zojuist had vastgesteld.
Op vrijdag hadden we drie clausules herschreven in alle elf contracten, de redlines naar elke klant gestuurd en twee agent-architecturen gepatcht. Dit is de walkthrough.
Wat het vonnis daadwerkelijk vastlegt
We gaan geen paragraafnummers verzinnen uit een vonnis dat we niet zelf hebben gelezen. De berichtgeving in de Duitse juridische pers en op Hacker News kwam uit op één principe: een platform dat een antwoord synthetiseert uit materiaal van derden en die synthese als feit presenteert, kan verantwoordelijk worden gehouden voor de juistheid van wat het presenteert.
De klassieke safe harbour voor het hosten van content van anderen, oorspronkelijk Artikel 14 van de e-Commerce-richtlijn en nu opgenomen in de Digital Services Act, is geschreven voor een wereld waarin een platform een bestand of post van een gebruiker bewaarde. Hij voorzag niet in een systeem dat tekst van anderen ingest, herschrijft en die herschrijving als het eigen antwoord van het platform presenteert.
Draai je een RAG-agent, dan is de zin hierboven de hele blogpost. Je retriever haalt materiaal van derden op. Je generator herschrijft het. Je agent presenteert de herschrijving. Het feit dat je herschrijft, verschuift je van host naar uitgever.
Zodra je agent een bron van derden parafraseert in plaats van letterlijk citeert, heb je een nieuwe feitelijke uitspraak gepubliceerd. Behandel elk gegenereerd antwoord als iets wat jouw bedrijf zei, niet als iets wat je bronnen zeiden.
Waarom dit niet alleen een Google-probleem is
De eerste reactie in het teamkanaal die dinsdag was: dit is een probleem op Google-schaal, geen probleem voor ons. Een gescrapte concurrentcatalogus die door een agent voor een Rotterdamse groothandel wordt geherformuleerd, is iets heel anders dan Google die het open web synthetiseert voor een miljard dagelijkse gebruikers. Maar het juridische principe schaalt niet mee met je omzet. Of de agent nu op planeetschaal draait of voor één regionale inkoper, de toets is dezelfde. Heeft het systeem materiaal van derden gepakt, het getransformeerd en die transformatie als antwoord gepresenteerd.
Die toets vangt vrijwel elke interessante RAG-architectuur die wij hebben opgeleverd. De uitzonderingen zijn agents die alleen letterlijk citeren, met bronvermelding, en weigeren te antwoorden als geen bron kan worden geciteerd. Daar hadden we er twee van, op elf. De andere negen parafraseerden.
Clausule één: de bron-van-waarheid-grens
De eerste clausule die we herschreven gaat over wat de agent contractueel mag ingest. Vóór het vonnis stond er in onze standaardtekst dat de agent 'door de klant aangeleverd en door de klant goedgekeurd bronmateriaal' indexeert. Dat was te ruim. Een klant die drie URL's in een onboarding-formulier plakte, had onder onze oude tekst een hele scrape-run goedgekeurd.
De nieuwe clausule splitst bronmateriaal in drie klassen:
- First-party: de klant is eigenaar of heeft een duidelijke schriftelijke licentie.
- Third-party permissive: open licentie, publiek domein, of schriftelijke toestemming in dossier, met de licentietekst opgeslagen naast de data.
- Third-party restricted: al het overige, inclusief gescrapte content.
De agent mag klasse één en twee contractueel parafraseren. Voor klasse drie moet hij letterlijk citeren, toeschrijven en linken, of weigeren te antwoorden. Het contract benoemt per klasse de verantwoordelijke partij. De klant is eigenaar van klasse één en twee. Klasse drie raken we niet aan zonder een aparte schriftelijke aanvulling die de klant aanwijst als juridisch verantwoordelijke uitgever.
Clausule twee: het versheidsvenster
De tweede clausule was een verrassing. Hier hadden we eerder nooit over geschreven, omdat verouderde data tot dan toe een kwaliteitskwestie was, geen juridische. Nu is het allebei.
Als een agent een vraag over een regeling of een prijs beantwoordt met een chunk die negen maanden geleden is opgehaald, en die chunk klopt inmiddels niet meer, dan heeft de agent een onwaarheid uitgesproken. Onder het Duitse principe komt die onwaarheid voor rekening van degene die de agent draait. Onze nieuwe clausule legt daarom per dataklasse een maximaal versheidsvenster vast tussen retrieval en antwoord. Voor regelgevende content is dat 30 dagen. Voor productspecs 7 dagen. Voor prijsdata 24 uur. Valt de meest verse beschikbare chunk buiten dat venster, dan moet de agent dat in het antwoord vermelden.
Het grootste deel van de architectuurwijziging zit in de indexer. De contractwijziging is het deel dat de klant tekent.
Clausule drie: de takedown-SLA
De derde clausule gaat over wat er gebeurt als een derde partij je laat weten dat je agent hen verkeerd weergeeft. Onder de e-Commerce-richtlijn moest een host na een melding 'voortvarend' handelen. De DSA heeft dat aangescherpt, maar de exacte deadline blijft een kwestie van interpretatie. Voor een uitgever zijn rechters historisch minder geduldig geweest.
Wij hebben een harde takedown-SLA van 24 uur in elk contract gezet. Binnen 24 uur na een geloofwaardige schriftelijke melding gaan de betreffende chunks uit de index, wordt de agent gepatcht om antwoorden over dat onderwerp te weigeren en wordt de klant geïnformeerd. Wij committeren ons daaraan. De klant stemt ermee in dat wij eenzijdig mogen handelen als hij onbereikbaar is. Zaterdag en zondag tellen mee.
Op deze clausule kwam de meeste weerstand. Twee klanten vroegen om 72 uur. We hielden voet bij stuk op 24. De reden is egoïstisch. Wij draaien de agents, dus wij dragen het krantenkop-risico als een rechter de SLA leest als bewijs van hoe serieus de operator omgaat met juistheid.
De architectuurpatch
Contracten zonder code zijn theater. Twee van de elf agents hadden echte aanpassingen nodig. De patch hieronder is de gate die we vóór elke generator-call hebben gezet. Plug je bestaande parafraseer- en quote-only-generators in als callables en de rest van het bestand draait as-is op Python 3.11+.
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Callable, Literal
LicenseClass = Literal["first_party", "third_permissive", "third_restricted"]
DataClass = Literal["regulatory", "product_spec", "pricing", "other"]
@dataclass
class Chunk:
text: str
source_id: str
license_class: LicenseClass
data_class: DataClass
retrieved_at: datetime
source_url: str | None = None
@dataclass
class Answer:
text: str
mode: Literal["paraphrase", "quote", "refuse"]
@classmethod
def refuse(cls, reason: str) -> "Answer":
return cls(text=reason, mode="refuse")
WINDOWS: dict[DataClass, timedelta] = {
"regulatory": timedelta(days=30),
"product_spec": timedelta(days=7),
"pricing": timedelta(hours=24),
"other": timedelta(days=30),
}
def is_stale(chunk: Chunk, now: datetime) -> bool:
return (now - chunk.retrieved_at) > WINDOWS[chunk.data_class]
def answer(
query: str,
chunks: list[Chunk],
now: datetime,
paraphrase: Callable[[str, list[Chunk]], str],
quote_only: Callable[[str, list[Chunk]], str],
) -> Answer:
# Hard fail at the boundary if any chunk lacks provenance.
for c in chunks:
assert c.source_id, "chunk has no source_id"
assert c.license_class, "chunk has no license_class"
usable = [c for c in chunks if not is_stale(c, now)]
if not usable:
return Answer.refuse("No fresh source for this question.")
restricted = any(c.license_class == "third_restricted" for c in usable)
if restricted:
return Answer(text=quote_only(query, usable), mode="quote")
return Answer(text=paraphrase(query, usable), mode="paraphrase")
if __name__ == "__main__":
sample = [
Chunk(
text="Widget X ships in 5 days.",
source_id="catalogue-row-9821",
license_class="first_party",
data_class="product_spec",
retrieved_at=datetime.utcnow() - timedelta(days=2),
)
]
out = answer(
"How fast does Widget X ship?",
sample,
datetime.utcnow(),
paraphrase=lambda q, cs: cs[0].text,
quote_only=lambda q, cs: f'"{cs[0].text}"',
)
print(out)
De belangrijkste verandering zit niet in de generator. Het is de assertion aan de grens. De helft van de indexers die we doorlichtten had chunks met lege source_id-velden, restanten van vroege prototypes. Die chunks zouden onder de nieuwe contracten de klant blootstellen. We hebben ze verwijderd en opnieuw geïndexeerd.
Het gesprek van vijf minuten met elke klant
Elke Nederlandse klant kreeg deze week hetzelfde gesprek van vijf minuten. De inhoud bleef in alle gesprekken hetzelfde, dus we hebben het één keer opgeschreven.
De juridische ondergrond onder AI-agents die content van anderen tonen, is deze week verschoven. De agent die wij voor jou hebben gebouwd is in orde, maar het contract eronder is geschreven vóór die verschuiving. Wij sturen je vanavond redlines. Graag binnen veertien dagen tekenen. Heb je een bron van derden die wij over het hoofd hebben gezien, laat het ons dan vóór vrijdag weten.
ABN-belscript voor klanten, juni 2026
Geen enkele klant weigerde. Twee vroegen om de takedown-SLA uit te stellen tot hun compliance-team ernaar had gekeken. Eén vroeg of hun oude PDF-helpcentrum, dat we hadden geïndexeerd, als first-party telde. Dat deed het, nadat we hadden geverifieerd dat ze schriftelijke toestemming hadden van de freelancer die het acht jaar geleden had opgesteld.
De audit die je vóór de lunch kunt draaien
Draai je een RAG-agent en kun je vanmiddag je jurist niet bellen, dan kun je het grootste gat alsnog in vijf minuten dichten. Open de database achter je vector store. Draai één query: hoeveel chunks hebben een niet-lege source identifier, en hoeveel niet. Draai dan de tweede query: van de chunks met een bron, hoeveel hebben een vastgelegde licentieklasse.
Zijn die twee tellingen niet gelijk aan je totaal aantal chunks, dan heb je een risico. Zorg dat de agent de niet-geclassificeerde chunks niet meer parafraseert. Dwing hem om letterlijk te citeren met bronvermelding, of te weigeren. Met die ene wijziging val je voor de betreffende content weer onder de host-lezing van de safe harbour, terwijl je jurist bijbeent.
Toen wij vorig jaar de leveranciers-kennis-RAG-agent voor een Rotterdamse groothandel bouwden, liepen we ertegenaan dat hun productdatabase first-party catalogustekst en gescrapte leveranciersspecs in dezelfde tabel had staan. Uiteindelijk hebben we het opgelost door elke rij bij ingest een licentieklasse mee te geven, en de agent te laten weigeren te starten als één rij geen klasse had. Hetzelfde patroon is inmiddels de minimumstandaard voor elke AI-agent die content raakt waarvan de klant geen eigenaar is.
Open je vector store. Tel de chunks zonder bron. Dat getal is je huiswerk.
Kern
Zodra je RAG-agent content van derden parafraseert, ben je geen host meer maar uitgever. Herschrijf je contracten daarop.
FAQ
Bindt het Duitse vonnis Nederlandse RAG-operators?
Het bindt Nederlandse rechters niet direct, maar het onderliggende principe van uitgever-aansprakelijkheid voor gesynthetiseerde antwoorden loopt door het hele EU-recht heen. Beschouw het als een sterk signaal van waar Nederlandse rechters zullen uitkomen.
Moeten we volledig stoppen met RAG-agents?
Nee. Agents die de nieuwe lat halen, citeren letterlijk met bronvermelding, of parafraseren alleen content waarvan de klant eigenaar is of die hij heeft gelicentieerd. De meeste productie-RAG kun je op orde brengen met een index-audit en een contract-redline.
Wat als onze agent altijd alleen letterlijk citeert?
Dan zit je dichter bij de host-safe-harbour. Je hebt nog steeds nauwkeurige bronvermelding nodig, een werkend takedown-pad en bewijs dat het citaat niet is gewijzigd. Letterlijk citeren is geen vrijbrief, maar wel een veel veiliger uitgangspunt.
Hoe snel moet de takedown-SLA zijn?
Wij committeren ons aan 24 uur, weekenden inbegrepen. Langere termijnen zijn verdedigbaar, maar lastiger uit te leggen voor een rechter die net een week oude hallucinatie heeft gelezen die nog steeds in je index staat.