AI Engineering
/
Embeddings & Retrieval
/

Compare lexical and dense retrieval on fixtures

Embeddings & Retrieval · 2 to 3 hours

Compare lexical and dense retrieval on fixtures

Rank four help articles by shared words and by cosine similarity, score both rankings against labels, and explain a dense miss and an accidental lexical success.

Medium
Hands-on

3 h

Overview

Compare lexical and dense retrieval using explicit relevance judgments and reproducible fixtures. You rank four articles both ways, score each ranking with precision and recall, and locate where a relevant item was lost before proposing a fix.

Study time: 2 to 3 hours

Interview format: Hands-on debugging with deterministic fixtures

By the end you can

  • Implement lexical and cosine rankings with a deterministic tie rule
  • Calculate precision@k, recall@k, and reciprocal rank from a ranked list
  • Recognize a ranking that succeeds by accident rather than by evidence
  • Identify the stage where a relevant item disappeared
  • Explain why lexical and dense scores should not be added directly, and how rank fusion avoids it

Prerequisites

Helpful background: Basic TypeScript, JavaScript, or Python and arithmetic are enough.

This topic finds and ranks candidates. RAG & Data Pipelines covers ingestion, grounding, citations, and the document lifecycle.

Establish a retrieval contract

Define the searchable unit, eligible corpus, query preprocessing, ranking direction, tie behavior, and result count. Decide whether evaluation judgments apply to documents or passages. Multiple passages from one document should not accidentally count as several relevant documents when evaluation is document-level.

For this exercise, each item is one document with a stable ID. All items are eligible. Return at most two results, break equal scores by ID, and evaluate against explicit document-level labels. Production access control is a separate mandatory eligibility check.

Build a baseline before adding complexity

Start with a lexical baseline and an exact dense search baseline. Exact dense search gives a reference for later approximate-index tuning. Record model configuration, metric, normalization, and document revision along with results.

A simple term-overlap scorer can expose behavior on tiny fixtures. Use a production full-text ranking method such as BM25 when evaluating a real search stack. The exercise scorer below deliberately measures shared unique words only.

Understand cosine calculations

Cosine similarity is dot(query, document) / (norm(query) × norm(document)). Vectors must have matching dimensions, finite values, and nonzero length. A zero vector has no defined cosine similarity.

The fixture uses two-dimensional vectors to make calculations inspectable. Real embedding generation is intentionally replaced by supplied numbers so the exercise runs offline. These numbers illustrate ranking mechanics rather than model quality.

A reproducible ranking exercise

Four help articles, each one document with a stable ID. Every document is eligible.

IDTextVector
D1Reset your password using a recovery link[1, 0]
D2Resolve E104 when a login token expires[0.8, 0.6]
D3Download a billing invoice[0, 1]
D4Change your profile display name[-1, 0]

Three queries, each with a supplied query vector and one relevant document.

QueryQuery vectorRelevant
forgot secret[1, 0]D1
E104[1, 0]D2
billing invoice[0, 1]D3

Rules:

  • Lexical score: lowercase both texts, split them into runs of letters and digits, and count the unique query words that also appear in the document. This measures shared words only; it is not BM25.
  • Dense score: cosine similarity between the query vector and the document vector.
  • Ranking: higher score first, equal scores broken by ascending ID, at most two results. Documents that score zero are still returned, so every query gets two results.

Code exercise

Lexical and dense ranking

Implement cosine, rankLexical, rankDense, precisionAtK, and recallAtK (snake_case names in Python) for the fixture above. Rankings return at most k IDs, highest score first, with equal scores broken by ascending ID. Cosine throws for empty, mismatched, non-finite, or zero vectors, and recall throws when there are no relevant documents.

Open coding workspace

Limitations

The vectors are hand-made fixtures, not model output, and the cosine helper is meant for small finite vectors of ordinary magnitude; production numerical handling should follow the chosen library. The lexical scorer counts shared unique words rather than BM25 and returns zero-score items to keep a fixed ranking. There is no approximate index, filtering, or fusion.

Predict the expected rankings

