Wat is een Embedding? Vectoren voor Betekenis, Uitgelegd (2026)

Een embedding is een lijst getallen die de betekenis van tekst, een afbeelding of audio vastlegt in een vector van vaste lengte. Vergelijkbare dingen krijgen vergelijkbare vectoren. Embeddings vormen de basis van semantische zoekopdracht, RAG, clustering, classificatie en aanbevelingen. Hier ziet u hoe ze werken, wat ze kosten en welke u moet kiezen.

22 min read·2026-05-27·Foundation
Op deze pagina

Agentic AI · Bijgewerkt mei 2026 · Beoordeeld door het IITS Azure data engineering team · Den Haag

Embedding = Betekenis, als een lijst getallen.

Een embedding is een vector van vaste lengte (een lijst getallen) die de betekenis van tekst, een afbeelding of audio vastlegt. Zinnen over vergelijkbare onderwerpen krijgen vergelijkbare vectoren; ongerelateerde onderwerpen krijgen vectoren ver uit elkaar. Embeddings vormen de basis van semantische zoekopdracht, RAG, clustering, classificatie en aanbevelingen. Geïntroduceerd voor woorden door Mikolov et al. (word2vec, 2013), nu geproduceerd door transformer-encoders die volledige zinnen en documenten embedden in één forward pass.

Wat het is

Een vector die betekenis representeert.

Wat het oplost

Tekst vergelijken op betekenis, niet op exacte woorden.

Wie het nodig heeft

Iedereen die zoek, RAG of aanbevelingen bouwt.

Na deze gids

U embed tekst, vergelijkt het, en kiest een model.

Van Tekst naar Betekenis

TEKSTINVOER "Wat is ons retourbeleid?" EMBEDDING-MODEL Transformer-encoder text-embedding-3-small VECTOR (1.536 dims) [0.012, -0.831, 0.445, 0.117, ...] GEPLOT IN BETEKENISRUIMTE "retourbeleid" "goederen retourneren" "geld terug" "verzendkosten" "levertijd" vergelijkbare betekenissen clusteren · ongerelateerde onderwerpen drijven uit elkaar

Tekst erin. Vector eruit. De vector is een coördinaat in een hoogdimensionale "betekenisruimte" waar dingen die op elkaar lijken dicht bij elkaar wonen.

Voorkennis & Setup

U heeft basiskennis Python nodig (functies, virtuele omgevingen, pip), het vermogen om een HTTP-aanroep te doen, en een API-sleutel voor OpenAI of Azure OpenAI. NumPy voor de wiskunde.

Installatie eenmalig

python -m venv .venv
source .venv/bin/activate     # Windows: .venv\Scripts\activate
pip install openai sentence-transformers numpy

Zet OPENAI_API_KEY als omgevingsvariabele. Haal er één op platform.openai.com/api-keys, of gebruik Azure OpenAI in EU-regio voor productie.

Waarom embeddings bestaan (het verhaal)

Vóór 2013 begrepen computers geen betekenis. Ze begrepen exacte strings. "De kat zat op de mat" en "Een poes rustte op het kleed" zagen er volledig ongerelateerd uit, ook al betekenen ze hetzelfde. Zoekmachines werkten op trefwoordenmatching: typ "retour" en u vond alleen documenten met letterlijk het woord "retour."

  • 2013 — word2vec (Mikolov et al., Google): toonde aan dat woorden konden worden afgebeeld op vectoren waarbij vergelijkbare woorden clusteren. De beroemde demo: koning − man + vrouw ≈ koningin.
  • 2018 — BERT (Devlin et al., Google): contextuele embeddings. De betekenis van "bank" hing nu af van of u sprak over een rivier of een financiële instelling.
  • 2019 — Sentence-BERT (Reimers & Gurevych): maakte het efficiënt om volledige zinnen te embedden, niet alleen woorden.
  • 2024–2026: OpenAI text-embedding-3, Voyage AI, Cohere Embed v3, BGE-M3 — instructie-getrainde, meertalige, multimodale embeddings werden de standaard.

