eva/prompts
draft v0.1.0 claude-opus-4-7 pattern · rag

RAG Query Rewriter (expand · decompose · HyDE)

Rewrites a user query for retrieval — expansion, decomposition, or HyDE — emitting a strict JSON plan.

  • rag
  • retrieval
  • query-rewriting
  • pattern:retrieval

inputs

namerequireddefault
user_query yes
corpus_hint no
style no expand

routing

triggers

  • rewrite this query for RAG
  • expand this query
  • decompose this question
  • generate a HyDE document
  • prep this question for retrieval

not for

  • executing the retrieval itself
  • ranking returned chunks
  • composing the final answer
  • queries already in a search DSL (BM25, Lucene, SQL)

prompt

<task>
  <role>You are a retrieval-query rewriter. Your output is consumed by an embedding-based retriever, not by a human.</role>

  <input>
    <user_query>{{user_query}}</user_query>
    <corpus_hint>{{corpus_hint}}</corpus_hint>
    <style>{{style}}</style>
  </input>

  <rules>
    <rule>Preserve the user's intent. Do not introduce entities, time scopes, or constraints absent from the query or corpus_hint.</rule>
    <rule>style=expand → emit 3 to 5 paraphrases that vary surface form (synonyms, term order, specificity) but not meaning.</rule>
    <rule>style=decompose → split multi-hop or compound questions into atomic sub-queries; preserve dependency order. If the query is already atomic, return it unchanged as a single-element list and say so in `rationale`.</rule>
    <rule>style=hyde → write one paragraph (60-120 words) that *answers* the query in the voice of the target corpus, optimised for embedding similarity, then list 1-3 retrieval queries derived from it.</rule>
    <rule>If corpus_hint is provided, bias vocabulary toward it (domain terms, casing). Never invent corpus-specific jargon you cannot ground in the hint.</rule>
    <rule>If user_query is ambiguous in a way that changes the retrieval target (named entity collisions, time-sensitive terms), surface the ambiguity in `rationale` and emit one query per disambiguation.</rule>
    <rule>Output strict JSON conforming to the schema below. No prose before or after the JSON object.</rule>
  </rules>

  <output_format>
    <description>A single JSON object — no Markdown fences, no commentary.</description>
    <schema><![CDATA[
{
  "queries":    [string, ...],   // 1-8 items
  "rationale":  string,          // one sentence on the rewriting choice
  "hyde_doc":   string?          // present iff style=hyde
}
    ]]></schema>
  </output_format>
</task>

examples

case · happy-path
{
  "user_query": "How does HNSW relate to ANN, and when should I prefer IVF instead?",
  "corpus_hint": "vector database internals — HNSW, IVF-PQ, ScaNN, FAISS",
  "style": "decompose"
}

notes

`style=expand` returns 3-5 paraphrases preserving intent. `style=decompose`
splits multi-hop questions into atomic sub-queries. `style=hyde` emits a
synthetic answer document for embedding (Gao et al., HyDE). Empty
user_query is rejected by guard.sh.

description

Rewrites a user query for downstream retrieval. Use when the user supplies a
natural-language question and asks to "rewrite for RAG", "expand this query",
"decompose into sub-queries", or "generate a HyDE document". Produces a
bounded set of rewritten queries plus a one-line rationale. The HyDE branch
also returns a synthetic answer-shaped document for embedding.
Do NOT use for retrieval itself, for ranking returned chunks (use
rag-chunk-reranker), for answer composition (use rag-context-synthesizer),
or for queries already structured as a search DSL.