Predict the outcome

Predict the expected rankings

Trace each query by hand: write every document's lexical and cosine score, apply the tie rule, and keep two results. Then reveal the expected rankings.

QueryRelevantLexical top twoDense top two
forgot secretD1??
E104D2??
billing invoiceD3??

Calculate retrieval metrics

Precision@k is the number of relevant items in the first k ranks divided by k under this exercise's fixed-k convention. Recall@k is the number of relevant items retrieved divided by the total number of relevant items in the eligible corpus. If fewer than k results are returned, document whether precision uses k or the actual returned count.

The reciprocal rank of a query is 1 divided by the rank of its first relevant result. Mean reciprocal rank (MRR) averages reciprocal ranks across queries, with zero assigned when no relevant item appears within the evaluated result window. It emphasizes the first relevant hit. Recall is more useful when several pieces of evidence must be recovered.

When a query has no relevant items, recall has a zero denominator. Define a separate no-answer metric or exclusion rule instead of inventing a recall value. Report how many queries fall into that category.

Score the E104 rankings

Predict the outcome

Score the E104 rankings

Only D2 is relevant for the E104 query. Using your rankings from the exercise above and the fixed-k convention, work out which IDs fall inside each cutoff and the resulting precision and recall, then reveal the answers.

Method and cutoffIDs in the windowPrecisionRecall
Dense, k = 1???
Dense, k = 2???
Lexical, k = 1???

Separate failure locations

FailureDiagnostic evidencePossible correction
Relevant item is absent from the corpusStable-ID lookup failsFix ingestion or publication eligibility
Item exists but is filtered outMetadata and effective filtersCorrect metadata or filter logic
Exact dense search ranks it poorlyExact baseline and source textImprove representation or add lexical retrieval
Exact search finds it but approximate search misses itSame query, metric, and eligibility setTune the approximate index
Candidate is retrieved but removed laterStage-by-stage candidate IDsInspect fusion, deduplication, or reranking
Old version winsDocument revision and active-state metadataEnforce freshness and revision rules

Increasing top-k can help expose a relevant candidate at a lower rank, but it cannot recover an item that was never indexed or was excluded by policy. More results can also increase downstream cost and distract a generator.

Combine ranked lists carefully

Lexical and dense scores may have unrelated scales and distributions. Adding a BM25-like score of 12 to a cosine score of 0.8 has no automatic interpretation. Score normalization requires evaluation and can be unstable across queries.

Rank-based fusion is an alternative. Reciprocal rank fusion (RRF) adds contributions of 1 / (c + rank) for each list in which a document appears, using one-based ranks and a positive rank constant c. An absent document contributes zero. Candidate list size and c affect results.

When two lists hold the same two documents in opposite orders, such as lexical [A, B] and dense [B, A], equal-weight RRF gives both documents the same score, 1 / (c + 1) + 1 / (c + 2). A deterministic tie rule ensures reproducibility, but it does not resolve which document is relevant. Query-aware exact-code handling or a reranker may be needed.

Filtering and normalization checks

Use the same eligible set when comparing methods. Otherwise apparent quality differences may actually be permission or metadata differences. Apply authorization before any content reaches an external reranker or generator, and verify authorization again when fetching mutable records if required by the consistency model.

Check query and document model versions, dimensions, and normalization. Equal dimensions can still hide incompatible embeddings. If an engine reports distance, inspect its direction before sorting. A reversed sort can produce convincing-looking yet irrelevant results.

Completion checklist

  • Reproduce the expected rankings for all three fixtures.
  • Calculate dense precision@2 and recall@2 for E104.
  • Explain why the lexical result for “forgot secret” is misleading.
  • Locate a retrieval failure in a named stage before proposing a change.

Sources

The vectors, articles, queries, scores, timing budgets, exercises, and rubrics are original synthetic teaching material. They do not describe the measured performance of a named model or search engine. Study times and readiness thresholds are editorial estimates. Check the chosen embedding model's and search engine's current documentation before implementation.

Practice the interview question

Answer it in your own words before you look at the reference answer.