Het kerninzicht

Als u betekenis in geometrie kunt omzetten, kunt u betekenis vergelijken met wiskunde. Twee zinnen? Twee vectoren. Hun gelijkenis? De hoek ertussen. Die ene zet ontgrendelde semantische zoekopdracht, RAG, clustering, aanbeveling, deduplicatie en de meeste moderne NLP.

Tegen 2026 zijn embeddings de basis van elke serieuze LLM-toepassing. Elk RAG-systeem berekent ze. Elke aanbevelingsmotor gebruikt ze. Elke semantische zoekopdracht bouwt erop.

Het mentale model

De betekeniskaart analogie

Stel u een enorme 1.536-dimensionale kaart voor. Elk stukje tekst dat ooit is geschreven is één enkele stip op die kaart. Zinnen over retouren clusteren in de ene buurt. Zinnen over verzending wonen in een andere. Zinnen over koken zijn in een totaal andere regio. De taak van het model is om elke nieuwe zin op de juiste coördinaat te plaatsen. Embeddings zijn die coördinaten.

Vijf termen die u moet internaliseren:

Vector / Dimensie

Technisch: een lijst van vaste lengte met floating-point getallen, meestal 384 tot 3.072 lang. Vriendelijk: een lijst getallen die één stuk tekst lokaliseert in de betekenisruimte. Concreet voorbeeld: [0.012, -0.831, 0.445, ...]. Veelvoorkomend misverstand: groter is niet altijd beter — 3.072 dims kost 2× de opslag en zoektijd van 1.536 dims voor slechts ~5% kwaliteitswinst.

Cosinus-gelijkenis

Technisch: dot product van twee vectoren gedeeld door het product van hun magnitudes, met een waarde tussen -1 en 1. Vriendelijk: een meting van hoe vergelijkbaar twee stukken tekst zijn — 1 betekent identieke betekenis, 0 betekent ongerelateerd, -1 betekent tegengesteld. Veelvoorkomend misverstand: Euclidische afstand is niet hetzelfde — voor embeddings is cosinus-gelijkenis bijna altijd wat u wilt.

Embedding-model

Technisch: een neuraal netwerk (meestal een transformer-encoder) dat tokens als invoer neemt en één vector van vaste lengte uitvoert. Vriendelijk: de functie die tekst omzet in zijn betekeniscoördinaat. Veelvoorkomend misverstand: het embedding-model is niet hetzelfde als het chat-LLM. ChatGPT produceert geen embeddings — u roept een aparte embedding-endpoint aan.

Semantische ruimte

Technisch: de hoogdimensionale vectorruimte (1.536-D voor text-embedding-3-small) waarin alle embeddings van één model wonen. Vriendelijk: de betekeniskaart zelf, met zinnen geplot als stippen. Veelvoorkomend misverstand: twee modellen delen GEEN semantische ruimte — een OpenAI-vector en een BGE-vector kunnen niet worden vergeleken.

Caching

Technisch: berekende embeddings persisteren op schijf of in een vector database zodat u nooit dezelfde tekst tweemaal embed. Vriendelijk: embeddings zijn deterministisch — zelfde tekst + zelfde model = zelfde vector, elke keer. Eenmaal betaald, voor altijd gebruikt. Veelvoorkomend misverstand: vergeten te cachen is de #1 manier om uw embedding-rekening te laten ontploffen.

Anatomie: volg één zin

Laten we één zin door een embedding-model volgen. Invoer: "Wat is ons retourbeleid?"

Stap 1 — Tokenize

De zin wordt opgesplitst in tokens. Met OpenAI's tokenizer wordt "Wat is ons retourbeleid?" 7 tokens. Elk token wordt via een opzoektabel naar een integer-ID gemapt.

Stap 2 — Encode

De token-IDs stromen door een transformer-encoder. Elk token krijgt een contextuele representatie die afhangt van elk ander token (dit is wat "bankrekening" anders maakt dan "rivieroever").

