What Is HyDE (Hypothetical Document Embeddings) and How Does It Work?
HyDE (Hypothetical Document Embeddings) is a retrieval technique that improves search accuracy by having a language model first generate a fake, “hypothetical” answer to a query, embedding that fake answer instead of the query itself, and then searching a real document collection for whatever is most similar to that embedding. Counterintuitively, the fake document doesn’t need to be factually correct to work — it just needs to be written in the same style and structure as the real documents you’re searching, which turns out to be enough to dramatically improve retrieval, especially when you have no labeled training data to fine-tune a retriever on.

The Problem HyDE Was Built to Solve
Standard dense retrieval embeds a user’s query and compares it against embedded documents using vector similarity. This works reasonably well, but it rests on an assumption that’s shakier than it looks: that a short, often vaguely-worded query and a long, detailed, information-dense document will land close together in embedding space simply because they’re “about” the same thing. In practice, queries and documents are different kinds of text — a query is a question, a document is an answer — and an embedding model has to bridge that structural gap correctly for retrieval to work well.
Retrieval models are typically made good at bridging this gap through supervised training on relevance-labeled data: real pairs of (query, correct document) that teach the model what a good match looks like. The problem is that this labeled data is expensive to produce and often doesn’t exist at all for a new domain, a new use case, or a new language — which leaves you needing good retrieval without the training data that normally makes retrieval good. This is precisely the zero-shot retrieval problem, and it’s the specific gap HyDE was designed to close.
Where HyDE Comes From
HyDE was introduced in the paper “Precise Zero-Shot Dense Retrieval without Relevance Labels” by Luyu Gao, Xueguang Ma, Jimmy Lin, and Jamie Callan. The framing in the title is the whole point: precise retrieval, without needing relevance labels to get there. Rather than trying to train a better retriever from labeled examples, the paper’s insight was to sidestep the query-document mismatch a different way entirely — by generating a fake document that already looks like the kind of thing you’re searching for, and embedding that instead of the original query.
How HyDE Actually Works, Step by Step
The mechanism has three steps, and each one matters:
- Generate a hypothetical document. The user’s query is sent to an instruction-following language model, which is prompted to write what an ideal, detailed answer to that query would look like — not a short response, but something resembling the actual documents in the target collection: a paragraph, an explanation, a passage.
- Embed the hypothetical document, not the query. That generated text — fictional, unverified, possibly wrong in its specifics — is passed through an embedding model, the same one used to embed the real document collection.
- Retrieve real documents nearest to that embedding. The embedding of the fake document is used to search the actual corpus via standard nearest-neighbor vector similarity. The generated document itself is discarded — it never gets shown to anyone and is never checked for accuracy. It only exists to produce a better embedding to search with.
The query never gets embedded directly at all. The entire technique is a substitution: swap a short, sparse query embedding for a rich, document-shaped embedding, generated on the fly specifically to resemble what you’re looking for.

Why It Works Even Though the Generated Document Is Often Wrong
This is the part most explanations of HyDE skip past, and it’s the actual insight the paper is built on. If the language model hallucinates — invents a wrong date, a fabricated statistic, an incorrect name — shouldn’t that send retrieval in the wrong direction? The paper’s answer is that it mostly doesn’t, because of what happens during the embedding step, not the generation step.
An embedding model that was contrastively trained to represent documents (the paper uses an unsupervised contrastively-trained encoder) compresses text into a fixed-size vector — a dense bottleneck. That compression step doesn’t preserve every specific fact evenly; it captures the general pattern, topic, and relevance signal of the text far more robustly than it preserves any single specific, possibly-wrong detail. A hallucinated fact is usually a small, localized error inside an otherwise topically-correct hypothetical document, and the embedding step effectively averages that error out, keeping the parts of the representation that correctly signal “this is the neighborhood of the vector space where the real answer to this query lives.” The fake document doesn’t have to be true. It has to be shaped like the truth.
Making It More Robust: Multiple Hypothetical Documents
Because any single generated document can still have an unlucky, off-topic hallucination that skews its embedding in a bad direction, a natural refinement is to generate several hypothetical documents for the same query — not just one — and average their embeddings together before searching. Averaging multiple independently generated fake documents smooths out any one generation’s idiosyncratic errors even further, since an error that appears in one generated sample is unlikely to appear the same way in another, while the genuine topical signal that’s actually relevant to the query shows up consistently across all of them.
HyDE vs. Standard Dense Retrieval vs. Query Expansion
It’s worth being precise about where HyDE sits relative to two techniques it’s easy to confuse it with:
- Standard dense retrieval embeds the query directly and compares it to document embeddings. It’s fast and requires no extra generation step, but it inherits the full query-document structural mismatch, and it depends heavily on the retriever having been trained (or fine-tuned) on data resembling your domain.
- Query expansion / query rewriting uses a language model to reformulate or add terms to the original query — still embedding something query-shaped, just a richer or better-worded version of it.
- HyDE doesn’t expand the query at all — it replaces it with an entirely different kind of object: a full, document-shaped piece of text generated specifically to resemble an answer, not a better question.
That distinction is the reason HyDE tends to outperform query expansion specifically in zero-shot settings: a better query is still a query, with the same structural mismatch against long-form documents; a hypothetical document sidesteps that mismatch by being the same shape as what you’re searching for.

