Modules/Gen AI/ Query Rewriting Lab

Query Rewriting and HyDE

Questions and answers are written in different registers. Closing that gap before you embed anything is often worth more than a better embedding model.

Overview

Before the details

A user's question and the passage that answers it are usually written in different registers: short and colloquial versus long-form and technical. Every similarity metric in this batch — cosine, BM25 — depends on shared vocabulary between what is embedded and what is stored. If the question and the answer do not share words, no similarity metric can bridge that gap on its own; the fix has to happen before retrieval, to the query itself.

What Gets Embedded

the HyDE passage below is written by hand as a labelled example of what an LLM would draft — no model runs in this page

What Actually Gets Embedded

Ranked Against Three Passages

Target Document

Rank2 of 3
Similarity
0.229

 

Query Rewriting and HyDE: A Practical Guide

Sometimes the query is the part that needs fixing, not the index.

Two ways to close the gap

Query expansion adds related terms to the original query — synonyms, likely technical vocabulary — widening what it can match against. HyDE (Hypothetical Document Embeddings) goes further: ask a language model to draft a plausible answer to the question, without ever checking whether that answer is true, and embed that hypothetical answer instead of the question. A fabricated but stylistically realistic answer sits much closer in embedding space to a real answer than a terse question ever does — the retrieval step never sees or uses the hypothetical text's truth, only its vocabulary and register.

The vocabulary gap

Users do not phrase questions the way documents phrase answers.

User: "why is my thing not working"
Document: "Troubleshooting connection failures in the client library"

Nothing overlaps. The embedding similarity is low, keyword overlap is zero, and the right document is not retrieved — even though it is the answer.

That mismatch has a name, the vocabulary gap, and it is one of the largest sources of retrieval failure in real systems. Two families of technique address it, both by changing the query rather than the index.

Query rewriting

Use a model to reformulate the question before searching. Several distinct operations hide under the same name:

Expansion. Add synonyms and related terms. "car" becomes "car automobile vehicle".

Clarification. Turn a vague question into a specific one. "why is my thing not working" becomes "why is the client library failing to connect".

Decomposition. Split a multi-part question into parts, retrieve for each, and combine. "How do refunds and exchanges differ?" becomes two searches.

Contextualisation. Resolve references against conversation history. "What about for premium users?" becomes "What is the refund policy for premium users?" — and this one is essential in any chat interface, because a follow-up question is meaningless as a standalone search.

Multi-query. Generate several rewrites, search with each, and fuse the results. Broader recall at the cost of several searches.

prompt = """Rewrite this question as 3 different search queries that would
find relevant documents. Return one per line, no numbering.

Question: {question}"""

queries = model.generate(prompt).strip().split("\n")
results = rrf([index.search(q, k=20) for q in queries])

Contextualisation deserves emphasis because it is the one that is always needed and often forgotten. Without it, the second turn of every conversation retrieves badly.

HyDE: search with a fabricated answer

HyDE — hypothetical document embeddings — takes an unintuitive approach that works surprisingly well.

Instead of embedding the question, ask a model to write a plausible answer, then embed that and search with it.

Question: "why is my thing not working"
Hypothetical answer: "Connection failures in the client library are usually caused by an expired API token, an incorrect endpoint URL, or a firewall blocking outbound requests on port 443. Check the token expiry first..."

That fabricated passage is written in the same register as the documents you are searching — technical, declarative, using the vocabulary answers use. Its embedding sits much closer to real answer passages than the question's embedding did.

The generated answer may be factually wrong, and that does not matter. It is never shown to the user; it is used only as a search key, and what makes it useful is its style and vocabulary, not its accuracy.

 Question embeddingHypothetical answer embedding
RegisterInterrogative, informalDeclarative, domain vocabulary
LengthShortParagraph
Match against documentsWeakStrong

Two practical variants: generate several hypothetical answers and average their embeddings, which is more robust; and combine the hypothetical embedding with the original question's rather than replacing it.

Measuring the vocabulary gap, and closing it

Query rewriting and HyDE both attack the same problem -- a short question does not look like the long answer that would satisfy it. This measures that gap on real vectors, applies both fixes, and finds the case where each one makes retrieval worse.

example_01.pyNumPy
Output

Experiments to try

  1. Read the raw query's ranking. A passage about data drift in production beats the overfitting passage — it happens to share more surface words ("model", "worse", "new", "data") with the terse question, even though the overfitting passage is the intended answer.
  2. Switch to the expanded query. A handful of added technical terms — "overfitting", "generalization" — appear in the target passage but not the drift one, and that is enough to move the target back to the top.
  3. Switch to HyDE. The hypothetical answer is written in the same register as the target passage — full sentences, technical vocabulary, no question words — and it pulls ahead by the widest margin of the three, precisely because it does not resemble the drift passage's phrasing at all.
  4. Compare all three similarity numbers. Same underlying question, same target document, three very different embedded-text choices — and three different outcomes for whether the right document is even reachable.

