Wat is RAG en waarom elke ontwikkelaar het zou moeten weten
I Groot taalmodel (LLM) ze hebben een revolutie teweeggebracht in de manier waarop we met mensen omgaan informatie, maar ze kampen met een fundamenteel probleem: hun kennis is statisch, bevroren tijdens de training. Wanneer u een LLM vraagt naar uw documentatie intern, op uw producten of op basis van bijgewerkte gegevens, zal het antwoord generiek, verzonnen of eenvoudigweg zijn verkeerd. Dit fenomeen heet hallucinatie.
Retrieval-augmented generatie (RAG) lost dit probleem op door krachten te bundelen generatief van LLM's met de precisie van een systeem voor het ophalen van informatie. In plaats van te vertrouwen alleen naar het modelgeheugen zoekt RAG eerst naar relevante documenten in een kennisbank en daar biedt context voor het model om nauwkeurige, op gegevens gebaseerde antwoorden te genereren.
In dit eerste artikel van de serie AI voor webontwikkelaars, zullen we RAG verkennen diepgaand: wat het is, hoe het werkt, wanneer je het moet gebruiken en wanneer je het moet vermijden. Aan het einde heb je er een een goed begrip van de RAG-architectuur en u bent klaar om deze in het volgende artikel te implementeren.
Serieoverzicht
| # | Item | Focus |
|---|---|---|
| 1 | Je bent hier - Wat is RAG | Funderingen en architectuur |
| 2 | RAG met TypeScript en LangChain.js | Praktische implementatie |
| 3 | Vectordatabase voor webontwikkelaars | Zoeken naar opslag en overeenkomsten |
| 4 | OpenAI en antropische API's | LLM-integratie |
| 5 | LLM Lokaal met Ollama | Modellen op locatie |
| 6 | Verfijning versus RAG | Wanneer wat te gebruiken |
| 7 | AI-agenten: architectuur | Autonome systemen |
| 8 | AI in de CI/CD-pijplijn | DevOps-automatisering |
Wat je gaat leren
- Wat is RAG en welk probleem lost het op?
- De volledige architectuur van een RAG-systeem (retrieval + generatie).
- Hoe insluitingen en zoeken naar overeenkomsten werken
- Chunking-strategieën voor het voorbereiden van documenten
- Het verschil tussen RAG en finetuning
- Real use cases: chatbot, semantisch zoeken, vraag en antwoord
- Beperkingen van RAG en wanneer het NIET te gebruiken
1. Het probleem: LLM en statische kennis
Stel je voor dat je een chatbot wilt bouwen voor de klantenondersteuning van je bedrijf. Je hebt er duizenden documentatiepagina's, veelgestelde vragen, technische handleidingen en opgeloste tickets. Je gebruikt een LLM zoals GPT-4 of Claude, maar het resultaat is teleurstellend: het model kent uw producten niet, het bedenkt niet-bestaande functies en biedt onjuiste procedures met absolute zekerheid.
De drie fundamentele problemen van LLM's
| Probleem | Beschrijving | Invloed |
|---|---|---|
| Kennisafsluiting | Het model kent alleen de trainingsgegevens | Het weet niets over uw bedrijfseigen gegevens |
| Hallucinaties | Genereer plausibele maar valse antwoorden | Onjuiste informatie met veel vertrouwen |
| Geen citaat | Hij kan de bron van de informatie niet aangeven | Kan de juistheid niet verifiëren |
Deze problemen worden niet eenvoudigweg opgelost met een betere prompt. We hebben echte gegevens nodig, bijgewerkt en specifiek voor uw domein. En dat is precies wat RAG doet.
2. Wat is RAG: Retrieval-Augmented Generation
VOD het is een architectuur die twee verschillende fasen combineert: de ophalen (ophalen) van relevante documenten uit een kennisbank is de generatie (generatie) van een antwoord op basis van die documenten. De term werd in 2020 geïntroduceerd door onderzoekers door Meta AI in de paper "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks".
Het idee is eenvoudig maar krachtig: voordat je het model vraagt een antwoord te genereren, zoek naar documenten die het meest relevant zijn voor de vraag van de gebruiker en voeg deze in de prompt in als extra context. Het model hoeft niet langer alles te ‘onthouden’, het hoeft alleen maar te redeneren op de verstrekte informatie.
LLM TRADIZIONALE:
Domanda utente --> [LLM] --> Risposta (basata solo su training data)
^-- Rischio allucinazione alto
RAG:
Domanda utente --> [Retrieval] --> Documenti rilevanti
|
v
Domanda + Documenti --> [LLM] --> Risposta (basata su dati reali)
^-- Rischio allucinazione basso
Praktische analogie
Beschouw RAG als één student tijdens een openboekexamen. De traditionele LLM hij is een student die uit zijn hoofd moet antwoorden: hij weet veel, maar hij kan in de war raken of iets bedenken. Met RAG kan de student zijn aantekeningen en boeken raadplegen voordat hij antwoordt. Het antwoord zal nauwkeuriger zijn omdat het gebaseerd is op concrete bronnen.
3. De complete architectuur van een RAG-systeem
Een RAG-systeem bestaat uit twee hoofdleidingen: de indexeringspijplijn (offline, eenmalig of periodiek uitgevoerd) en de querypijplijn (wordt in realtime uitgevoerd bij elke gebruikersvraag).
3.1 Indexeringspijplijn (offline)
In deze fase worden documenten voorbereid voor onderzoek. De stappen zijn:
[Documenti Sorgente]
|
v
[1. Document Loader] -- Carica PDF, HTML, Markdown, CSV, database
|
v
[2. Text Splitter] --- Divide in chunk di dimensione gestibile
|
v
[3. Embedding Model] - Trasforma ogni chunk in un vettore numerico
|
v
[4. Vector Store] ---- Salva i vettori in un database vettoriale
3.2 Querypijplijn (online)
Deze fase behandelt de gebruikersvraag in realtime:
[Domanda Utente]
|
v
[1. Embedding Model] --- Stessa funzione usata nell'indicizzazione
|
v
[2. Similarity Search] - Cerca i chunk più simili nel vector store
|
v
[3. Context Assembly] -- Assembla i chunk trovati in un contesto
|
v
[4. Prompt Template] --- "Rispondi alla domanda basandoti su: [contesto]"
|
v
[5. LLM Generation] --- Genera la risposta finale
|
v
[Risposta con Citazioni]
Let op de consistentie van de inbedding
Het is essentieel om het te gebruiken hetzelfde inbeddingsmodel beide in de fase van indexeren dan in de queryfase. Als u verschillende modellen gebruikt, zullen de vectoren dat niet zijn vergelijkbaar en het zoeken naar overeenkomsten zal niet correct werken.
4. Inbedding: het hart van RAG
De inbedding het zijn numerieke representaties (vectoren) van tekst die vastleggen de semantische betekenis. Twee zinnen met een vergelijkbare betekenis hebben "near"-vectoren in de multidimensionale ruimte, zelfs als ze totaal andere woorden gebruiken.
Frase: "Il gatto dorme sul divano"
Embedding: [0.23, -0.45, 0.67, 0.12, -0.89, ...] // vettore a 1536 dimensioni
Frase: "Il felino riposa sul sofa"
Embedding: [0.22, -0.44, 0.68, 0.11, -0.88, ...] // vettore molto simile!
Frase: "Il prezzo dell'oro sale"
Embedding: [-0.56, 0.78, -0.12, 0.91, 0.34, ...] // vettore molto diverso
Populaire insluitingssjablonen
| Model | Afmetingen | Aanbieders | Kosten |
|---|---|---|---|
text-embedding-3-small |
1536 | Open AI | $ 0,02 / 1 miljoen tokens |
text-embedding-3-large |
3072 | Open AI | $ 0,13 / 1 miljoen tokens |
voyage-3 |
1024 | Reis AI | $ 0,06 / 1 miljoen tokens |
all-MiniLM-L6-v2 |
384 | Knuffelgezicht (gratis) | Gratis (zelf gehost) |
nomic-embed-text |
768 | Ollama (lokaal) | Gratis (lokaal) |
La cosinus gelijkenis is de meest voorkomende maatstaf voor vergelijk inbedden. Meet de hoek tussen twee vectoren: een waarde van 1,0 geeft vectoren aan identiek, 0,0 duidt op geen verband, -1,0 duidt op tegengestelde betekenissen.
function cosineSimilarity(a: number[], b: number[]): number {
if (a.length !== b.length) {
throw new Error('I vettori devono avere la stessa lunghezza');
}
let dotProduct = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
// Esempio d'uso
const embedding1 = [0.23, -0.45, 0.67, 0.12];
const embedding2 = [0.22, -0.44, 0.68, 0.11];
const similarity = cosineSimilarity(embedding1, embedding2);
console.log(similarity); // ~0.999 - molto simili!
5. Chunking-strategieën
Il chunking is het proces waarbij documenten in fragmenten worden verdeeld (stukje) van hanteerbare omvang. Deze fase is van cruciaal belang: te grote brokken verspreiden zich wat betekent dat brokken die te klein zijn, hun context verliezen.
Key Chunking-parameters
- Brokgrootte: De maximale grootte van elk fragment (in tekens of tokens). Meestal 500-2000 tekens
- Stukoverlap: De overlap tussen opeenvolgende chunks (10-20% van de chunkgrootte). Vermijd het halverwege afsnijden van concepten
- Afscheiders: De punten waarop knippen de voorkeur heeft (paragrafen, zinnen, titels)
FIXED SIZE CHUNKING:
Testo: "AAAA|BBBB|CCCC|DDDD" (ogni | = taglio ogni N caratteri)
Pro: Semplice e veloce
Contro: Può tagliare a meta frasi e concetti
RECURSIVE CHARACTER SPLITTING:
Testo diviso per: "\n\n" -> "\n" -> "." -> " " -> ""
Pro: Rispetta la struttura del testo
Contro: Chunk di dimensioni variabili
SEMANTIC CHUNKING:
Usa embeddings per trovare i "punti di rottura" semantici
Pro: Chunk coerenti semanticamente
Contro: Più lento e costoso (richiede embeddings)
DOCUMENT-AWARE CHUNKING:
Rispetta la struttura del documento (titoli, sezioni, tabelle)
Pro: Mantiene il contesto strutturale
Contro: Richiede parsing specifico per formato
Documento originale (600 caratteri):
"Angular è un framework TypeScript per applicazioni web.
Supporta il rendering lato server (SSR) per migliorare
le performance. I componenti standalone eliminano la
necessità di NgModule. I Signals offrono reattività
fine-grained senza Zone.js."
Con chunk_size=200, overlap=50:
Chunk 1: "Angular è un framework TypeScript per applicazioni web.
Supporta il rendering lato server (SSR) per migliorare
le performance."
Chunk 2: "per migliorare le performance. I componenti standalone
eliminano la necessità di NgModule."
Chunk 3: "eliminano la necessità di NgModule. I Signals offrono
reattività fine-grained senza Zone.js."
Veel voorkomende fouten bij het chunken
- Te grote brokken (>4000 tokens): Het model negeert mogelijk delen van de context of overschrijdt de tokenlimiet
- Chunks te klein (<100 tokens): Verlies van context, gefragmenteerde antwoorden
- Nul overlap: Concepten gehalveerd, herstel onvolledig
- Metagegevens negeren: Verlies van informatie zoals titel, auteur, datum van het document
6. RAG versus fijnafstemming: wanneer wat te gebruiken
Een van de meest voorkomende vragen is: "Moet ik RAG gebruiken of het model verfijnen?". Het antwoord hangt af van het soort kennis dat u wilt toevoegen en hoe deze zal worden gebruikt.
RAG versus fijnafstemming - gedetailleerde vergelijking
| Ik wacht | VOD | Fijnafstelling |
|---|---|---|
| Soort kennis | Specifieke feiten, gegevens, documenten | Stijl, formaat, gedrag |
| Update | Direct (documenten bijwerken) | Vereist herscholing |
| Initiële kosten | Laag (infrastructuur + inbedding) | Hoog (GPU, gelabelde gegevens, tijd) |
| Kosten per zoekopdracht | Medium (ophalen + genereren) | Laag (alleen generatie) |
| Traceerbaarheid | Hoog (je kunt bronnen citeren) | Geen (geïntegreerde kennis) |
| Hallucinaties | Verminderd (echte gegevens in context) | Mogelijk (kennis geleerd) |
| Schaalbaarheid van gegevens | Miljoenen documenten | Beperkt per trainingsset |
| Complexiteit | Media (pijplijn + vector-DB) | Hoog (training, evaluatie, inzet) |
Praktische regel
VS VOD wanneer u wilt dat het model specifieke informatie "weet". (documenten, veelgestelde vragen, handleidingen). VS fijnafstemming wanneer u het model wilt zich op een bepaalde manier ‘gedragen’ (toon, format, reactiestijl). In veel gevallen de combinatie van de twee benaderingen levert de beste resultaten op.
7. Echte gebruiksscenario's van RAG
RAG is niet alleen maar theorie: het is de basis van veel producten die we dagelijks gebruiken. Hier volgen de meest voorkomende gebruiksscenario's en hoe RAG deze mogelijk maakt.
7.1 Zakelijke chatbots
De meest populaire gebruikscasus. Een chatbot die klantvragen beantwoordt op basis van op de echte documentatie van het bedrijf: handleidingen, veelgestelde vragen, opgeloste tickets, intern beleid.
// Pseudocodice di un chatbot RAG
async function handleUserQuery(query: string): Promise<string> {
// 1. Cerca documenti rilevanti
const relevantDocs = await vectorStore.similaritySearch(query, 5);
// 2. Costruisci il contesto
const context = relevantDocs
.map(doc => `[Fonte: ${doc.metadata.source}]\n${doc.pageContent}`)
.join('\n\n');
// 3. Genera la risposta con contesto
const response = await llm.invoke(`
Sei un assistente del supporto clienti.
Rispondi SOLO basandoti sulle informazioni fornite.
Se non trovi la risposta nei documenti, dillo esplicitamente.
DOCUMENTI DI RIFERIMENTO:
${context}
DOMANDA DEL CLIENTE:
${query}
RISPOSTA:
`);
return response;
}
7.2 Semantisch zoeken
In tegenstelling tot traditioneel zoeken op trefwoord, semantisch zoeken met RAG omvat de betekenis van de vraag. "Hoe u uw wachtwoord opnieuw kunt instellen" levert resultaten op ook al staat er in het document "procedure voor het herstellen van inloggegevens".
7.3 Vragen en antwoorden over documenten
Hiermee kunnen gebruikers vragen in natuurlijke taal stellen over grote verzamelingen documenten: juridische contracten, technische documentatie, wetenschappelijke artikelen, interne kennisbanken.
7.4 Code-assistent
Een codeassistent die uw specifieke codebase kent. Indexeer de broncode, API-documentatie, opmerkingen en tests om gecontextualiseerde suggesties te bieden.
Vergelijking van gebruiksscenario's
| Gebruikscasus | Gegevensbron | Frequentie bijwerken | Complexiteit |
|---|---|---|---|
| Chatbot-ondersteuning | Veelgestelde vragen, handleidingen, tickets | Wekelijks | Gemiddeld |
| Semantisch zoeken | Productcatalogus, artikelen | Dagelijks | Laag |
| Vraag- en antwoorddocumenten | PDF, contracten, rapporten | Op aanvraag | Gemiddeld |
| Code-assistent | Broncode, API-documenten | Bij elke verplichting | Hoog |
8. Anatomie van een complete RAG-pijplijn
Laten we elk onderdeel van de pijplijn in detail bekijken, met de technologische keuzes waar u bij de uitvoering mee te maken krijgt.
+------------------+--------------------------------------------+
| Componente | Opzioni Tecnologiche |
+------------------+--------------------------------------------+
| Document Loader | LangChain loaders, Unstructured, custom |
| Text Splitter | RecursiveCharacter, Semantic, Markdown |
| Embedding Model | OpenAI, Voyage, HuggingFace, Ollama |
| Vector Store | Pinecone, Chroma, Weaviate, pgvector |
| Retriever | Similarity, MMR, Self-Query, Ensemble |
| Prompt Template | LangChain templates, custom |
| LLM | GPT-4, Claude, Llama, Mistral |
| Post-processing | Citation extraction, confidence scoring |
+------------------+--------------------------------------------+
8.1 Documentladers
Documentladers extraheren tekst uit verschillende bronnen. De kwaliteit van de extractie heeft rechtstreeks invloed op de kwaliteit van de antwoorden.
Formato | Loader Consigliato | Note
-----------------+---------------------------+---------------------------
PDF | PDFLoader, PyPDFLoader | Attenzione a tabelle/immagini
HTML/Web | CheerioWebBaseLoader | Rimuove tag, estrae testo
Markdown | MarkdownTextSplitter | Preserva la struttura
CSV/Excel | CSVLoader | Una riga = un documento
JSON | JSONLoader | Configura il percorso dati
Database SQL | Custom loader | Query -> documenti
Confluence/Notion| API-based loader | Richiede autenticazione
Codice sorgente | TextLoader + filtri | Splitta per funzione/classe
8.2 Retriever: verder zoeken dan gelijkenis
De retriever vindt niet alleen de meest vergelijkbare brokken. Er zijn geavanceerde strategieën om de kwaliteit van het herstel te verbeteren.
Ophaalstrategieën
- Gelijkenis zoeken: De k-chunks met de hoogste gelijkenisscore. Eenvoudig maar effectief
- MMR (maximale marginale relevantie): Breng relevantie en diversiteit in evenwicht. Vermijd stukken die te veel op elkaar lijken
- Zelf-query: Het model haalt filters uit de vraag (bijvoorbeeld 'documenten uit 2024' filtert op datum)
- Ensemble: Combineer resultaten van meerdere retrievers (bijvoorbeeld trefwoorden + semantiek) voor een betere dekking
- Bovenliggend document: Haalt het relevante deel op, maar retourneert het bovenliggende document voor de volledige context
9. Beperkingen van RAG en wanneer deze NIET te gebruiken
RAG is geen magische oplossing. Zoals elke architectuur heeft het beperkingen waarvan u zich bewust moet zijn alvorens het over te nemen.
Wanneer RAG NIET de juiste keuze is
- Complexe redenering: RAG levert feiten, geen redeneringen. Voor analyse in meerdere stappen of complexe logische gevolgtrekkingen moet het model zijn eigen mogelijkheden hebben
- Gestructureerde gegevens: Als u SQL-aggregaties, berekeningen of joins tussen tabellen nodig heeft, gebruik dan een relationele database en niet RAG
- Ultrasnelle realtime reacties: De ophaalpijplijn voegt latentie toe (100-500 ms). Als u antwoorden nodig heeft binnen <50 ms, overweeg dan caching
- Kennisbank te klein: Met weinig documenten (<10 pagina's) kunt u alles in de prompt passen zonder dat u deze hoeft op te halen
- Zeer dynamische gegevens: Als de gegevens elke seconde veranderen (bijvoorbeeld de aandelenkoersen), is RAG niet snel genoeg met het bijwerken
Veelvoorkomende problemen en oplossingen
| Probleem | Oorzaak | Oplossing |
|---|---|---|
| Irrelevante antwoorden | Te groot stuk | Verklein de brokgrootte, vergroot de overlap |
| Hij antwoordt te vaak: 'Ik weet het niet' | Ophalen te beperkend | Verhoog k (aantal resultaten), gebruik MMR |
| Aanhoudende hallucinaties | Onvoldoende of dubbelzinnige context | Verbeter de prompt, voeg expliciete instructies toe |
| Hoge latentie | Te veel stukjes in context | Verlaag k, gebruik herrangschikking |
| Hoge kosten | Te veel tokens per query | Comprimeer brokken, gebruik goedkopere modellen |
10. Evaluatiestatistieken voor RAG
Om te weten of uw RAG-systeem goed werkt, moet u het meten. Dit zijn de belangrijkste statistieken.
RAG-statistieken
| Metrisch | Wat het meet | Doel |
|---|---|---|
| Contextrelevantie | Zijn de opgehaalde documenten relevant voor de aanvraag? | > 0,8 |
| Trouw | Is het antwoord gebaseerd op de verstrekte documenten? | > 0,9 |
| Antwoord Relevantie | Is het antwoord relevant voor de vraag? | > 0,85 |
| Latentie | Totale tijd om te reageren | < 3 seconden |
| Hallucinatiepercentage | Percentage claims dat niet door documenten wordt ondersteund | < 5% |
Tool di Valutazione:
- RAGAS (Retrieval Augmented Generation Assessment)
- LangSmith (by LangChain) - tracing e valutazione
- Phoenix (by Arize) - osservabilità LLM
- DeepEval - framework di testing per LLM
- TruLens - valutazione feedback-driven
Metriche Composite:
RAG Score = (Context Relevance + Faithfulness + Answer Relevance) / 3
Volgende stappen
In dit artikel heb je een goed inzicht gekregen in RAG: wat het is, hoe het werkt, de belangrijkste componenten van de architectuur en wanneer deze te gebruiken (of niet te gebruiken). Je hebt de rol begrepen basisprincipes van inbedding, chunking-strategieën en evaluatiestatistieken.
In de volgend artikel we gaan van theorie naar praktijk: we gaan implementeren een compleet RAG-systeem met behulp van TypeScript en LangChain.js, met een vector echte winkel en een conversatie-interface met geheugen.
Aanvullende bronnen
- Origineel RAG-papier: “Retrieval-Augmented Generation voor kennisintensieve NLP-taken” (Lewis et al., 2020)
- LangChain.js-documenten: Officiële documentatie voor implementatie in TypeScript
- OpenAI-kookboek: Praktische voorbeelden van RAG met OpenAI API's
- Pinecone Leercentrum: Gidsen over vectordatabases en inbedding
- RAGAS: Open-source raamwerk voor het evalueren van RAG-systemen







