# Lokaal RAG draaien: van embedding tot antwoord

[Naar de inhoud](#lm-inhoud)Netwerk/NL[EN](/en/)[Hubhub.llmnet.nlModellen vergelijken op taak, taal, kosten en licentie.](https://hub.llmnet.nl/)[Communitycommunity.llmnet.nlPrompttechnieken, patronen en systeemprompts.](https://community.llmnet.nl/)[APIapi.llmnet.nlLLM's robuust in software: rate limits, routing, structured output.](https://api.llmnet.nl/)[Consultancyconsultancy.llmnet.nlAI invoeren in een organisatie, van pilot tot productie.](https://consultancy.llmnet.nl/)[Nieuwsnieuws.llmnet.nlOntwikkelingen in AI, geduid voor Nederland.](https://nieuws.llmnet.nl/)[Benchmarkbenchmark.llmnet.nlZelf meten wat AI-kwaliteit is, voor jouw taken.](https://benchmark.llmnet.nl/)[Vacaturesvacatures.llmnet.nlAI-rollen, salarissen en carrièrepaden in Nederland.](https://vacatures.llmnet.nl/)[Lerenleren.llmnet.nlAI-concepten in gewoon Nederlands, van beginner tot bouwer.](https://leren.llmnet.nl/)[Gidsgids.llmnet.nlAI privé draaien op eigen Mac, pc, NAS of thuisserver.](https://gids.llmnet.nl/)[Directorydirectory.llmnet.nlHet AI-ecosysteem in kaart: tools, modellen, bedrijven.](https://directory.llmnet.nl/)[Radarradar.llmnet.nlSignalen uit X, onderzoek en communities voor indie developers.](https://radar.llmnet.nl/)[llmnet.nl — hoofdsite](https://llmnet.nl/)[](https://x.com/intent/post?url=https%3A%2F%2Fgids.llmnet.nl%2Flokaal-rag-draaien-van-embedding-tot-antwoord&text=Lokaal%20RAG%20draaien%3A%20van%20embedding%20tot%20antwoord)[](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fgids.llmnet.nl%2Flokaal-rag-draaien-van-embedding-tot-antwoord)[](https://www.reddit.com/submit?url=https%3A%2F%2Fgids.llmnet.nl%2Flokaal-rag-draaien-van-embedding-tot-antwoord&title=Lokaal%20RAG%20draaien%3A%20van%20embedding%20tot%20antwoord)[](#)[](https://x.com/intent/post?url=https%3A%2F%2Fgids.llmnet.nl%2Flokaal-rag-draaien-van-embedding-tot-antwoord&text=Lokaal%20RAG%20draaien%3A%20van%20embedding%20tot%20antwoord)[](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fgids.llmnet.nl%2Flokaal-rag-draaien-van-embedding-tot-antwoord)[](https://www.reddit.com/submit?url=https%3A%2F%2Fgids.llmnet.nl%2Flokaal-rag-draaien-van-embedding-tot-antwoord&title=Lokaal%20RAG%20draaien%3A%20van%20embedding%20tot%20antwoord)[](#)

 
# Lokaal RAG draaien: van embedding tot antwoord

 Door Ivo Donker — samengesteld met AI-ondersteuning (Claude & Gemini) · 15 augustus 2026

 
 
### Referentieopstelling & systeembeslag

 Hardware: 8-core CPU, 32 GB RAM, NVIDIA RTX 4070 (12 GB VRAM) of Apple Silicon M-serie (36 GB Unified Memory).
 Embeddingmodel: BAAI/bge-m3 (1024 dimensies, 560M parameters, FP16 ~1.1 GB VRAM of Q8_0 ~600 MB).
 Generatief model: Qwen 2.5 7B Instruct (Q4_K_M kwantisatie, contextlengte 8192 tokens, ~5.2 GB VRAM).
 Vectordatabase: Qdrant lokaal via Docker of embedded Chroma (in-memory met persistentie op SSD).

 

 Binnen de route van lokaal taalmodellen draaien bevindt dit artikel zich in de fase koppelen en verrijken. Nadat een lokaal model geïnstalleerd is en naar behoren functioneert, ontstaat direct de behoefte om het model te voeden met eigen, actuele of vertrouwelijke bronbestanden. Voor een solide basis over de benodigde rekenkracht en geheugenbandbreedte raadpleeg je het artikel over [hardware voor lokale LLMs](https://gids.llmnet.nl/hardware-voor-lokale-llm), waarin de balans tussen VRAM en CPU-geheugen wordt uitgelegd.

 Retrieval-Augmented Generation (RAG) lost de twee fundamentele beperkingen van elk taalmodel op: een statische kennislimiet en de neiging tot hallucineren. Door gerichte passages uit eigen documenten op te halen en mee te sturen in de context, baseert het model zijn antwoord direct op controleerbare bronnen. In deze complete handleiding doorlopen we de volledige keten op eigen hardware: van het inlezen en opdelen van ruwe tekst tot vectorrepresentatie, semantisch zoeken, contextinjectie en de uiteindelijke synthese.

 
## 1. De anatomie van een lokale RAG-pijplijn

 Een RAG-architectuur bestaat uit twee gescheiden fasen: de ingestiefase (offline voorbereiding) en de queryfase (real-time ophalen en genereren). In een cloudomgeving worden deze stappen vaak uitbesteed aan externe API's, maar op een lokaal systeem draaien alle componenten direct op de eigen machine. Dit garandeert volledige gegevenssoevereiniteit.

 Tijdens de ingestiefase worden documenten zoals PDF's, Markdown-notities of Word-documenten ingelezen, ontdaan van ruis, opgedeeld in semantisch samenhangende fragmenten (chunks), en omgezet in dichte numerieke vectoren (embeddings). Deze vectoren worden geïndexeerd in een lokale vectoropslag. In de queryfase zet het embeddingmodel de vraag van de gebruiker om in dezelfde vectorruimte, waarna de database de best passende tekstfragmenten selecteert op basis van cosinus-overeenkomst of dot-product.

 Het generatieve model krijgt vervolgens een gecombineerde prompt aangeboden: de systeeminstructie, de opgehaalde tekstfragmenten als bewijsmateriaal, en de oorspronkelijke vraag. Het model fungeert hierbij primair als een intelligente syntax- en redeneermotor die de context samenvat en vertaalt naar een natuurlijk antwoord, zonder te leunen op zijn eigen (mogelijk verouderde) parametrische geheugen.

 
## 2. Document parsing en chunking-strategieën

 De kwaliteit van de gegenereerde antwoorden staat of valt met de precisie van de chunking-stap. Als een tekstfragment te groot is, verdrinkt de relevante informatie in irrelevante context, wat de aandachtsmechanismen van kleinere lokale modellen overbelast. Is het fragment te klein, dan verliest de tekst zijn grammaticale en semantische samenhang.

 Voor gestructureerde Nederlandse teksten levert een recursieve karakter-splitter met semantische scheidingstekens de beste resultaten op. Hierbij splitst het algoritme eerst op dubbele regeleindes (paragrafen), vervolgens op enkele regeleindes, daarna op zinnen en pas in het uiterste geval op losse woorden. Een overlap tussen opeenvolgende fragmenten voorkomt dat cruciale zinnen precies op een breekpunt worden doormidden gesneden.

 
 
 
 
 Documenttype | 
 Aanbevolen Chunkgrootte | 
 Overlap | 
 Aandachtspunt | 
 

 
 
 
 Beleidsdocumenten & Rapporten | 
 512 tokens (~1800 tekens) | 
 64 tokens | 
 Kopregels behouden in metadata | 
 

 
 Notities & Gespreksverslagen | 
 256 tokens (~900 tekens) | 
 32 tokens | 
 Tijdstempels en sprekers labelen | 
 

 
 Broncode & Technische API-docs | 
 384 tokens (~1300 tekens) | 
 48 tokens | 
 Functiegrenzen intact laten via AST | 
 

 
 
 

 Hieronder staat een concreet Python-voorbeeld waarin ruwe tekst wordt opgedeeld met behulp van structurele ankers:

def chunk_tekst(tekst: str, chunk_size: int = 500, overlap: int = 50) -> list[str]:
 woorden = tekst.split()
 chunks = []
 stap = chunk_size - overlap
 for i in range(0, len(woorden), stap):
 segment = " ".join(woorden[i:i + chunk_size])
 if segment:
 chunks.append(segment)
 return chunks

# Voorbeeld met documentverwerking
brontektst = "Lokale AI waarborgt privacy door data binnen het eigen netwerk te houden."
fragmenten = chunk_tekst(brontektst, chunk_size=200, overlap=30)

 
## 3. Embeddings: van tekst naar compacte vectoren

 Een embeddingmodel zet tekstfragmenten om in een multidimensionale vector waarin semantische betekenis wiskundig wordt vastgelegd. Teksten die qua betekenis op elkaar lijken, komen dicht bij elkaar te liggen in de vectorruimte, ongeacht of ze exact dezelfde trefwoorden bevatten.

 Voor een Nederlandstalige RAG-toepassing is de taalkeuze van het embeddingmodel cruciaal. Veel standaardmodellen zijn primair getraind op Engelse data en verliezen veel nuance bij Nederlandse grammaticale structuren. Raadpleeg de gedetailleerde vergelijking over [het juiste embeddingmodel voor Nederlandse documenten](https://gids.llmnet.nl/welk-embeddingmodel-kies-je-voor-nederlandse-documenten) om te bepalen wanneer een meertalig model zoals BGE-M3 of een specifiek Nederlands model optimaal presteert.

 Embeddingmodellen vereisen aanzienlijk minder rekenkracht dan generatieve modellen. Een model van 500 miljoen parameters draait moeiteloos op een CPU of vereist minder dan 1.5 GB VRAM op een grafische kaart. Let bij de configuratie goed op de dimensiegrootte: 384 dimensies (zoals bij MiniLM) vereisen minder geheugen en rekenkracht bij het indexeren, terwijl 1024 dimensies (zoals bij BGE-M3) aanzienlijk meer diepte en kruisverbanden tussen complexe dossiers vasthouden.

 
## 4. Opslag en semantisch zoeken in de vectordatabase

 Zodra tekstfragmenten zijn omgezet in vectoren, moeten deze efficiënt worden opgeslagen en doorzocht. Hiervoor gebruiken we een gespecialiseerde vectordatabase die gebruikmaakt van HNSW-indexering (Hierarchical Navigable Small World) om binnen milliseconden de dichtstbijzijnde buren te vinden tussen honderdduizenden fragmenten.

 In een lokale opstelling zijn Qdrant en Chroma de meest gangbare keuzes. Wie direct aan de slag wil met de installatie en configuratie hiervan, vindt praktische instructies in de handleiding over [een lokale vectordatabase opzetten met Qdrant en Chroma](https://gids.llmnet.nl/lokale-vector-database-opzetten), waarin het persistent maken van collecties op schijf stap voor stap wordt uitgewerkt.

 Het ophalen van vectoren gebeurt meestal op basis van Cosine Similarity. De formule berekent de hoek tussen de zoekvector en de opgeslagen documentvectoren:

import numpy as np

def cosine_similarity(v1: np.ndarray, v2: np.ndarray) -> float:
 dot_product = np.dot(v1, v2)
 norm_v1 = np.linalg.norm(v1)
 norm_v2 = np.linalg.norm(v2)
 if norm_v1 == 0 or norm_v2 == 0:
 return 0.0
 return float(dot_product / (norm_v1 * norm_v2))

 
## 5. Retrieval-strategieën: puur vectorieel versus hybride en reranking

 Puur semantisch zoeken heeft een bekend zwak punt: het herkent conceptuele verbanden uitstekend, maar presteert matig op exacte trefwoorden, artikelnummers, dossiercodes of persoonsnamen. Als een document vraagt om "Factuur 2026-F44", zoekt een vectorzoeker naar het concept van een rekening in plaats van die specifieke code.

 Om dit op te lossen combineert een geavanceerde RAG-opstelling semantisch zoeken met traditioneel trefwoordzoeken (BM25). Deze hybride aanpak levert twee lijsten met resultaten op, die worden samengevoegd met Reciprocal Rank Fusion (RRF). Vervolgens beoordeelt een lichtgewicht cross-encoder (reranker) de top-20 resultaten om de meest relevante 3 tot 5 fragmenten te selecteren voor de prompt. Voor een theoretische en praktische afweging tussen deze methodes biedt het overzicht over [embeddings, rerankers of hybride retrieval](https://hub.llmnet.nl/embedding-reranker-of-hybride-welk-retrieval-model-wanneer) diepgaande vergelijkende benchmarks.

 
 
 
 
 Retrieval-methode | 
 Voordelen | 
 Nadelen / Beperkingen | 
 Lokale Latency Impact | 
 

 
 
 
 Puur Dense Vector | 
 Begrijpt synoniemen en context | 
 Mist exacte serienummers en id's | 
 Laag (5-15 ms) | 
 

 
 Hybride (Vector + BM25) | 
 Robuust op zowel concept als trefwoord | 
 Vereist dubbele indexering en RAM | 
 Gemiddeld (20-40 ms) | 
 

 
 Hybride + Cross-Encoder Rerank | 
 Hoogste precisie en contextkwaliteit | 
 Extra rekenstap per zoekopdracht | 
 Middelgroot (+50-120 ms) | 
 

 
 
 

 
## 6. Contextinjectie en promptconstructie

 Zodra de relevante tekstfragmenten zijn geselecteerd, worden deze samengevoegd in het contextvenster van het generatieve model. De manier waarop deze context wordt gestructureerd, heeft directe invloed op het redeneervermogen van het model. Wanneer bronnen ongeordend worden aangeboden, treedt vaak het 'lost in the middle'-effect op, waarbij het model informatie in het midden van de prompt negeert.

 Een beproefd prompt-sjabloon voor lokale modellen maakt gebruik van strikte scheidingsmarkeringen en duidelijke instructies om uitsluitend te antwoorden op basis van de meegeleverde context:

Je bent een betrouwbare assistent die vragen beantwoordt op basis van documenten.
Beantwoord de onderstaande vraag UITSLUITEND met behulp van de meegeleverde bronfragmenten.
Als het antwoord niet in de bronnen staat, zeg dan expliciet: "Op basis van de beschikbare documenten kan ik deze vraag niet beantwoorden."

=== BRONNEN START ===
[Bron 1 - Documentatie.pdf (pagina 4)]
Lokale RAG-architecturen vereisen geen externe netwerkverbindingen voor data-opslag.

[Bron 2 - Beleid2026.docx (sectie 2.1)]
Alle interne verslagen dienen lokaal te worden verwerkt onder Q4_K_M kwantisatie.
=== BRONNEN EINDE ===

Vraag: Welke kwantisatie moeten interne verslagen volgens het beleid gebruiken?
Antwoord:

 Bij het configureren van het generatieve model speelt het geheugenbeslag van het contextvenster een grote rol. Om het model soepel te laten draaien zonder haperingen, is een compact formaat noodzakelijk. In het artikel over [kwantisatiemethoden voor lokale modellen](https://gids.llmnet.nl/kwantisatie-uitgelegd) wordt uitgelegd hoe technieken zoals 4-bit en 5-bit GGUF-compressie ervoor zorgen dat zowel het model als de uitgebreide RAG-context binnen het VRAM-budget passen.

 
## 7. De complete integratie in Python

 Hieronder staat een compact maar functioneel Python-script dat de volledige keten verbindt: het genereren van een query-embedding, het ophalen van context uit een lokale vectorstore en het aanroepen van een lokaal taalmodel via een OpenAI-compatibele interface (zoals Ollama of llama.cpp server):

import requests
import json

OLLAMA_API = "http://localhost:11434/api"

def haal_embedding(tekst: str) -> list[float]:
 payload = {"model": "bge-m3", "prompt": tekst}
 response = requests.post(f"{OLLAMA_API}/embeddings", json=payload)
 return response.json()["embedding"]

def genereer_rag_antwoord(vraag: str, context_fragmenten: list[str]) -> str:
 context_tekst = "\n\n".join([f"- {frag}" for frag in context_fragmenten])
 system_prompt = (
 "Beantwoord de vraag feitelijk op basis van de onderstaande context.\n\n"
 f"Context:\n{context_tekst}"
 )
 
 payload = {
 "model": "qwen2.5:7b-instruct-q4_k_m",
 "messages": [
 {"role": "system", "content": system_prompt},
 {"role": "user", "content": vraag}
 ],
 "stream": False,
 "options": {"temperature": 0.1, "num_ctx": 4096}
 }
 
 res = requests.post("http://localhost:11434/v1/chat/completions", json=payload)
 return res.json()["choices"][0]["message"]["content"]

# Uitvoering
gebruikersvraag = "Wat is het stroomverbruik van de server in ruststand?"
opgehaalde_chunks = [
 "Metingen tonen aan dat de lokale server in ruststand exact 14 Watt verbruikt.",
 "Onder volledige belasting met 2 actieve streams stijgt het vermogen naar 185 Watt."
]

antwoord = genereer_rag_antwoord(gebruikersvraag, opgehaalde_chunks)
print(antwoord)

 
## 8. Kwaliteitscontrole, factchecking en foutdiagnose

 Zelfs met een zorgvuldig ingerichte RAG-keten kunnen er fouten optreden. Veelvoorkomende faalmodi zijn:

 
 
- Retrieval failure: De relevante informatie zit wel in de documenten, maar komt niet voor in de top-k resultaten door een verkeerde zoekterm of suboptimale chunking.
 
- Contextverwarring: Twee tegenstrijdige bronnen worden tegelijk in de context geplaatst, waardoor het model een willekeurige keuze maakt of beide combineert.
 
- Hallucinatie ondanks context: Het model negeert de expliciete instructie en gebruikt voorgetrainde aannames wanneer een bron vaag is geformuleerd.
 

 Om te verifiëren of de output daadwerkelijk klopt met de onderliggende bronnen, is een systematische evaluatiemethode essentieel. Zie het artikel over [het factchecken van AI-antwoorden](https://gids.llmnet.nl/ai-antwoorden-factchecken) voor praktische technieken om beweringen automatisch te vergelijken met brondocumenten en inconsistenties op te sporen.

 
## 9. Privacy, netwerkisolatie en dataveiligheid

 Het belangrijkste argument voor een lokale RAG-architectuur is de garantie dat vertrouwelijke gegevens de eigen hardware nooit verlaten. Bij cloudgebaseerde RAG-diensten passeren documenten, query's en embeddings meerdere externe servers en opslaglocaties.

 In een lokale opstelling blijft de volledige datastroom binnen het lokale netwerk of zelfs binnen één enkele machine. Er worden geen telemetriegegevens verzameld en er is geen externe API-sleutel nodig. Wie benieuwd is naar de juridische en operationele waarborgen van deze aanpak, leest in het overzicht over [privacyvriendelijk werken met AI](https://gids.llmnet.nl/privacyvriendelijk-ai) hoe een strikt lokaal model voldoet aan strenge databeschermingseisen.

 Ook in een thuissituatie of een klein kantoor voorkomt een afgeschermde omgeving dat privégegevens en persoonlijke dossiers per ongeluk op straat komen te liggen. Praktische maatregelen om systemen lokaal af te schermen worden behandeld in de gids over [veilig AI-gebruik in een thuisomgeving](https://gids.llmnet.nl/ai-veilig-thuis), waarin netwerksegmentatie en toegangsrechten centraal staan.

 
## Samenvatting en volgende stappen

 Een lokaal draaiende RAG-pijplijn transformeert een generiek open-source taalmodel tot een gespecialiseerde kennishulp die exclusief redeneert over eigen dossiers. Door zorgvuldige documentparsing, een passend embeddingmodel, persistente vectoropslag en scherpe contextinjectie ontstaat een betrouwbaar systeem dat snel reageert en volledige privacy biedt.

 Na het inrichten van de basispijplijn ligt de volgende stap in het automatiseren van evaluaties en het toevoegen van gespecialiseerde filters. Hiermee wordt de lokale RAG-infrastructuur een robuust en schaalbaar fundament voor dagelijks professioneel documentbeheer.
