Module 85: Embeddings and Vector Search
Semantic search
🏠The everyday picture
A helpful librarian understands "books about starting a small shop" even if no title contains those words. A card catalogue only finds exact title words.
📘What it really is
- Semantic search uses embeddings to find text by meaning:
- index: split approved documents into chunks, embed each chunk, store with metadata;
- query: embed the user's question with the same model;
- search: find the nearest chunks (filtered by permissions and metadata);
-
show the results, or pass them to a model to answer from (Module 86).
-
Keyword search (PostgreSQL full-text search with
tsvector, Module 57) still matters: it's better for exact terms, product codes, names and numbers ("SKU-4471", "GST"), where embeddings can be fuzzy. -
Hybrid search combines both: run keyword and semantic searches, then merge the results (a simple method is reciprocal rank fusion: score each result by its position in each list). This is often the most reliable approach.
-
Keep the index fresh: when a document changes, re-chunk and re-embed it; when it's withdrawn, delete its chunks. Store a version or
updated_atper document. -
Only approved material goes in: drafts, outdated policies and private notes stay out, or the assistant will repeat them (Module 90).
-
Semantic search alone is already a useful feature: a search box for staff that finds the right policy paragraph.
🖱️Try it
Write an indexDocument(documentId) function that splits a document into paragraphs (proper chunking comes in Module 86),
embeds them, and stores them. Index your approved documents. Build GET /v1/search?q= returning the top five chunks with their
document titles, and add a PostgreSQL full-text search alongside it. Compare both for one meaning-based question and one exact
product-code question.
✅Quick check
When does keyword search beat semantic search?
Show the answer
For exact terms such as product codes, names and numbers.
What must happen when an approved document is updated?
Show the answer
Its chunks must be re-created and re-embedded, and old ones removed.
