Handbooks / Generative AI & LLMs / Chapter 3

Embeddings and Vector Search

7 pages · ~5 min✓ Reviewed

Builds on Prompting Techniques. Next up: Evaluation and Hallucinations.

Generative AI & LLMsPage 1

Embeddings and the Vector Mental Model

1. What an Embedding Is

  • Embedding = fixed-length array of floats made by a model
  • Typical sizes: 384, 768, 1536 dims
  • Similar meaning lands at nearby points

2. Meaning Is Position

PairPosition
car / automobileclose
car / bananafar apart
  • Dimensions have no human-readable meaning
  • Only distances and angles between vectors mean anything
  • Different models = different spaces and dims: never mix them in one index

3. Query and Chunking Rules

  1. Chunksplit long text
  2. Embedone model
  3. Indexvectors
  4. Querysame model
Mixing models

Vectors from two models are not comparable, even when the dims match. A new model means re-embed everything.

Generative AI & LLMsPage 2

Similarity Metrics: Cosine, Dot Product, Euclidean

1. The Three Metrics

MetricFormulaReading
Cosine(a·b) / (|a||b|)-1 to 1; angle only, ignores length
Dot productsum of a_i*b_ifastest; higher = closer
Euclidean (L2)sqrt(sum (a_i-b_i)^2)smaller = closer; sensitive to magnitude
  • Dot product equals cosine when vectors are L2-normalised to length 1

2. Worked Example

python
import math
def cos(x, y):
    d = sum(i * j for i, j in zip(x, y))
    return d / (math.hypot(*x) * math.hypot(*y))
a, b, c = [1, 0], [1, 1], [0, 1]
print(round(cos(a, b), 2), round(cos(a, c), 2))

a and b: 1 / (1 * 1.414)

output
0.71 0.0
  • Cosine 0 means unrelated (right angle)
  • Cosine near 1 means same direction

3. Mistakes

  • Using a metric different from the one the model was trained for
  • Reading cosine distance as if it were similarity
Distance flips the direction

Cosine distance = 1 - cosine. Smaller is closer, the opposite of similarity.

Generative AI & LLMsPage 3

Vector Databases and Core Workflow

1. What a Vector DB Is

  • Stores vectors + metadata, answers top-k nearest-neighbour queries
  • DBs: pgvector, Pinecone, Qdrant, Weaviate, Milvus
  • FAISS = a library, not a DB

2. Ingest and Query

  1. Chunk200-500 tokens, overlap
  2. Embedeach chunk
  3. Upsertvector + id + metadata
  1. Embed querysame model
  2. Top-kchosen metric
  3. Filtermetadata, optional
  4. Returnchunks

3. pgvector and Filters

sql
CREATE EXTENSION vector;
CREATE TABLE docs(id serial, body text,
  emb vector(768));
SELECT body FROM docs
ORDER BY emb <=> $1 LIMIT 5;

$1 = query embedding

OperatorMeaning
<=>cosine distance
<->L2 distance
<#>negative inner product
Filter after search

Tenant, date, language filters must run with the search. Top-k first, then filter, can return fewer than k results.

Generative AI & LLMsPage 4

Approximate Nearest Neighbour Indexes

1. Flat vs ANN

  • Flat search: query vs every vector, O(N·d)
  • Perfect recall, fine up to ~100k vectors
  • ANN trades a little recall for big speed
  • Most true neighbours, not guaranteed all
  • Measured as recall@k: share of true top-k found

2. HNSW

  1. Top layersparse entry
  2. Greedy hopnearest node
  3. Drop a layerrepeat
  4. Layer 0top-k
  • Layered proximity graph: fast, high recall, memory-heavy
  • M: links per node
  • efConstruction: build quality
  • efSearch: query breadth; higher = better recall, slower

3. IVF and PQ

  • IVF: k-means splits vectors into nlist cells
  • Search only the nprobe nearest cells; tune for recall
  • PQ compresses vectors: less memory, some accuracy lost
HNSWIVF
Memoryhighlower
KnobefSearchnprobe
Trainingnonek-means first
Mistakes

Never skip recall vs a flat baseline. Never build IVF before the table holds enough representative data to train clusters.

Generative AI & LLMsPage 5

Semantic, Keyword and Hybrid Search

1. Keyword vs Semantic

Keyword (BM25)Semantic
Matchesexact terms, weighted by frequency and raritymeaning, via embeddings
Wins onIDs, error codes, names, rare jargon'budget airfare' finds 'cheap flights'
Missessynonyms, paraphraseexact strings: ERR_4012, a SKU

2. Hybrid and the Pipeline

  • Hybrid = run both, merge the ranked lists
  • RRF score = sum over lists of 1/(k + rank), k≈60
  • Uses ranks only: no need to normalise incompatible scores
  1. Hybrid retrievetop 50-100
  2. Cross-encoderrerank
  3. LLMtop 5
  • Reranker is accurate, but too slow for the whole corpus

3. Mistakes

  • New embedding model, old index not rebuilt
  • Ignoring chunk size
  • Judging by eyeballing results
Measure it

Keep a labelled query set and track recall@k and MRR.

Generative AI & LLMsPage 6

Embeddings and Vector Search Cheat Sheet

1. Vectors and Metrics

  • Embedding = fixed-length float vector
  • Same model for queries and documents
  • Never mix models in one index
  • Match the metric the model was trained on
MetricLengthNote
Cosineignoredangle only
Dot productused= cosine if normalised
L2sensitivesmaller = closer

2. Pipeline

  • Ingest: chunk → embed → upsert with metadata
  1. Embedquery
  2. Top-kANN search
  3. Filtermetadata
  4. Rerankbest first

3. Indexes and Search

IndexIdeaTune
Flatexact, slow at scalenone
HNSWfast, high recall, more RAMefSearch
IVFcluster pruningnprobe
PQcompressionless accuracy
  • BM25: exact tokens (IDs, error codes)
  • Semantic: meaning, paraphrase
  • Hybrid: merge with RRF, k≈60
  • Reranker on the top 50-100
Measure it

Check recall@k against a flat baseline, using a labelled test query set.

Generative AI & LLMsPage 7

Check yourself

Query q=[1,0]. Docs x=[10,0] and y=[1,1]. Which wins under cosine, and which under L2 distance?
  • Cosine: x = 1.0, y ≈ 0.71, so x wins
  • L2: x is 9 away, y is 1 away, so y wins
  • Cosine ignores length, L2 does not
You ask for k=10 with a tenant filter applied after the search, but get only 2 rows. Why?
  • Top 10 were found across all tenants first
  • Only 2 of them matched the tenant
  • Apply the filter with the vector search
RRF with k=60. Doc A is rank 1 in BM25 and rank 3 in vectors. Doc B is rank 2 in both. Who wins?
  • A: 1/61 + 1/63 ≈ 0.03227
  • B: 2/62 ≈ 0.03226
  • A wins, by a hair
Pure vector search returns unrelated results for the query ERR_4012. Why, and what fixes it?
  • Embeddings capture meaning, not exact strings
  • BM25 matches the exact token
  • Go hybrid: merge both lists with RRF