Vector search
Similarity metrics, exact vs approximate nearest-neighbor indexes, their knobs and memory, hybrid search with RRF, and filtering pitfalls.
Metrics: dot , cosine , L2 . For unit vectors all three rank the same (), so normalize and use dot. Otherwise use the metric the model was trained with.
| Index | How it works | Knobs | Cost / memory | Use when |
|---|---|---|---|---|
| Exact (flat) | compare with every vector | none | per query; bytes in float32 | up to a few hundred thousand vectors, small filtered subsets, ground truth |
| IVF | k-means cells, scan nearest | (start near ), | large , cheap build, works with PQ | |
| HNSW | layered neighbor graph, greedy descent | , efConstruction, efSearch () | vectors + about bytes/vector of links | fits in RAM, want high recall at low latency |
| PQ | subvectors, each a 1-byte codebook ID | , codebook size (256) | bytes/vector (e.g. 3 KB to 96 B, ) | memory-bound; re-score top candidates exactly |
Index recall@k . Measure on real queries; tune for a recall target at a latency budget.
Reciprocal rank fusion: . Dense A,B,C,D + BM25 E,F,A,B gives A, B, E, F, C, D.
Watch outPost-filtering a top- list keeps about selectivity results (0.2 of 10 at 2%). Filter inside the search, partition by tenant, or brute-force small subsets. Enforce access control in retrieval, never in the LLM.
Operations: store model name and version with every vector; re-embed everything when the model changes (blue-green); HNSW deletes are tombstones until rebuild; IVF centroids go stale after heavy inserts.
Where to run it: in-memory (NumPy, FAISS) for small or batch; pgvector when data and metadata already live in Postgres; a dedicated vector database or search engine for scale, hybrid search, and multi-tenancy.
Lessons: Vector search · The RAG pipeline