Hirestack
Hirestack
Chapter 8

RAG Systems · Embeddings and semantic search

📖 2 min read · 6 sections · May 2026

Why this matters

Embeddings are the workhorse of every RAG system, every "find similar" feature, every clustering / classification pipeline. Picking the wrong model or the wrong dimension wastes years of latency budget on every query.

What is an embedding, mechanically?

A neural network reads a chunk of text and outputs a fixed-length vector (e.g., 1536 floats). Models are trained so that semantically similar texts produce similar vectors (high cosine similarity). The model that produces embeddings is different from the model that produces chat completions — usually smaller, encoder-only, and cheap.

Choosing an embedding model in 2026

ModelDim$/1M tokensNotes
OpenAI text-embedding-3-small1536 (truncatable)$0.02Default for most apps; cheap, good
OpenAI text-embedding-3-large3072 (truncatable)$0.13Best for nuanced retrieval; truncate to 1024 for storage savings
Cohere embed-english-v31024$0.10Strong on retrieval-tuned tasks; multilingual variant available
Voyage AI voyage-31024$0.06Often top of MTEB leaderboard for retrieval
BGE-M3 (open source)1024self-hostFree; competitive with closed; great for multilingual + long-context
Matryoshka embeddings: newer models (text-embedding-3, voyage-3) support truncation — you store a 3072-dim vector but can use the first 512 dims for fast pre-filtering, then re-rank with the full vector. Storage drops 6×, recall barely moves.

Always normalise (when you can)

If your vectors are unit-length, cosine similarity = dot product. Dot product indexes are faster and more widely supported in vector DBs. Most providers return normalised vectors; if you're working with raw outputs, normalise before storing.

import numpy as np
def normalise(v): return v / np.linalg.norm(v)

Distance metrics — when each one matters

Takeaway

Start with OpenAI text-embedding-3-small, truncate to 1024 dims, normalise. Benchmark something better only after you have an eval set. Most teams over-optimise the embedding model and under-optimise chunking strategy (chapter 10), which matters far more.