When HyDE Actually Helps
HyDE earns its keep specifically in zero-shot or cold-start retrieval scenarios: a new domain or dataset with no relevance-labeled data to train or fine-tune a retriever on, short or ambiguous queries that don’t carry enough signal on their own, and situations where you don’t have the resources to build and maintain a domain-specific fine-tuned retrieval model. In these cases, generating a document-shaped stand-in for the query is often enough to meaningfully close the gap with a properly trained retriever, without any training data at all.
When It Doesn’t Help — and What It Actually Costs
HyDE is not a free upgrade, and the cases where it adds little or actively hurts are just as important as the cases where it helps:
- Added latency and cost on every single query. HyDE requires an extra LLM generation call before retrieval can even begin, on top of the embedding and search steps a normal query would need. That’s real, measurable latency overhead and real additional inference cost, paid on every request, not just occasionally.
- Diminishing returns once you already have a good retriever. If your corpus is well-matched to your queries, or you already have a fine-tuned, in-domain retrieval model, the structural mismatch HyDE is designed to paper over is much smaller to begin with — meaning there’s less gap for HyDE to close, and the extra generation cost buys you less.
- Hallucination risk in high-stakes domains. The dense-bottleneck argument explains why HyDE’s retrieval quality survives typical hallucinations — but it’s a statistical tendency, not a guarantee. In regulatory, medical, or legal contexts, a badly off-topic hallucinated document can occasionally pull retrieval toward the wrong neighborhood entirely, which is a bigger problem in domains where a wrong answer has real consequences.
- It benefits from being paired with other techniques, not used in isolation. Because it’s a probabilistic improvement rather than a guarantee, HyDE is commonly combined with reranking or hybrid keyword-plus-vector search afterward, to catch cases where the hypothetical document happened to steer retrieval in a weaker direction.
The practical rule of thumb: reach for HyDE when you’re retrieving in an unfamiliar domain with no labeled data and can absorb the extra latency and cost; skip it when you already have a well-matched retriever, when queries and documents already resemble each other structurally, or when consistent low latency matters more than a marginal recall improvement.
Implementing HyDE in Practice
Concretely, HyDE is implemented as a small pipeline in front of an existing vector search setup: generate the hypothetical document with an LLM, embed it, and issue the search using that embedding instead of the raw query’s embedding. Here’s what that looks like against a vector database collection in Weaviate:
from weaviate.classes.query import NearVector
def generate_hypothetical_document(query, llm_client):
prompt = (
f"Write a detailed passage that directly answers this question, "
f"as if it were an excerpt from a real reference document:\n\n{query}"
)
return llm_client.generate(prompt)
def hyde_search(query, collection, llm_client, embed_fn, num_samples=1):
# Generate one or more hypothetical documents and average their embeddings
hypothetical_docs = [
generate_hypothetical_document(query, llm_client)
for _ in range(num_samples)
]
embeddings = [embed_fn(doc) for doc in hypothetical_docs]
averaged_vector = [sum(dim) / len(embeddings) for dim in zip(*embeddings)]
# Search the real corpus using the hypothetical embedding, not the query's
return collection.query.near_vector(
near_vector=averaged_vector,
limit=5,
)
results = hyde_search(
query="What causes HNSW graphs to degrade under high write volume?",
collection=client.collections.use("Documentation"),
llm_client=my_llm_client,
embed_fn=my_embedding_function,
num_samples=3,
)
The generated documents from `generate_hypothetical_document` are never stored, shown to the user, or checked for factual accuracy — they exist purely to produce `averaged_vector`, the actual thing being searched with. Everything downstream of that point is ordinary vector search against your real, trustworthy corpus.
The Bottom Line
HyDE’s core move is a reframing, not a trick: instead of trying to make a short query resemble a long document through better training, it generates a disposable document-shaped stand-in and lets the embedding model’s own compression behavior filter out the parts that are wrong while keeping the parts that are topically useful. That’s a genuinely different lever than fine-tuning a retriever or expanding a query, which is exactly why it earns a place in the retrieval toolkit specifically for the zero-shot, no-labeled-data situations where the other two levers aren’t available — while remaining a deliberate trade-off of extra latency and cost that isn’t worth paying once those situations no longer apply.