query-rewrite
Published
Public
in @rag-essentials

Rewrite a conversational user query into a standalone, retrieval-optimized query (plus optional alternatives for multi-query retrieval).

query-rewrite

Turn a raw, conversational user query into a standalone, retrieval-optimized query — pronouns resolved, filler dropped, keywords surfaced — and optionally a handful of alternative phrasings for multi-query retrieval. The first stage of a RAG pipeline: a better query in means better chunks out.

Built for LangChain / LlamaIndex retrievers, conversational RAG (where the latest turn is full of "it" / "that one" / "there"), and multi-query fan-out retrieval.

Entrypoints

EntrypointRendersInputs
systemThe rewriter instructions + embedded output schemaconversationHistory?, numAlternatives? (control phrasing)
userThe delimited query block (+ optional history)query, conversationHistory?

Render system as the system message and user as the user message. The optional variables are read by both entrypoints — pass them to both renders.

Variables

  • query (string, required) — the user's (possibly conversational) query to rewrite.
  • conversationHistory (string, optional) — prior turns, used to resolve pronouns/references in query. Turns labeled by speaker (User: / Assistant:) work best. Omit for a single-shot query.
  • numAlternatives (integer, optional) — how many additional phrasings to produce for multi-query retrieval. Omit (or 0) for none.

Output

parseOutput() returns:

{
  "reasoning": "\"it\" refers to the Pro plan named two turns earlier; rephrased as a keyword-bearing question about pricing.",
  "rewritten_query": "What is the monthly price of the Pro plan?",
  "alternatives": ["How much does the Pro subscription cost per month?", "Pro plan pricing and billing details"]
}
  • reasoning comes before the rewrite by design — it notes which references were resolved and from where. Reasoning that precedes the rewrite informs it.
  • rewritten_query is a single standalone query. It may equal the input verbatim when the query was already clear — the prompt is told not to distort a good query just to look busy.
  • alternatives is empty unless you ask for some via numAlternatives. Each expresses the same information need from a different angle, so they retrieve a complementary set of documents.

House conventions

  • Reasoning-first, key order pinned in the system prompt.
  • Grounded only in the query + history — the prompt forbids inventing intent, entities, or constraints the user did not express. Unresolvable references are left in the user's own words rather than guessed.
  • Injection-safe — the query and history are treated as data; embedded commands ("ignore the above…") are not obeyed.
  • Triple-mustache input ({{{query}}}, {{{conversationHistory}}}) so &, <, " are never HTML-escaped, wrapped in XML-style delimiters.
  • Empty / trivial input → returned essentially unchanged with an empty alternatives.

Notes

Verified by local render and against the live API. Suggested default model claude-sonnet-4-6 at temperature: 0 (carried in version metadata — override per call). First stage of the RAG Essentials pipeline: rewrite → decompose → grade → guardrail → synthesize.

@sufleur/