Stap 3 — Pool

De encoder produceert één vector per token (7 vectoren voor onze zin). Een pooling-stap (meestal middelen) comprimeert ze tot één enkele vector die de hele zin representeert.

Stap 4 — Normaliseer

De vector wordt geschaald tot magnitude 1. Daarna is cosinus-gelijkenis gelijk aan gewoon dot product (sneller te berekenen, identiek antwoord).

Stap 5 — Geef terug

De uitvoer is een vector van 1.536 dimensies zoals [0.012, -0.831, 0.445, ...]. Dit is de coördinaat van "Wat is ons retourbeleid?" in OpenAI's betekenisruimte.

Niveau 1 — Speelgoedvoorbeeld

Het kleinste nuttige embedding-voorbeeld. Twaalf regels. In-memory. Embed drie zinnen, bereken cosinus-gelijkenis, zie welke twee het meest op elkaar lijken.

import os, numpy as np
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

def embed(text):
    return np.array(client.embeddings.create(input=text, model="text-embedding-3-small").data[0].embedding)

a = embed("Ons retourbeleid staat retouren toe binnen 30 dagen.")
b = embed("Klanten mogen artikelen retourneren in de eerste maand.")
c = embed("Verzending is gratis voor bestellingen boven 50 euro.")

# Cosinus-gelijkenis (vectoren zijn al genormaliseerd door OpenAI, dus dot product = cosinus)
print(f"a vs b: {a @ b:.3f}")
print(f"a vs c: {a @ c:.3f}")

Verwachte uitvoer

a vs b: 0.812
a vs c: 0.318

Wat er net gebeurde

U hebt drie Nederlandse zinnen omgezet in drie 1.536-dimensionale vectoren. De cosinus-gelijkenis tussen "retourbeleid" en "retourneren" is 0.81 — het model herkent dat ze bijna hetzelfde betekenen ondanks weinig woordoverlap. Als u dit hebt laten draaien, begrijpt u wat een embedding doet.

Niveau 2 — Realistisch

Niveau 1 heeft drie problemen voor echt gebruik: (a) elke herstart betaalt opnieuw de embedding-rekening, (b) één-voor-één aanroepen zijn traag, (c) geen foutafhandeling. Niveau 2 lost alle drie op met batching, caching en model-versionering.

import os, json, hashlib, numpy as np
from pathlib import Path
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
CACHE = Path("./embeddings_cache.jsonl")
MODEL = "text-embedding-3-small"

def _key(text: str) -> str:
    return hashlib.sha256(f"{MODEL}::{text}".encode()).hexdigest()

cache: dict[str, list[float]] = {}
if CACHE.exists():
    for line in CACHE.read_text().splitlines():
        row = json.loads(line)
        cache[row["key"]] = row["vec"]

def embed_many(texts: list[str]) -> np.ndarray:
    """Embed een batch. Cachet via tekst+model hash."""
    missing = [t for t in texts if _key(t) not in cache]
    if missing:
        for i in range(0, len(missing), 2048):
            batch = missing[i:i+2048]
            resp = client.embeddings.create(input=batch, model=MODEL)
            with CACHE.open("a") as f:
                for text, item in zip(batch, resp.data):
                    cache[_key(text)] = item.embedding
                    f.write(json.dumps({"key": _key(text), "vec": item.embedding}) + "\n")
    return np.array([cache[_key(t)] for t in texts])

Wat er veranderde t.o.v. Niveau 1

  • Persistente cache: embeddings worden gehasht op model::tekst en opgeslagen op schijf.
  • Batching: tot 2.048 teksten per API-aanroep (50× sneller).
  • Vooraf genormaliseerd: OpenAI retourneert unit-vectoren.
  • Model versioned in de cache-key: als u ooit van model wisselt, wordt de oude cache automatisch omzeild.

Niveau 3 — Productiepatroon

In productie gaan embeddings door een speciale service met retries, observability, en een echte cache-backend (Redis of pgvector, geen JSON-bestanden). Schets:

