Search / the floor every product is built on

The pre-LLM baseline: BM25 over a phone catalogue. It works when users know exact terms — and breaks on every natural-language query.

After
() →
search
A retrieval function — keyword match, BM25, or vector similarity
query_user
The user's raw natural language input
results
A ranked list of phone results matching the query terms
# search(query_user) → results

query_user: "something for my mom who struggles
             with technology"

BM25 tokens: [something, mom, struggles, technology]
Matches: 0

Result: No phones found.

Keyword search only works when the user speaks the vocabulary of your data model. Natural language intent is invisible to BM25.

1 / 5

What you build

  • A BM25 index over phones.json
  • A query tokeniser that splits query_user into terms
  • A ranker that scores phones by term frequency

What it fixes

Users can find phones by exact keyword — brand names, model numbers, OS.

BM25
A probabilistic ranking function that scores documents by term frequency and inverse document frequency. The default in most search engines.
Semantic search
Retrieval using vector embeddings rather than keyword match, so queries and documents with similar meaning rank together.
Narrative field
A natural-language description of each phone written for semantic search — the only field that embeds meaningfully against user intent.
Recall
The fraction of relevant results the system actually returns. High recall means fewer relevant items are missed. Precision is the inverse tradeoff.
The Recall Law

Maximize recall, sacrifice precision. Maximize precision, sacrifice recall. Always.

A user types "something for my mom who struggles with technology" into the search box. BM25 tokenises the query: [something, mom, struggles, technology]. Zero matches. Every word is meaningful. None maps to a field in phones.json. This is the ceiling of keyword retrieval: it works when users speak the vocabulary of your data model, and fails the moment they speak their own.

What it reveals

Intent expressed in natural language — "something for my mom" — has zero term overlap with any phone record.

Ability No LLM yet. Retrieval capability is bounded by token overlap. The model's ability is irrelevant here.
Behaviour Keyword matching defines what "relevant" means. The system's behaviour is entirely determined by the index.
Code BM25 → semantic search is an infrastructure decision. Embedding pre-computation happens once before the workshop.
Design The search box sets user expectations. Users expect it to understand them. It doesn't.
Economics Cheapest layer. No LLM calls. No API cost. Zero latency overhead.