A retrieval-augmented generation system often searches with the user’s latest message. That works for self-contained questions, but conversational questions frequently depend on earlier turns.
Consider a support assistant. The user first asks about a failed database migration, discusses PostgreSQL for several turns, and then asks:
Does the rollback command work on version 16 too?Searching that sentence literally may retrieve pages about unrelated rollback commands because the query does not say what is being rolled back. A query rewriter can turn the conversational message into a self-contained retrieval query such as:
PostgreSQL 16 database migration rollback commandThe useful part is not making the query sound better. It is recovering the information needed for retrieval while preserving the user’s actual constraints. A bad rewrite can silently change a product name, version, negation, date, or scope and make retrieval confidently answer the wrong question.
This article develops a practical mental model for RAG query rewriting, shows the smallest useful implementation pattern, explains where rewriting helps and hurts, and describes how to evaluate it separately from the final generated answer.
Treat rewriting as a retrieval transformation
A query rewriter sits between the user’s request and the retriever:
conversation
|
v
query rewriter -> retrieval query -> retriever -> evidence -> answer modelIts job is narrower than answering the question. It should produce a representation that helps the retrieval system find relevant evidence.
That distinction matters because a good answer and a good search query have different properties. An answer may explain, qualify, and synthesize. A retrieval query usually needs the entities, constraints, and terminology that distinguish relevant documents from irrelevant ones.
For example:
Conversation:
User: Our image classifier is deployed on factory cameras.
User: We changed from daytime-only data to day and night data.
User: How should we check whether it got worse?
Possible retrieval query:
evaluate image classifier performance after day and night input distribution changeThe rewrite resolves what “it” refers to and makes the distribution change explicit. It does not invent a metric or decide that the model has degraded.
A useful rule is:
rewrite = recover retrieval context, not solve the taskKeeping that boundary clear reduces the chance that the rewriter inserts unsupported conclusions into the search process.
Start with the smallest useful rewrite
Suppose a developer documentation assistant receives this conversation:
User: I'm using the Acme Search API v3.
Assistant: What are you trying to configure?
User: Hybrid retrieval. Does it support filters before ranking?The final message contains two references that are weak in isolation: “it” and the implied product version. A useful rewrite is:
Acme Search API v3 hybrid retrieval filters before rankingNotice what changed:
Acme Search API v3was copied from conversation context.hybrid retrievalwas preserved from the current request.filters before rankingwas preserved rather than generalized to “filtering.”- No answer was added.
Now compare a risky rewrite:
How to configure pre-filtering for hybrid vector search in Acme Search API v3This sounds natural, but it assumes that “filters before ranking” means a feature called “pre-filtering” and that the product uses vector search. Those assumptions may be correct, but the conversation did not establish them. If the documentation uses different semantics, the rewrite can bias retrieval toward the wrong feature.
The safest first implementation therefore favors context restoration over semantic expansion. Add missing context that is clearly supported by the conversation before trying synonyms, inferred terminology, or broader query expansion.
Preserve constraints as first-class data
The most damaging rewrite errors often involve small words and values rather than the main topic.
Suppose the user asks:
Find guidance for models that do not send prompts to an external service.A rewrite that becomes:
external hosted language model prompt privacy guidancehas reversed the practical intent. The word not carried more decision value than the generic phrase language model.
The same problem appears with versions, dates, regions, languages, hardware limits, and exclusions:
Python 3.12, not 3.11
before January 2025
EU region only
CPU inference, no GPU
open-source models onlyA useful design is to think of the rewriter as preserving two layers:
intent: what information is being requested?
constraints: what must remain true about acceptable results?Even if your production retriever accepts only a text query, keeping these layers separate during development makes failures easier to inspect. A conceptual intermediate representation might look like this:
intent: "find guidance for running a language model locally"
constraints:
- "no external prompt processing"
- "CPU only"The final retrieval query can then be produced from both pieces. This is a teaching representation, not a requirement for any particular API.
Copy exact identifiers when they matter
Names such as model IDs, error codes, package names, product versions, and configuration keys often work better when copied exactly rather than paraphrased.
If a user reports:
Error: EMBEDDING_DIMENSION_MISMATCHrewriting it as “vector size error” throws away a high-value lexical signal. Semantic retrieval may still find useful documents, but exact identifiers can be especially valuable to lexical or hybrid retrieval.
A rewriter should therefore distinguish ordinary natural language from tokens whose exact form may carry retrieval value.
Resolve conversational references conservatively
Follow-up questions contain pronouns and omitted subjects because humans rely on shared context. Query rewriting is useful when it restores that context.
Consider:
User: Compare cosine similarity and dot product for normalized embeddings.
Assistant: ...
User: What happens if I skip that step?Here, “that step” most plausibly refers to normalization. A self-contained query could be:
effect of skipping embedding normalization when comparing cosine similarity and dot productBut reference resolution becomes dangerous when several antecedents are plausible:
User: We chunk documents, embed them, and rerank the top results.
User: Can I remove that stage to reduce latency?Without more context, “that stage” could refer to embedding, reranking, or even the whole retrieval sequence. A rewriter that chooses one silently may retrieve excellent evidence for the wrong question.
In an interactive application, ambiguity may be better handled by asking the user to clarify. In a pipeline that must continue without another turn, a conservative alternative is to retain more of the original wording or search multiple plausible interpretations if the added retrieval cost is acceptable.
The important principle is that rewriting cannot recover information that the conversation never disambiguated.
Choose between rewriting and query expansion
Query rewriting and query expansion are related but solve different problems.
Rewriting produces a better representation of the same request, often by making a conversational query self-contained:
"Does it work in v3?"
-> "Acme Search hybrid retrieval filtering support in API v3"Expansion produces additional formulations or terms intended to increase recall:
"model serving latency"
-> "model serving latency inference delay response time"Expansion can help when relevant documents use different vocabulary, but it also increases the chance of topic drift. If a system adds “response time,” “throughput,” “batching,” and “GPU utilization” to every latency query, it may retrieve documents that are adjacent to the topic rather than relevant to the user’s specific problem.
Start with rewriting when the main problem is missing conversational context. Add expansion only when evaluation shows that vocabulary mismatch is causing retrieval misses.
Use multiple queries only when one rewrite is too narrow
A single rewritten query is easy to reason about and cheap to execute. Sometimes, however, one formulation cannot represent several useful retrieval angles.
Suppose the user asks:
Why does my RAG system find the right document but still miss the answer inside it?One query might emphasize chunking:
RAG correct document retrieved but answer missing from retrieved chunkAnother might emphasize passage selection:
RAG passage retrieval misses relevant section inside correct documentSearching both can improve recall when the corpus uses inconsistent terminology. The trade-off is additional retrieval work and more candidates to merge, deduplicate, or rerank.
Do not generate many paraphrases merely because a language model can. Each extra query should have a reason to cover a distinct interpretation, vocabulary family, or subproblem. Otherwise, the system spends latency and retrieval budget on near-duplicates.
A practical policy is:
clear self-contained request -> search original or one rewrite
context-dependent request -> one context-restored rewrite
known vocabulary mismatch -> small number of distinct expansions
true ambiguity -> clarify or search explicit alternativesThe exact policy should be validated on your corpus and workload.
Keep the original query available
Rewriting is a transformation, and transformations can lose information. One simple safeguard is to retain the original user query alongside the rewrite.
You can use the pair in several ways:
original query -> retrieval A
rewritten query -> retrieval B
|
v
merge or rerankThis costs more retrieval work, but it gives the original wording a path to contribute exact terms that the rewriter may have removed.
Another option is to log both strings while searching only the rewrite. That does not protect retrieval directly, but it makes evaluation and debugging much easier because you can see whether failures began at rewriting or later in the pipeline.
Do not assume that searching both is automatically better. Duplicate candidates can consume a fixed top-k budget, and additional searches add latency and cost. Compare the strategy against a simpler baseline.
Separate rewrite quality from answer quality
A final answer can fail even when rewriting succeeds. The retriever may miss relevant documents, the reranker may order them badly, or the answer model may ignore good evidence. Conversely, a weak rewrite can occasionally produce a correct answer by luck.
Evaluate the stages separately.
For a small evaluation set, store at least:
conversation
current user message
rewritten query
relevant document or passage IDs
retrieved resultsThen compare retrieval using the original query and the rewritten query. Depending on the task, useful retrieval measures include whether a relevant item appears in the top k results, reciprocal rank of the first relevant item, or recall over known relevant items.
For example, imagine 100 conversational questions with at least one labeled relevant passage:
relevant passage in top 5
original latest message 68 / 100
rewritten query 79 / 100That result would show an improvement on this evaluation set, not a universal 11-point benefit from rewriting. Break the results down by query type before drawing a design conclusion.
You may discover something like:
self-contained questions: rewrite -2 points
pronoun follow-ups: rewrite +18 points
versioned questions: rewrite +12 pointsThat pattern suggests routing rather than rewriting everything.
Evaluate whether the rewrite preserved meaning
Retrieval metrics tell you whether relevant evidence was found. They do not fully tell you whether the rewrite changed the user’s request.
Add targeted checks for high-value constraints. For example, annotate whether each source query contains:
- a negation that must be preserved;
- a version or date;
- a named entity or exact identifier;
- a geographic or language constraint;
- an inclusion or exclusion condition.
Then inspect whether those constraints survive the rewrite.
A simple automated validator can catch exact fields that your application already knows. If the UI supplies product_version = "3", for example, you do not need a language model to rediscover that value from prose. Pass the structured value into retrieval explicitly where the search system supports it.
Model-based judging can also help at scale, but treat it as another imperfect evaluator. Calibrate it against human-reviewed examples before using it as the sole gate for meaning preservation.
Do not rewrite every query
A common mistake is placing an LLM rewrite call in front of every retrieval request. That adds latency and cost even when the user already supplied an excellent query.
This message is already self-contained:
How does cosine similarity behave when both embedding vectors are L2-normalized?A rewrite may add little value and can introduce new failure modes.
A lightweight router can decide whether rewriting is warranted. Signals might include pronouns, omitted entities, references to earlier turns, very short follow-ups, or known conversational patterns. These are heuristics, not guarantees, so measure their errors.
You can also use a simple policy based on conversation state:
if request is self-contained:
search(request)
else:
search(rewrite(conversation, request))The difficult part is deciding “self-contained,” not implementing the branch. Start with a small labeled set of real queries and inspect false positives and false negatives before building a complex classifier.
Control latency and cost explicitly
Rewriting adds work before retrieval begins. If the rewrite requires a remote model call, it can increase time to first useful evidence even when retrieval itself is fast.
The end-to-end cost can include:
rewrite model latency
+ rewrite model usage
+ additional searches for multi-query expansion
+ candidate merging or rerankingMeasure these separately. A retrieval improvement that adds unacceptable tail latency may not be a good production trade-off.
Several approaches can reduce overhead:
- Skip rewriting for self-contained queries.
- Use a smaller model when it preserves intent well enough on your evaluation set.
- Keep the rewrite output short and task-specific.
- Generate multiple queries only for cases that benefit from them.
- Cache rewrites only when the complete conversational inputs and relevant retrieval configuration make reuse semantically safe.
The correct choice depends on the value of improved retrieval relative to latency and compute in your application.
Common failure modes
Answering instead of rewriting. The rewriter inserts a likely answer into the query. Retrieval then becomes biased toward evidence matching the model’s guess.
Dropping negation. “Models that do not require a GPU” becomes “GPU model requirements.” The topic remains similar while the intent reverses.
Changing exact identifiers. An error code, model name, or version is paraphrased into generic language, weakening a useful lexical signal.
Over-expanding terminology. The rewrite adds many related concepts and retrieves broad background material instead of evidence for the specific question.
Resolving ambiguous references with false confidence. The system chooses what “it” or “that” means when the conversation supports several interpretations.
Rewriting already-good queries. The system pays extra latency and occasionally degrades retrieval without solving a real problem.
Evaluating only final answers. A correct answer hides a poor rewrite, or an answer-generation failure makes a good rewrite look bad. Stage-level metrics are needed to locate the problem.
Testing only synthetic follow-ups. Handwritten examples are useful for development, but production conversations contain abbreviations, corrections, topic switches, and incomplete sentences that curated examples may miss.
Build a practical evaluation loop
A useful rollout can stay small.
First, collect a representative set of conversational retrieval requests and label the passages or documents that should be retrievable. Include self-contained questions as well as follow-ups so the rewriter has opportunities both to help and to do harm.
Second, run two paths:
baseline: latest user message -> retrieval
variant: conversation -> rewrite -> retrievalThird, compare retrieval quality, latency, and rewrite preservation errors. Inspect regressions manually, especially cases involving negation, identifiers, and ambiguous references.
Fourth, decide where rewriting earns its cost. You may find that it is valuable only for follow-up questions. That is a useful result: a conditional rewrite stage is simpler and cheaper than rewriting all traffic.
Finally, continue evaluating after changing the rewrite prompt, model, retriever, embedding model, corpus, or ranking strategy. Query rewriting is coupled to retrieval behavior. A rewrite that worked well for one corpus and retriever is not guaranteed to remain optimal after the retrieval system changes.
When rewriting is the wrong tool
Do not add query rewriting when the problem is elsewhere in the pipeline.
If the correct passage is retrieved but ranked too low, reranking may be the more direct intervention. If the correct document is found but the relevant fact is split across poor chunks, improve chunking or passage construction. If the corpus simply lacks the required information, no rewrite can retrieve evidence that is not there.
Likewise, if users submit short keyword queries that already match a well-indexed domain vocabulary, rewriting may add complexity without measurable gain.
Use rewriting when retrieval failures come from how the request is expressed: missing conversational context, references to earlier turns, or vocabulary mismatch that evaluation shows can be corrected without changing intent.
Conclusion
RAG query rewriting is most useful when you treat it as a controlled retrieval transformation rather than a miniature answering step. Restore context that the user clearly established, preserve constraints and exact identifiers, and be conservative when references are ambiguous.
Start with one self-contained rewrite, keep the original query available for debugging, and add expansion or multiple searches only when measured retrieval failures justify them. Most importantly, evaluate rewriting at the retrieval stage. A rewrite is valuable because it helps the system find better evidence without changing what the user asked—not because the rewritten sentence sounds more polished.