What can go wrong

HyDE embeds a fabrication. If the hypothetical answer is confidently wrong about the topic rather than just stylistically answer-shaped, it can retrieve confidently wrong documents just as easily as right ones — it improves vocabulary match, not correctness. It also costs an extra model call before retrieval even starts, which query expansion usually does not.

The short of it

Retrieval quality is not only a property of the index and the similarity metric — it depends on how close the embedded query text sits to the embedded document text in vocabulary and register. Query expansion narrows that gap cheaply by adding terms; HyDE narrows it further by replacing the question with a fabricated answer written in the target register, at the cost of an extra generation step and the risk of chasing a plausible-sounding but wrong hypothesis.

What each costs

Every one of these techniques adds a model call before retrieval starts.

TechniqueExtra callsExtra latency
Contextualisation1200–500ms
Single rewrite1200–500ms
Multi-query (3 rewrites)1, then 3 searches300–700ms
HyDE1 generation500–1500ms — it generates a paragraph

HyDE is the most expensive because it generates substantially more text. A small fast model is usually adequate for the generation, which brings the cost down considerably.

Three mitigations worth having:

Cache by query text. Repeated and similar questions are common, and the rewrite is deterministic at temperature 0.

Run rewrites in parallel with the original query's search, so the latency is the maximum rather than the sum.

Apply selectively. Short vague queries benefit; long specific ones usually do not. A length or specificity heuristic avoids paying the cost when there is nothing to gain.

When these help, and when they hurt

They help most with: short vague queries, conversational follow-ups, domain jargon the user does not know, and multi-part questions.

They hurt when: the query already contains exact identifiers — rewriting "error E4471" can lose the code, which was the most useful part. Guard by keeping the original query in the fused search alongside any rewrites.

HyDE specifically hurts when the model has no knowledge of the domain and generates a hypothetical answer that is not merely wrong but off-topic, pulling retrieval in an unhelpful direction.

The safe general pattern is additive rather than substitutive: search with the original query and the rewrites, and fuse. That way a bad rewrite dilutes the results slightly rather than replacing them.

Where they sit in a pipeline

A realistic ordering, with each stage added only if it measures better:

  1. Contextualise against conversation history — almost always worth it in chat.
  2. Self-query to extract metadata filters, if the corpus has metadata.
  3. Rewrite or HyDE to close the vocabulary gap.
  4. Hybrid retrieval — dense plus BM25 — with the original and rewritten queries.
  5. Fuse with reciprocal rank fusion.
  6. Rerank with a cross-encoder.
  7. Deduplicate or apply MMR.

Measure each addition on a question set with known answers. In most systems hybrid search and reranking give the largest gains, and query transformation matters most where users phrase things very differently from the documents.

Questions people ask

Does HyDE need a large model? No — the hypothetical answer only needs the right register and vocabulary. A small fast model works well.

Does it matter that the hypothetical answer is wrong? Not for retrieval, since it is used only as a search key. It would matter if you showed it to the user, which you should not.

Should I replace the original query? No — search with both and fuse. That way a poor rewrite cannot destroy the results.

How many rewrites for multi-query? Three to five. Beyond that, returns flatten and latency grows.

Is query rewriting better than a better embedding model? A better embedding model helps every query; rewriting helps the badly-phrased ones. Try the model first.

Can I cache these? Yes, and you should — keyed on the query text, at temperature 0.

Recap in one screen

  • Users phrase questions differently from how documents phrase answers, and that gap causes retrieval failures.
  • Query rewriting expands, clarifies, decomposes or contextualises the question before searching.
  • Contextualising against conversation history is essential in chat, and frequently forgotten.
  • HyDE generates a plausible answer and searches with its embedding, matching the documents' register.
  • Search with the original query as well as the rewrites, and fuse — never substitute blindly.

Recall check

0 of 3

Say the answer out loud before you reveal it — recalling it is what makes it stick, and rereading it is not.

  1. What does this module say about “Before the details”?

  2. What does this module say about “What Gets Embedded”?

  3. What does this module say about “Two ways to close the gap”?

Cheat sheet

Query Rewriting and HyDE

Questions and answers are written in different registers. Closing that gap before you embed anything is often worth more than a better embedding model.

GEN AI · vizlearn.in/gen_ai/query_rewriting_and_hyde.html

Further reading

About the author

Ashish Jangra builds and maintains VizLearn. Every module here is written and the visualisation behind it hand-built, so the numbers in a readout come from the same code that draws the picture. Corrections are genuinely welcome and get priority over everything else — if a page states something wrong, or an animation misrepresents what the algorithm does, get in touch.