Reading tools and contents
Retrieval Engineering

Chapter 4 of 10

Dense embeddings as learned retrieval geometry

Representation

About 4 minutes · includes examples, an exercise, and references

Chapter at a glance

  • Embedding model, input template, pooling, normalization, and metric form one versioned contract.
  • Nearest does not imply relevant; dense indexes return a neighbor even for unsupported queries.
  • Hard negatives improve discrimination but can introduce false-negative and domain biases.

A dense retriever maps queries and passages into fixed-dimensional vectors and ranks them by a similarity function. Instead of requiring shared terms, training places representations of relevant pairs near each other and irrelevant pairs farther apart. This learned geometry enables paraphrase and concept matching, but it also compresses a rich text into a finite vector. What survives that compression depends on architecture, training data, objective, pooling, instruction format, and similarity function.

Dual-encoder retrieval computes q = f(query) and d = g(document) independently. Documents can be embedded offline; online search only embeds the query and compares it with stored vectors. DPR showed this pattern for open-domain question answering. Sentence-BERT uses siamese or triplet structures to produce sentence embeddings suitable for efficient similarity. Independence gives scale but limits interaction: a single passage vector cannot adapt its token interpretation to a particular query.

Similarity must match training. Dot product is q·d. Cosine similarity divides the dot product by vector norms. If vectors are L2-normalized, dot product and cosine induce the same ranking. Euclidean distance between normalized vectors is also monotonic with cosine. Inner-product models may intentionally encode magnitude, so normalizing them after the fact can change behavior. Record the model card, expected prefix or instruction, pooling, normalization, and distance metric as one inseparable representation contract.

Contrastive training typically increases similarity for a relevant pair relative to negatives. In-batch negatives are efficient but can contain false negatives—other passages that are actually relevant. Hard negatives retrieved by a strong baseline teach fine distinctions but can amplify annotation errors. Domain adaptation can improve specialized vocabulary while degrading generality. Measure before and after on both target slices and retained broad slices.

Input construction matters. Some models expect different prefixes for queries and documents. Titles or heading paths may improve disambiguation. Truncation can remove decisive text. Concatenating sensitive or rapidly changing metadata into text makes it part of vector identity and complicates deletion. Build one deterministic encoding function and test its output shape, norm distribution, empty-input behavior, maximum length, and model digest.

Dense similarity is not probability or truth. A vector index always returns nearest neighbors, even when every neighbor is poor. Distribution shift can make a query land in an unsupported region. Define rejection or fallback using judged calibration, lexical agreement, metadata, or a downstream relevance model; do not choose a universal cosine threshold from intuition. Thresholds vary by model and corpus density.

Analyze embedding quality beyond aggregate retrieval. Plot or summarize vector norms, duplicate rates, language and domain slices, nearest-neighbor label purity, and hubness—the tendency of some vectors to appear near many unrelated queries. Inspect false friends caused by generic templates, negation, numbers, or product versions. Compare exact entity queries with paraphrases. Dense models often blur critical distinctions such as “enable” versus “disable” or old versus current policy unless the corpus and reranker carry those signals.

Model upgrades are schema migrations. A new model, dimension, normalization, tokenizer, or input template requires a new vector field or index generation. Never query new vectors against old document vectors. Backfill, validate on a fixed judged set, compare latency and storage, then atomically switch. Retain the old generation for rollback and keep query logs labelled with the model version used.

Late interaction offers a middle ground. ColBERT stores token-level document representations and computes query-token maximum similarities at search time. It preserves more fine-grained matching than a single vector but requires more storage and specialized indexing. Learned sparse retrieval offers another point in the design space. Choose among them based on measured accuracy, update cost, storage, latency, and explainability, not a false binary between “keyword” and “vector.”

The practical lesson is to treat embeddings as a versioned learned index key. They are valuable because the geometry generalizes, and risky for the same reason. Pair semantic recall with explicit filters, lexical evidence, stage-level evaluation, and reranking when consequence requires finer interaction.

Key points

  • Embedding model, input template, pooling, normalization, and metric form one versioned contract.
  • Nearest does not imply relevant; dense indexes return a neighbor even for unsupported queries.
  • Hard negatives improve discrimination but can introduce false-negative and domain biases.
  • Changing the embedding pipeline requires a coherent reindex and rollback plan.

Compare dot product and cosine safely

Read the expected behavior in the surrounding walkthrough, then copy and run this reference implementation.

Compare dot product and cosine safelypython
from math import sqrt

def dot(a, b):
    if len(a) != len(b): raise ValueError("dimension mismatch")
    return sum(x * y for x, y in zip(a, b))

def normalize(v):
    norm = sqrt(dot(v, v))
    if norm == 0: raise ValueError("zero vector")
    return [x / norm for x in v]

query = normalize([1.0, 1.0, 0.0])
documents = {
    "paraphrase": normalize([0.9, 1.1, 0.1]),
    "unrelated": normalize([0.0, 0.1, 1.0]),
}
print(sorted(((dot(query, v), k) for k, v in documents.items()), reverse=True))

Exercise

Audit an embedding contract

Compare two embedding models for a multilingual product corpus.

  1. Pin the complete encoding contract for queries and passages.
  2. Evaluate paraphrase, identifier, negation, version, language, and unsupported-query slices.
  3. Design a zero-downtime migration and rollback between vector generations.

Success criteria

  • No score is interpreted without its model and metric.
  • The experiment measures both gains and regressions by slice.
  • Queries can never mix incompatible query and document vectors.

Reflect: Which meaning distinction is most likely to be compressed away by one vector?

References and further reading