# embeddings/service.py
from dataclasses import dataclass
from typing import Sequence
import hashlib, logging, time
from tenacity import retry, stop_after_attempt, wait_exponential

class EmbeddingService:
    def __init__(self, client, cache, model: str = "text-embedding-3-small", batch_size: int = 1024):
        self.client = client
        self.cache = cache
        self.model = model
        self.batch_size = batch_size
        self.log = logging.getLogger("embeddings")

    def _key(self, text: str) -> str:
        return hashlib.sha256(f"{self.model}::{text}".encode()).hexdigest()

    @retry(stop=stop_after_attempt(3), wait=wait_exponential(min=1, max=8))
    def _call_api(self, batch: list[str]) -> list[list[float]]:
        resp = self.client.embeddings.create(input=batch, model=self.model)
        return [d.embedding for d in resp.data]

    def embed(self, texts: Sequence[str], *, trace_id: str = "") -> list[dict]:
        # Cache check, batch missing, log hit-rate + latency
        ...

Waarom retries met backoff

OpenAI rate limits veroorzaken 429's onder belasting. Exponentiële backoff met 3 pogingen vangt ~99% van transiente fouten op.

Waarom model-versioned cache-keys

Als u upgraded van text-embedding-3-small naar large, verandert elke oude cache-key automatisch. Geen verouderde vectoren in de nieuwe index.

Waarom cache-hit rate loggen

Een gezonde productie-embedding-service heeft > 90% cache-hit ratio na warm-up. Als die daalt, weet u dat er iets mis is.

Waarom batchen met 1.024

OpenAI's max is 2.048, maar kleinere batches geven betere p99 latency. 1.024 is de sweet spot voor productie.

Acht valkuilen (productielessen)

1. Verkeerd model voor het domein

De val: "OpenAI is de standaard, dus moet het beste zijn." Het gevolg: middelmatige retrieval op juridische, medische, code- of meertalige data. De fix: benchmark op UW domein via de MTEB leaderboard. Voyage wint voor legal/finance/code; BGE-M3 wint voor multilingual.

2. Geen caching

De val: "Het is maar $0.02 per 1M tokens, dus wat maakt het uit." Het gevolg: een 5M-document her-embed bij elke deploy kost $200 en uren. De fix: hash model::tekst en persisteren.

3. Vectoren vergelijken tussen verschillende modellen

De val: u migreert van OpenAI naar BGE maar her-embed slechts de helft van de corpus. Het gevolg: de niet-gemigreerde vectoren zijn stil fout — ze wonen in een andere semantische ruimte. De fix: tag elke vector met zijn modelnaam; weiger cross-model vergelijkingen.

4. Vergeten te normaliseren

De val: sommige modellen produceren niet-genormaliseerde vectoren. U gebruikt cosinus-gelijkenis maar behandelt het als dot product. Het gevolg: rankings verschuiven; u kunt niet zien waarom. De fix: normaliseer altijd naar unit-lengte na de API-aanroep.

5. Lange tekst stilzwijgend afkappen

De val: text-embedding-3-small heeft een 8.192-token invoerlimiet. U stuurt een 50-pagina PDF; het model kapt stil af tot de eerste 8.192 tokens. De fix: chunken vóór embedden.

6. Engels-alleen model op meertalige data

De val: een model gebruiken dat is getraind op Engels voor Nederlandse / Duitse / Franse content. Het gevolg: embeddings clusteren per taal, niet per betekenis. De fix: gebruik BGE-M3, Cohere multilingual-v3, of Voyage multilingual.

7. Ruwe float32 vectoren op schaal opslaan

De val: 1M vectoren × 1.536 dims × 4 bytes = 6 GB RAM/schijf. Prima totdat u 100M bereikt. De fix: binaire kwantisatie (1 bit per dim, 32× kleiner, ~95% kwaliteit behouden).

8. Alles opnieuw embedden bij modelverandering

