Als je een chatbot bouwt die antwoorden geeft op basis van je eigen documentatie, of een zoekmachine die begrijpt wat je bedoelt in plaats van wat je letterlijk typt, dan werk je met embeddings. Ze zijn de onzichtbare laag onder vrijwel alle moderne AI-toepassingen. In deze gids demystificeren we de technologie en laten we zien hoe je hem zelf kunt toepassen.
Wat zijn embeddings?
Een embedding is een numerieke representatie van tekst (of een afbeelding, audio, etc.) als een vector: een array van getallen. De OpenAI text-embedding-3-small model zet elke tekst om naar een vector van 1536 getallen. De magie: semantisch vergelijkbare teksten krijgen vectoren die dicht bij elkaar liggen in de wiskundige ruimte. 'Hond' en 'puppy' zijn dicht bij elkaar. 'Hond' en 'hypotheek' zijn ver van elkaar.
Dit is fundamenteel anders dan keyword search. Bij keyword search zoek je naar exacte woorden. Bij vector search zoek je naar betekenis. Als een gebruiker zoekt naar 'mijn auto doet het niet', vindt een vector zoekopdracht ook artikelen over 'startproblemen', 'accu leeg' en 'motorpech' - ook al staan die exacte woorden niet in de zoekopdracht.
Embeddings en vector search uitgelegd: van concept tot implementatie
Cosine similarity: hoe meet je gelijkenis?
Cosine similarity meet de hoek tussen twee vectoren. Een score van 1.0 betekent identiek, 0.0 betekent geen gelijkenis, -1.0 betekent tegengesteld. In de praktijk gebruik je cosine similarity om te ranken welke documenten het meest relevant zijn voor een zoekopdracht. Je berekent de embedding van de zoekquery en vergelijkt hem met alle document-embeddings in je database. De top-k resultaten met de hoogste cosine similarity zijn de meest relevante documenten.
💡 Cosine vs Euclidische afstand
Gebruik cosine similarity voor tekstembeddings, niet euclidische afstand. Cosine similarity is robuust tegen de lengte van de vector (een lang document vs een korte zin produceren vergelijkbare scores bij gelijke inhoud). Euclidische afstand is beter geschikt voor embeddings waarbij de magnitude betekenis heeft, zoals afbeeldingen.
Vector databases: Pinecone, Weaviate en pgvector
Je hebt een gespecialiseerde database nodig om embeddings efficient op te slaan en te doorzoeken. Pinecone is de meest gebruikte managed vector database. Serverless, schaalt automatisch, met uitstekende API's voor Python en TypeScript. Ideaal als je snel wilt starten zonder infrastructuur te beheren. Weaviate is een open-source vector database met hybride zoekfunctionaliteit (vector en keyword gecombineerd). Je kunt hem self-hosted draaien of als cloud service gebruiken.
Pgvector is een PostgreSQL extensie die vector opslag en zoeken toevoegt aan je bestaande Postgres database. Als je al Postgres draait, is dit de eenvoudigste manier om vector search toe te voegen zonder een nieuwe database te introduceren. Supabase biedt pgvector out-of-the-box aan in hun hosted PostgreSQL service. Voor de meeste applicaties is pgvector de pragmatische keuze tot je miljoenen vectoren hebt.
RAG-architectuur: embeddings in de praktijk
RAG staat voor Retrieval Augmented Generation. Dit is de architectuur die embeddings combineert met taalmodellen om vragen te beantwoorden op basis van je eigen documenten. Het werkt in drie stappen. Stap 1 (Indexing): splits je documenten op in chunks van 500-1000 tokens. Genereer een embedding voor elk chunk. Sla de embedding en de originele tekst op in je vector database.
Stap 2 (Retrieval): als een gebruiker een vraag stelt, genereer je een embedding van die vraag. Zoek in je vector database naar de top-k meest vergelijkbare chunks. Stap 3 (Generation): stuur de vraag samen met de gevonden chunks als context naar een taalmodel (Claude, GPT-4o). Het model genereert een antwoord gebaseerd op de gevonden informatie. Dit is hoe moderne AI-assistenten die 'je documentatie kennen' werken.
⚠️ Chunk size is cruciaal
De grootte van je chunks heeft grote invloed op de kwaliteit van je RAG systeem. Te kleine chunks missen context. Te grote chunks voegen ruis toe en passen mogelijk niet in het context window van het model. Begin met chunks van 500-800 tokens met een overlap van 100 tokens. Experiment met je specifieke content en meet de retrieval kwaliteit.
OpenAI Embeddings API in de praktijk
De OpenAI Embeddings API is simpel te gebruiken. Installeer de openai library en maak een call naar client.embeddings.create(model='text-embedding-3-small', input='Jouw tekst hier'). De response bevat een embedding vector die je kunt opslaan. Het model text-embedding-3-small is goedkoop ($0.02 per miljoen tokens) en presteert uitstekend voor de meeste use cases. text-embedding-3-large is zwaarder en duurder maar presteert beter op complexere semantische taken.
Praktijkvoorbeeld: zoekfunctie voor je documentatiesite
Hier is een concreet voorbeeld. Je wilt een semantische zoekfunctie bouwen voor je helpcenter. Index-fase: crawl alle helpartikelen, chunk ze, genereer embeddings via OpenAI, sla op in pgvector. Zoek-fase: ontvang de zoekquery van de gebruiker, genereer een embedding, zoek de top-5 meest vergelijkbare chunks, geef de resultaten terug als zoekresultaten. Optioneel: stuur de top-3 chunks naar Claude als context en laat het model een samengevat antwoord genereren.
🚀 Kies het juiste embedding model
OpenAI text-embedding-3-small: goedkoopste, snel, voor de meeste toepassingen voldoende. OpenAI text-embedding-3-large: beter bij complexe semantische taken, hogere dimensionaliteit. Voor meertalige content (inclusief Nederlands) scoort het multilingual-e5-large model van Hugging Face vaak beter dan OpenAI's modellen.