RAG and vector searchLoading progress…

Query and document encoders

Rank documents by dot product, cosine and L2 distance and explain the role of normalization and model choice.

Turning text into points to search

Embedding retrieval converts a query and a set of documents into vectors, then returns the documents whose vectors are closest to the query's. For this to mean anything, the query and documents must be encoded by compatible models: ones trained together so that their coordinates share a meaning. Some models also treat the two roles differently, for example by requiring a prefix on queries and another on documents.

A toy encoder counts five words. The second "encoder" has the same size (5 numbers) but lists the words in another order, so its coordinates mean something else.

documentvectordot with the query
paris is the capital of france[1, 1, 1, 0, 0]2
rome is the capital of italy[0, 1, 0, 0, 1]1
pizza in rome[0, 0, 0, 1, 1]0
query vector: [0, 1, 1, 0, 0] best match: "paris is the capital of france" matching dimensions made the arithmetic possible, not the answer meaningful

Retrieval models also give queries and documents different roles; some require prefixes such as query: and passage: . Follow the contract of the model you chose.

Same size, different encoders: see what happens to the ranking.

Predict first. Can embeddings from unrelated encoders be compared just because their dimensions match?

Chapter context

Semantic search represents queries and documents as vectors in a compatible space. Good retrieval depends on the encoder, its training objective and the candidate data; choosing a distance formula alone does not create semantic relevance.

Chapter reference: math, worked example & code

This section belongs to the whole chapter, so it is the same on every lesson in it and may cover a different lesson's topic. The code for the experiment you just ran is inside the experiment itself.

Math and notation

cos⁡(q,x)=qTx∥q∥∥x∥,∥q−x∥2=∥q∥2+∥x∥2−2qTx.\cos(q,x)=\frac{q^Tx}{\|q\|\|x\|},\quad \|q-x\|^2=\|q\|^2+\|x\|^2-2q^Tx.

For unit-normalized vectors, squared L2 is 2−2qTx2-2q^Tx, so their rankings agree under the appropriate direction. Zero vectors require a defined handling policy.

Worked example

Let q=[1,0], A=[1,0] and B=[10,10]. Raw dot products are 1 and 10, so B ranks first by dot product. Cosines are 1 and 1/sqrt(2), so A ranks first by cosine. This is a deliberate example of magnitude changing the retrieval objective.

Reference code

The following example uses the Python standard library and does not call a remote service.

from math import sqrt,isclose
q,a,b=[1,0],[1,0],[10,10]
dot=lambda u,v: sum(x*y for x,y in zip(u,v))
norm=lambda u: sqrt(dot(u,u))
assert dot(q,b) > dot(q,a)
assert dot(q,a)/(norm(q)*norm(a)) > dot(q,b)/(norm(q)*norm(b))
assert isclose(dot(q,b)/(norm(q)*norm(b)),1/sqrt(2))
assert 128*4 == 512

Python examples are provided for study and local execution; this page does not execute Python.

Common mistakes

Do not mix embedding spaces or metric directions. Normalize only when it matches the model and search objective. Similarity is not factual verification.