De val: committen aan een model, 50M chunks embedden, daarna komt er een beter model. Opnieuw embedden kost $1.000+ en duurt een dag. De fix: ontwerp uw index zodat side-by-side modelversies ondersteund worden.

Skim-samenvatting als u hier stopt

Embedding = vector die betekenis vastlegt. Kies een model voor uw domein, normaliseer, cache agressief, versie uw indexen, vergelijk nooit tussen modellen. De acht valkuilen hierboven zijn verantwoordelijk voor ~80% van productie-embedding-falen.

Embedding-modellen vergelijken

ModelDimensiesKosten / 1M tokensBest voorOpen weights
OpenAI text-embedding-3-small1.536$0.02Standaard EngelsNee
OpenAI text-embedding-3-large3.072$0.13Hogere-kwaliteit EngelsNee
Voyage voyage-3-large1.024$0.12Code, legal, financeNee
Cohere embed-multilingual-v31.024$0.10100+ talenNee
BGE-M3 (BAAI)1.024Gratis (self-host)Meertalig, on-premJa (MIT)
all-MiniLM-L6-v2384Gratis (self-host)Klein / snel / CPUJa (Apache 2.0)
CLIP (OpenAI)512Gratis (self-host)Beeld + tekst samenJa

Eerlijk oordeel

Standaard OpenAI text-embedding-3-small voor nieuwe Engelse projecten. Schakel over op text-embedding-3-large alleen als benchmarking dit bewijst. Gebruik Voyage voor gespecialiseerde domeinen. Gebruik BGE-M3 wanneer u on-prem / EU-alleen / multilingual / gratis nodig heeft.

Kosten & Prestaties

Embeddings zijn het goedkoopste onderdeel van elk RAG-systeem — totdat ze het niet zijn. De kosten worden gedomineerd door hoeveel tokens u embed, niet door welk model.

Een 10M-chunk corpus embedden (200 tokens elk)

Totaal tokens: 2 miljard. Kosten:

  • text-embedding-3-small: ~$40
  • text-embedding-3-large: ~$260
  • Voyage voyage-3-large: ~$240
  • BGE-M3 op uw eigen A100 GPU: ~$10 aan compute-tijd

Latency: een enkele OpenAI embedding-aanroep duurt 50–100ms; een batch van 1.000 duurt ~500ms (10× sneller per item). Self-hosted BGE-M3 op een moderne GPU doet ~20.000 zinnen/seconde.

Verder gaan

Morgen

Embed 200 documenten van uw team met Niveau 1-code. Bereken een similariteitsmatrix. Vind de top 5 bijna-duplicaten waarvan u niet wist dat ze bestonden.

Volgende maand

Bouw een semantische zoekopdracht over uw documenten met Niveau 2 met pgvector of Qdrant. Vergelijk 3 embedding-modellen op uw echte queries.

Lange termijn

Verken fine-tuning van embeddings, multimodale embeddings, binaire kwantisatie op schaal, en Matryoshka embeddings.

Geselecteerde bronnen

Zelfcheck: heeft u het geleerd?

1. Waarom zijn twee embeddings van verschillende modellen niet direct vergelijkbaar?

Antwoord: Elk model heeft zijn eigen geleerde semantische ruimte. OpenAI's coördinaat voor "retour" leeft in OpenAI-ruimte; BGE's in BGE-ruimte. Cosinus-gelijkenis ertussen is wiskundig valide maar semantisch betekenisloos.

2. Wat is het verschil tussen cosinus-gelijkenis en dot product?

Antwoord: Cosinus-gelijkenis = dot product / (magnitude van a × magnitude van b). Wanneer beide vectoren zijn genormaliseerd tot unit-lengte, zijn hun magnitudes beide 1, dus cosinus-gelijkenis is gelijk aan gewoon dot product.

3. Uw semantische zoekopdracht geeft rare resultaten. Het model is OpenAI text-embedding-3-small. Waar kijkt u eerst?

Antwoord: Check drie dingen op volgorde. (1) Taal: is uw corpus Engels? (2) Domein: is het specialistische tekst? (3) Chunking: embed u 5.000-woord documenten in één keer?

