En embedding er en rekke tall som beskriver hva en tekst betyr. Tekster med lignende betydning får lignende tall, og da kan en maskin finne dem ved å måle avstand.
Vanlig søk finner ord. Embedding-søk finner betydning. Det er forskjellen på å lete etter «sitron» og å lete etter alt som handler om det samme.
Embeddings lages av egne modeller som er trent til nettopp det. Samme ord brukes også inne i språkmodellen, men det er noe litt annet. Embedding-modellen leser en tekst, et ord, en setning eller et helt avsnitt, og gir fra seg en liste på hundrevis til tusenvis av tall. Den er trent slik at tekster som hører sammen eller brukes i lignende sammenhenger, får lignende tall.
Tegn hvert ord som et punkt, og det du får er et kart der avstand betyr likhet. Kartet i figuren har to dimensjoner. Ekte embeddings har mange flere. Vi kan ikke tegne dem, men prinsippet er det samme: nær betyr lik.
Tenk på et bibliotek der bøkene ikke står alfabetisk, men etter hva de handler om. Spør du etter noe om sitroner, går du til hylla med frukt og dessert, selv om tittelen aldri nevner sitron.
Betydning er ikke alt. En embedding kan gjøre «jeg er fornøyd» og «jeg er ikke fornøyd» ganske like, for de handler om det samme. Eksakte tall, navn og koder fanger den dårlig. Og tekst og spørsmål må lages med samme modell, ellers ligger de på hvert sitt kart. Derfor kombineres embedding-søk ofte med vanlig ordsøk.
Cosinuslikhet måler hvor likt to vektorer peker, uavhengig av lengde: 1 er lik retning, 0 er rett vinkel. Det er det vanligste målet i tekstsøk, men ikke det eneste. Prikkprodukt og vanlig avstand brukes også. Under er det i ren Python på sju konstruerte vektorer med fire tall hver. Jeg har satt tallene for hånd. De kommer ikke fra en modell, og dimensjonene har ingen navn. Ekte embeddings kommer fra en embedding-modell og har hundrevis til tusenvis av tall.
import math
# Konstruerte vektorer, fire tall hver. Jeg har satt tallene for hånd slik at
# frukt ligger nær frukt og dyr nær dyr. Dimensjonene har ingen navn, og i ekte
# embeddings kommer vektorene fra en modell og har hundrevis av tall.
ORD = {
"lime": [0.9, 0.1, 0.0, 0.2],
"appelsin": [0.8, 0.2, 0.1, 0.1],
"pære": [0.7, 0.1, 0.0, 0.4],
"hund": [0.1, 0.9, 0.2, 0.0],
"katt": [0.0, 0.8, 0.3, 0.1],
"Bergen": [0.0, 0.1, 0.9, 0.7],
"Tromsø": [0.1, 0.0, 0.8, 0.8],
}
def cosinus(a, b):
skalar = sum(x * y for x, y in zip(a, b))
lengde = math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b))
return skalar / lengde
sok = [0.8, 0.1, 0.1, 0.3] # «sitron», et ord som ikke står i lista, plassert for hånd i frukt-hjørnet
rangert = sorted(((cosinus(sok, v), ord_) for ord_, v in ORD.items()), reverse=True)
for skar, ord_ in rangert:
print(f"{skar:5.2f} {ord_}")Utskrift fra en kjøring:
0.98 lime 0.98 pære 0.97 appelsin 0.41 Tromsø 0.31 Bergen 0.24 hund 0.19 katt
Frukt ligger nær frukt, byene og dyrene langt unna. Slik fungerer også nærmeste-nabo-søket i en ekte embedding-løsning, bare med vektorer fra en modell. Anthropic har ingen egen embedding-modell og peker på Voyage AI i dokumentasjonen sin. Eksempel på bruk står under RAG. Hvor godt en modell fungerer på norsk, må du teste på dine egne tekster. Én åpen modell å ta med i testen er NbAiLab/nb-sbert-v2-large, som tar høyst 512 token om gangen (modellkortet på Hugging Face, lest 8. oktober 2026).
Kjørt her med Python 3.13 og bare standardbiblioteket, 8. oktober 2026. Utskriften er limt inn slik den kom. Vektorene er konstruerte og viser prinsippet, ikke hvordan en ekte modell plasserer ord. Ikke kjørt mot noen embedding-modell.
Oppdatert oktober 2026. Kartet er en forenklet framstilling i to dimensjoner, og tallene på kortene er konstruerte. Ekte embeddings har typisk hundrevis til tusenvis av dimensjoner, og avstanden måles i alle samtidig. På et slikt kart sier avstanden mellom gruppene lite. Det er nærheten innenfor gruppene som kan leses ut.