Embed & Store
Vectors That Capture Meaning
What Are Embeddings?
An embedding is a list of numbers (a vector) that represents the meaning of a piece of text. Similar meanings produce similar vectors. This is the magic that makes semantic search work.
"What is the PTO policy?" → [0.12, -0.34, 0.78, 0.45, ...]
"How many vacation days?" → [0.11, -0.31, 0.76, 0.43, ...] ← very similar!
"Expense reimbursement rules" → [0.89, 0.22, -0.15, 0.67, ...] ← very differentThe first two questions are about the same topic — their vectors are close together in high-dimensional space. The third is about a different topic — its vector points in a different direction.
Why Not Just Use Keywords?
Keyword search for "vacation days" won't find a document that says "paid time off." Embedding search will, because both phrases have similar meaning-vectors. This is semantic search — matching by meaning, not by exact words.
Embedding Models
You send text to an embedding model API, and it returns a vector. Common choices:
| Model | Dimensions | Speed | Quality |
|---|---|---|---|
| OpenAI text-embedding-3-small | 1536 | Fast | Good for most use cases |
| OpenAI text-embedding-3-large | 3072 | Slower | Better for nuanced content |
| Cohere embed-v3 | 1024 | Fast | Strong multilingual support |
For this course, we'll use 1536-dimensional vectors (the most common). The actual model choice matters less than getting the pipeline right.
async function embed(text: string): Promise<number[]> {
// In production: call OpenAI/Cohere API
// For learning: we'll use mock embeddings first,
// then swap in a real model
const response = await openai.embeddings.create({
model: "text-embedding-3-small",
input: text,
});
return response.data[0].embedding; // number[1536]
}Storing in pgvector
pgvector is a PostgreSQL extension that stores vectors alongside your regular data. Supabase includes it out of the box — no separate vector database needed.
-- Enable the extension
create extension if not exists vector;
-- Create chunks table with a vector column
create table chunks (
id text primary key,
content text not null,
embedding vector(1536),
metadata jsonb default '{}',
created_at timestamptz default now()
);The vector(1536) column stores your embeddings right next to the text content and metadata. One table, one query — no need to join across systems.
HNSW Indexing
Without an index, searching vectors requires comparing your query against every single stored vector. With 10,000 chunks, that's fine. With 1,000,000 chunks, it's too slow.
HNSW (Hierarchical Navigable Small World) is an approximate nearest-neighbor index. It trades a tiny bit of accuracy for massive speed improvements:
create index on chunks
using hnsw (embedding vector_cosine_ops)
with (m = 16, ef_construction = 64);| Without Index | With HNSW |
|---|---|
| Scans every vector | Navigates a graph structure |
| O(n) — linear | O(log n) — logarithmic |
| 100% accurate | ~99% accurate (close enough) |
| Fine for < 10K rows | Scales to millions |
For this course, our dataset is small enough that brute-force search works fine. But we'll add the HNSW index anyway — it's a one-line addition that makes the system production-ready.
Similarity Metrics
How do you measure "similar"? Two common approaches:
Cosine Similarity
Measures the angle between two vectors. Ranges from -1 (opposite) to 1 (identical). Ignores magnitude — two vectors pointing the same direction score 1.0 regardless of length.
Dot Product
Multiplies corresponding elements and sums them. Faster to compute, but sensitive to vector magnitude. Works well when vectors are normalized (length = 1).
For text search, use cosine similarity. It's the standard, and pgvector supports it natively with the <=> operator:
select id, content, 1 - (embedding <=> query_embedding) as similarity
from chunks
order by embedding <=> query_embedding
limit 5;The <=> operator returns cosine distance (0 = identical). We subtract from 1 to get similarity (1 = identical).
This is chapter 3 of RAG in 60 Minutes.
Get the full hands-on course — free during early access. Build the complete system. Your projects become your portfolio.
View course details