4. U bedient een meertalige EU-app en moet alle data in de EU houden. Welke embedding-setup?

Antwoord: Ofwel (a) Azure OpenAI in West-Europa regio met text-embedding-3-small/large — zelfde model, data blijft in EU; of (b) self-host BGE-M3 op een kleine GPU.

5. Wat is fout aan deze code?
def search(query, docs):
    q_vec = embed(query)
    scores = [np.dot(q_vec, embed(d)) for d in docs]
    return sorted(zip(docs, scores), key=lambda x: -x[1])[:5]

Antwoord: Twee grote problemen. (1) embed(d) wordt in de lus aangeroepen op elke zoekopdracht — elke zoekopdracht her-embed de hele corpus. (2) embed wordt één document per keer aangeroepen in plaats van gebatcht.

6. Wanneer fine-tune u een embedding-model in plaats van off-the-shelf gebruiken?

Antwoord: Wanneer off-the-shelf modellen onderscheidingen verwarren die voor u belangrijk zijn. Fine-tuning heeft ~5K gelabelde paren nodig en geeft 5–20% retrieval-winst.

7. Ontwerp een embedding-service voor een multi-tenant SaaS waar elke tenant privédata heeft. Wat drie dingen zijn het belangrijkst?

Antwoord: (1) Per-tenant cache-keys. (2) Per-tenant rate limits. (3) Per-tenant modelversionering.

Veelgestelde vragen

Wat is een embedding in eenvoudige termen?

Een lijst getallen (vector) die de betekenis van tekst, beeld of audio representeert. Vergelijkbare dingen krijgen vergelijkbare vectoren.

Hoeveel dimensies heeft een embedding?

Meestal 384 tot 3.072 afhankelijk van het model. OpenAI text-embedding-3-small is 1.536; large is 3.072; BGE-M3 is 1.024.

Hoe vergelijkt u twee embeddings?

Cosinus-gelijkenis: dichter bij 1 = meer vergelijkbaar. De meeste productie-modellen retourneren genormaliseerde vectoren.

Wat is het beste embedding-model in 2026?

Geen enkel antwoord. Standaard OpenAI text-embedding-3-small voor Engels; Voyage voor code/legal/finance; BGE-M3 voor multilingual of on-prem.

Hoeveel kosten embeddings?

~$0.02 per 1M tokens voor OpenAI's goedkoopste model. Een 10M-chunk corpus embedden kost ongeveer $40.

Kan ik embeddings van verschillende modellen mengen?

Nee. Verschillende modellen wonen in incompatibele vectorruimtes.

Wat is het verschil tussen een embedding en een token?

Een token is een stukje tekst (invoer). Een embedding is de betekenisvector (uitvoer).

Waarom embeddings normaliseren?

Normalisatie laat u snel dot product gebruiken in plaats van volledige cosinus-gelijkenis. De meeste API's retourneren al genormaliseerde vectoren.

Kunnen embeddings beelden en audio representeren?

Ja. CLIP en SigLIP embedden beelden en tekst in dezelfde ruimte (zoeken naar beelden via tekst).

Wat is fine-tuning van een embedding-model?

Een bestaand model verder trainen op uw eigen gelabelde paren zodat het domeinspecifieke onderscheidingen beter vastlegt. Typisch 5–20% retrieval-verbetering.

Volgende leesstuk: hoe embeddings Retrieval-Augmented Generation aandrijven

Embeddings zijn de basis van RAG — de techniek die taalmodellen toegang geeft tot uw eigen data. Om te zien hoe ze samenkomen met vector databases, re-ranking en prompt engineering, lees Wat is RAG? Retrieval-Augmented Generation Uitgelegd (2026).

Klaar om dit in productie te brengen?

IITS bouwt productieklare Azure data- en AI-systemen voor Nederlandse bedrijven. Vaste prijzen, 2-weken pilots, EU-region Azure.

Plan een strategiegesprek →