query-decomposition
Published
Public
in @rag-essentials

Decide whether a complex question needs splitting, and if so break it into a minimal set of independently-answerable sub-queries — without over-decomposing simple questions.

query-decomposition

Break a complex, multi-part question into a minimal set of simpler, independently-answerable sub-queries — and, crucially, decline to split a question that doesn't need it. Each sub-query is retrieved and answered on its own, then the answers are combined. Over-decomposition is the failure mode this prompt is tuned against: it adds retrieval noise and dilutes results.

Built for multi-hop RAG, comparison questions, and any retrieval flow where one fan-out query buries the documents that actually answer each part.

Entrypoints

EntrypointRendersInputs
systemThe decomposition instructions + embedded output schemamaxSubQueries? (caps the split)
userThe delimited question blockquery

Render system as the system message and user as the user message. Pass maxSubQueries to the system render when you want a cap.

Variables

  • query (string, required) — the question to (possibly) decompose.
  • maxSubQueries (integer, optional) — a hard cap on the number of sub-queries. If the question needs more parts than the cap, the most related parts are merged to fit. Omit to let the model pick the minimal set.

Output

parseOutput() returns:

{
  "reasoning": "Asks to compare two plans on two dimensions — distinct facts in different docs, so splitting helps.",
  "is_decomposable": true,
  "sub_queries": [
    "What features are included in the Pro plan?",
    "What features are included in the Enterprise plan?",
    "What is the price of the Pro plan?",
    "What is the price of the Enterprise plan?"
  ]
}

For an atomic question:

{ "reasoning": "A single focused fact one retrieval can satisfy.", "is_decomposable": false, "sub_queries": [] }
  • reasoning comes first — it justifies the split-or-not decision before committing.
  • is_decomposable is true only when answering genuinely needs distinct retrievals (comparison / multiple separate facts / multi-hop). A long-but-focused question stays false.
  • sub_queries is the minimal covering set, each standalone (pronouns resolved, makes sense out of order). It is empty when is_decomposable is false — your caller still has the original query to retrieve with.

House conventions

  • Reasoning-first, key order pinned in the system prompt.
  • Grounded only in the question — no invented entities, constraints, or sub-topics; the prompt does not answer the question, only restate its parts.
  • Anti-over-decomposition is an explicit rule, not a hope: prefer the smallest covering set; atomic ⇒ no split.
  • Injection-safe triple-mustache input wrapped in XML-style delimiters.

Notes

Verified by local render and against the live API (a genuine multi-part question decomposes; a simple one does not over-decompose). Suggested default claude-sonnet-4-6 at temperature: 0. Second stage of the RAG Essentials pipeline: rewrite → decompose → grade → guardrail → synthesize.

@sufleur/