Skip to content
AI Dev Toolkit.
Esc
  • AI Token CounterCount tokens for GPT, Claude, Gemini, DeepSeek, Qwen and more.Tool
  • LLM API Cost CalculatorEstimate per-request, daily and monthly API costs.Tool
  • AI Model ComparisonCompare prices, context windows and features across models.Tool
  • AI Model Pricing PagesSpecs, real costs and cheaper alternatives for popular models.Tool
  • Context Window CheckerSee whether your text fits each model’s context window.Tool
  • Subscription vs API CalculatorFind out whether a chat plan or the API is cheaper for you.Tool
  • GPU / VRAM CalculatorCheck how much VRAM a local model needs and which GPUs fit.Tool
  • Prompt Caching CalculatorEstimate savings from prompt caching.Tool

Prompt template · LLM apps and evals

Query rewriting prompt for RAG search

Turn a follow-up question and chat history into standalone search queries for retrieval. Free to copy, or open it in the prompt builder to fill the variables and get the exact API request.

205 tokens unfilled · 262 with the example below · o200k_base (GPT-4o and later)

Template

The prompt

Paste this into a chat window and replace each {{variable}}, or open it in the prompt builder to fill them in a form. Sections are marked with XML tags, which every major model reads well.

Prompt (one message, plain text)
You turn user questions into search queries for a {{search_type}} over {{corpus}}.

<context>
The conversation so far:
<history>
{{history}}
</history>
</context>

<constraints>
- Resolve references from the history: replace “it”, “that plan” or “the second one” with what they mean.
- Write one to three queries. Use more than one only if the question has separate parts or could use different terms.
- Use the vocabulary the documents are likely to use, not the user’s slang. Keep product names and error codes exactly as written.
- Don’t answer the question.
- If the question doesn’t need a search (a greeting, a thank-you), return an empty list.
</constraints>

<output_format>
JSON only: {"queries": ["...", "..."]}
</output_format>

<task>
Rewrite the latest user question as standalone search queries that will find the documents needed to answer it.

<latest_question>
{{latest_question}}
</latest_question>
</task>
For an API call: system prompt and user message

With a system prompt, the role, constraints and output format stay fixed across calls (and can be cached), while the context and task go in the user message.

System prompt
You turn user questions into search queries for a {{search_type}} over {{corpus}}.

<constraints>
- Resolve references from the history: replace “it”, “that plan” or “the second one” with what they mean.
- Write one to three queries. Use more than one only if the question has separate parts or could use different terms.
- Use the vocabulary the documents are likely to use, not the user’s slang. Keep product names and error codes exactly as written.
- Don’t answer the question.
- If the question doesn’t need a search (a greeting, a thank-you), return an empty list.
</constraints>

<output_format>
JSON only: {"queries": ["...", "..."]}
</output_format>
User message
<context>
The conversation so far:
<history>
{{history}}
</history>
</context>

<task>
Rewrite the latest user question as standalone search queries that will find the documents needed to answer it.

<latest_question>
{{latest_question}}
</latest_question>
</task>

Variables

What to put in each variable

{{search_type}}
The retrieval method, such as “keyword search”, “vector search” or “hybrid search”. Keyword search needs exact terms; vector search tolerates paraphrase.
{{corpus}}
What is being searched, such as “our product help centre” or “the engineering wiki”.
{{history}}
The last few turns of the conversation. Three to six turns is usually enough context.
{{latest_question}}
The user’s newest message.

Use

When to use it

Use it in a chat-based RAG system before retrieval. Follow-up questions such as “what about on the free plan?” mean nothing to a search index on their own; rewriting them into standalone queries is one of the simplest ways to improve what retrieval returns.

For single-turn search boxes, it still helps with vague or multi-part questions, but test whether it beats sending the raw question. Every extra model call adds latency and cost, so measure the retrieval improvement on your own data.

Structure

Why it’s structured this way

The search type and corpus are in the role because they change what a good query is. Keyword search needs the exact terms the documents use, while vector search works better with a natural sentence. Telling the model which it is writing for avoids queries that suit the wrong engine.

Resolving references is the main job, and the constraint gives concrete examples of what to resolve. Keeping product names and error codes exactly as written matters because those are often the only terms that match precisely.

Returning a list, possibly empty, makes the output easy to wire up: run each query, merge the results. The empty case saves a pointless retrieval for messages like “thanks”, and the “don’t answer” rule stops the model from skipping ahead.

Example

A filled-in example

{{search_type}}
hybrid keyword and vector search
{{corpus}}
a hosting company’s help centre
{{history}}
User: How do I add a custom domain?
Assistant: Go to Sites, then Domains, then Add domain, and follow the DNS steps shown.
User: Is SSL included?
Assistant: Yes. A certificate is issued automatically once the DNS records are verified.
{{latest_question}}
and does that work on the free plan?

What to look for. Taken alone, “does that work on the free plan” is unsearchable. Good output resolves “that” to custom domains and SSL, such as custom domain free plan and SSL certificate free plan, keeping “free plan” in the help centre’s wording.

The complete filled-in prompt (262 tokens)
Filled-in prompt
You turn user questions into search queries for a hybrid keyword and vector search over a hosting company’s help centre.

<context>
The conversation so far:
<history>
User: How do I add a custom domain?
Assistant: Go to Sites, then Domains, then Add domain, and follow the DNS steps shown.
User: Is SSL included?
Assistant: Yes. A certificate is issued automatically once the DNS records are verified.
</history>
</context>

<constraints>
- Resolve references from the history: replace “it”, “that plan” or “the second one” with what they mean.
- Write one to three queries. Use more than one only if the question has separate parts or could use different terms.
- Use the vocabulary the documents are likely to use, not the user’s slang. Keep product names and error codes exactly as written.
- Don’t answer the question.
- If the question doesn’t need a search (a greeting, a thank-you), return an empty list.
</constraints>

<output_format>
JSON only: {"queries": ["...", "..."]}
</output_format>

<task>
Rewrite the latest user question as standalone search queries that will find the documents needed to answer it.

<latest_question>
and does that work on the free plan?
</latest_question>
</task>

Models

Tips by model family

  • All models

    A small, fast model is usually enough for rewriting. It runs on every turn, so its latency adds directly to the time before the answer starts.

  • OpenAI GPT

    Use Structured Outputs with an array of strings for queries. OpenAI notes that a refusal may not follow the schema, so check the refusal field before parsing.

  • Gemini

    Google recommends few-shot examples for Gemini. Two examples of a follow-up question and its rewritten queries, taken from your own logs, teach the resolution pattern quickly.

Related

Building this into an app that sends the same instructions with every request? Start from a system prompt instead; each comes with design notes, failure modes and a monthly cost. In the system prompt library: Search query rewriter for RAG.

Edited the template? Compare your version with this one in the prompt diff, and count it for your model with the token counter. In the glossary: rag. Browse all 29 prompt templates.