Wat is RAG en waarom is het belangrijk
Standaard GPT-4o kent de interne documenten van jouw bedrijf, je productcatalogus of je klantdata niet. RAG lost dit op: je slaat je inhoud op als vectorembeddings in een database, en bij het stellen van een vraag vind je de meest relevante passages en stuur je ze als context naar de LLM.
Het resultaat: een AI-assistent die vragen beantwoordt over jouw specifieke data, nauwkeurig en met bronvermeldingen.
RAG is nu de standaardarchitectuur voor enterprise AI-assistenten, interne kennisbanken en klantenservicebots. Het alternatief, een model finetunen op jouw data, is 10× duurder, trager om bij te werken, en minder betrouwbaar voor feitelijke retrieval. Voor 95% van de zakelijke use cases presteert RAG met een goed retrievalsysteem beter dan finetunen.
Stap 1: pgvector activeren in Supabase
Supabase wordt geleverd met pgvector ingebouwd. In de Supabase SQL-editor voer je uit: CREATE EXTENSION IF NOT EXISTS vector;
Maak daarna je documenttabel: CREATE TABLE documents ( id bigint primary key generated always as identity, content text, embedding vector(1536), metadata jsonb, created_at timestamptz default now() );
Maak een index voor snelle gelijkenis-zoekopdracht: CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops);
Dit is de enige SQL die je hoeft te schrijven.
Stap 2: Embeddings genereren met Xano
In Xano maak je een endpoint dat een tekstreeks accepteert, de OpenAI Embeddings API aanroept (text-embedding-3-small) en het resultaat opslaat in je Supabase documents-tabel.
De function stack: (1) Haal tekstinput op, (2) Roep OpenAI API POST /v1/embeddings aan, (3) Extraheer de embedding-array uit de respons, (4) Voeg in in Supabase via de Supabase API-koppeling.
Voer dit uit voor elk document, artikel of FAQ-item waarvan je wilt dat je AI het kent.
Stap 3: Semantisch zoeken in Xano
Maak een tweede endpoint dat: (1) Een gebruikersvraagstring accepteert, (2) Een embedding genereert voor de vraag (dezelfde OpenAI-aanroep), (3) Een vectorgelijkenis-zoekopdracht uitvoert in Supabase.
De Supabase RPC-functie hiervoor: SELECT content, 1 - (embedding <=> query_embedding) as similarity FROM documents ORDER BY embedding <=> query_embedding LIMIT 5;
Dit retourneert de 5 meest semantisch relevante passages voor de vraag van de gebruiker.
Stap 4: Het antwoord genereren met GPT-4o
Met de opgehaalde passages roep je de OpenAI Chat Completions API aan. De systeemprompt:
"Je bent een behulpzame assistent. Beantwoord de vraag van de gebruiker ALLEEN met de hieronder verstrekte context. Als het antwoord niet in de context staat, zeg dat dan.
Context: [VOEG OPGEHAALDE PASSAGES HIER IN]"
Dit verankert het antwoord van de LLM in je werkelijke data en voorkomt hallucinaties.
Stap 5: Bouw de chat-UI in WeWeb
In WeWeb maak je een chatinterface met een berichtenlijst en een invoerveld. Bij verzenden: roep je Xano zoekendpoint aan, stream daarna het GPT-antwoord met Xano's streamingondersteuning of een directe OpenAI-aanroep vanuit WeWeb's aangepaste code.
Voor productie voeg je toe: berichtengeschiedenis (opslaan in Supabase), broncitaties (toon welke documenten werden opgehaald) en een feedbackmechanisme (duim omhoog/omlaag om ophaal-kwaliteit te verbeteren).
Het juiste embeddingmodel kiezen
OpenAI biedt in 2025 drie embeddingmodellen: text-embedding-3-small (1536 dimensies, $0,02/1M tokens), text-embedding-3-large (3072 dimensies, $0,13/1M tokens), en het verouderde text-embedding-ada-002. Voor de meeste RAG-toepassingen is text-embedding-3-small de juiste keuze: het balanceert kosten, snelheid en retrievalkwaliteit voor standaard documentzoeken.
text-embedding-3-large is het overwegen waard wanneer retrievalprecisie cruciaal is, juridische contractanalyse, medisch literatuuronderzoek, of toepassingen waarbij een gemiste relevante passage betekenisvolle gevolgen heeft. In onze projecten hebben we 3-small vs 3-large gebenchmarkt op een kennisbank van 10.000 documenten, en 3-small behaalde 94% van de retrievalnauwkeurigheid van 3-large tegen 15% van de kosten.
Voor meertalige toepassingen (gangbaar in ons Europese klantenbestand) verwerken beide OpenAI-modellen Frans, Duits, Zweeds en Nederlands redelijk goed. Voor gespecialiseerde branche-terminologie in niet-Engelse talen kun je echter overwegen om te testen tegen meertalig-specifieke modellen zoals Cohere's multilingual-22-12 via de Cohere API als benchmark.
Chunkingstrategieën: de verborgen variabele in RAG-kwaliteit
Hoe je je documenten in chunks opdeelt, is aantoonbaar de belangrijkste variabele voor RAG-kwaliteit, invloedrijker dan modelkeuze voor de meeste toepassingen. Te groot en je opgehaalde chunks bevatten irrelevante inhoud die de LLM in verwarring brengt. Te klein en je verliest de context die de LLM nodig heeft om coherent te antwoorden.
In onze productie-RAG-projecten gebruiken we een hybride chunkingstrategie: eerst splitsen op alineagrenzen (natuurlijke semantische eenheden), en dan een maximale chunkgrootte van 512 tokens en een minimum van 100 tokens afdwingen. Chunks die te klein zijn, worden samengevoegd met hun buur. Dit behoudt semantische coherentie en voorkomt te grote chunks. Voor gestructureerde documenten (FAQ-pagina's, productspecificaties) chunken we op het niveau van vraag-en-antwoord of sectie in plaats van op tokenaantal.
Een vaak over het hoofd geziene techniek: voeg overlap toe tussen chunks. Als chunk N eindigt bij zin 10 en chunk N+1 begint bij zin 11, gaat context die de grens overbrugt verloren. Wij voegen een overlap van 50 tokens toe, zinnen 9-10 van chunk N worden herhaald aan het begin van chunk N+1. Deze overhead van 10% verbetert retrieval aanzienlijk voor vragen die verwijzen naar concepten die chunkgrenzen overschrijden.
Vectorgelijkenisdrempels en retrieval-tuning
Niet alle opgehaalde chunks zijn even relevant. De cosinusgelijkenis-score die pgvector retourneert, loopt van 0 (geen gelijkenis) tot 1 (identiek). In de praktijk scoren relevante chunks doorgaans boven 0,75, en zou je alles onder 0,60 moeten filteren om te voorkomen dat je irrelevante context aan de LLM voedt.
Voeg in je Supabase RPC-functie een gelijkenisdrempel toe: WHERE 1 - (embedding <=> query_embedding) > 0.70 ORDER BY embedding <=> query_embedding LIMIT 5. Begin met 0,70 en stem af op basis van je data. Zegt je assistent "Ik heb daar geen informatie over" bij vragen waarvan je weet dat hij ze zou moeten kunnen beantwoorden, verlaag dan de drempel. Geeft hij antwoorden op basis van zwak gerelateerde chunks, verhoog hem dan.
Implementeer voor geavanceerde retrieval een hybride zoekopdracht die vectorgelijkenis combineert met trefwoordzoeken (PostgreSQL's ingebouwde full-text search). Deze hybride aanpak, vaak "reciprocal rank fusion" genoemd, verbetert de precisie voor vragen met specifieke eigennamen, productnamen of technische termen die embeddings soms slecht verwerken. Supabase ondersteunt zowel vector- als full-text search native, waardoor hybride retrieval haalbaar is zonder aangepaste infrastructuur.
Kostenoptimalisatie voor productie-RAG
De belangrijkste kostenfactoren in een RAG-systeem zijn: embeddinggeneratie (wanneer je nieuwe documenten toevoegt), embeddingqueries (elk gebruikersbericht), en LLM-inferentie (elke GPT-4o-aanroep). Voor een typische interne kennisbank met 5.000 documenten en 500 dagelijkse vragen ziet de maandelijkse kostenopbouw er ongeveer zo uit: embedding-ingestie (eenmalig) $0,20, dagelijkse queryembeddings $0,30/maand, GPT-4o-antwoorden met gemiddeld 3.000 tokens context $45/maand. Totaal: ruwweg $50/maand voor 500 dagelijkse gebruikers.
Implementeer om LLM-kosten te verlagen een cachinglaag voor veelvoorkomende vragen. Sla de top 100 vragen en hun antwoorden op in Supabase. Controleer vóór het aanroepen van GPT-4o of een semantisch vergelijkbare vraag recent is beantwoord (cosinusgelijkenis > 0,95 met een gecachte query-embedding). Cache-hits serveren het opgeslagen antwoord direct, geen LLM-aanroep nodig. In onze productie-RAG-apps zijn 30-40% van de vragen cache-hits, wat de LLM-kosten met een derde verlaagt.
Overweeg voor toepassingen met een zeer hoog volume om de antwoordgeneratie voor eenvoudige vragen over te schakelen van GPT-4o naar GPT-4o-mini. Implementeer een routeringslaag die vragen classificeert als eenvoudig (feitelijke opzoeking, antwoord uit één bron) versus complex (synthese uit meerdere bronnen, analyse), en route eenvoudige vragen naar het goedkopere model. Deze hybride LLM-aanpak verlaagt de inferentiekosten met 60-70% bij typische kennisbank-workloads.
Productieoverwegingen: betrouwbaarheid, monitoring en dataversheid
Productie-RAG-systemen hebben operationele vereisten die prototype-tutorials negeren. De actualiteit van documenten is cruciaal: als je kennisbank verouderd is, geeft je AI verkeerde antwoorden met een overtuigend klinkende toon. Implementeer een geautomatiseerde her-ingestiepijplijn: wanneer een document wordt bijgewerkt in je CMS of database, activeer dan een Xano-achtergrondtaak om de betreffende chunks opnieuw te embedden en de vectorindex bij te werken.
Monitoring in productie betekent het volgen van: querylatency (embedding + retrieval + LLM samen, zou onder 3 seconden moeten blijven voor een goede UX), retrievalkwaliteit (log de gelijkenisscores van opgehaalde chunks, een daling in de gemiddelde score signaleert dat je documentenset mogelijk recente vragen niet dekt), en gebruikerstevredenheid (duim omhoog/omlaag-feedback opgeslagen in Supabase, wekelijks beoordeeld). In onze projecten is de wekelijkse review van laag-gewaardeerde antwoorden de meest effectieve kwaliteitsverbeteringsactiviteit.
Voeg voor data-isolatie in multi-tenant RAG-apps een workspace_id-kolom toe aan je documents-tabel en neem deze op in elke RLS-policy en elke retrievalquery. De kennisbank van elke tenant is volledig geïsoleerd, een gebruiker kan alleen antwoorden ophalen en ontvangen uit zijn eigen documenten. Dit is niet-onderhandelbaar voor elke app die vertrouwelijke bedrijfsdata verwerkt, en de RLS van Supabase maakt het eenvoudig om dit correct te implementeren.