Command Palette

Search for a command to run...

Hectal
PHASE 7Intermediate ~26 min· topic 4 of 9

Topic 7.4

Many Queries for One Question

In one line

One question can be several questions, or one question in several phrasings. Search with each, then fuse the ranked lists with reciprocal rank fusion so passages that several searches agree on rise to the top.

Think of it like this

You lost your keys and ask three friends to look. One checks the kitchen, one the car, one the coat pockets. None searches everywhere, but together they cover the likely places, and if two of them say "I saw them on the hall table" you go there first. Several searches, then a vote.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

Multi-query
Running several searches for one user question and combining the results.
Decomposition
Splitting a compound question into simpler sub-questions.
Query variant
Another phrasing of the same question.
Fusion
Combining several ranked lists into one.
RRF
Reciprocal rank fusion: each list gives 1 / (60 + rank) to every passage in it, and the scores are added.
Rank
Position in a list, starting at 1 for the best.

Step by step

01Step 1: see a single search miss half the question

With k = 1 the compound question returns only D8. The helmet half is simply not in the results, and the model would answer half the question or invent the rest.

02Step 2: split with a guard

Split at " and " only if every part keeps two or more content words. Otherwise return the question whole.

split.pywhole filepython
def split_question(question):
    parts = [part.strip() for part in question.replace("?", "").split(" and ")]
    if len(parts) > 1 and all(len(content_words(part)) >= 2 for part in parts):
        return parts
    return [question]

03Step 3: search each part and merge

Take the top hit of each part and keep them in order without repeats. The merged list covers both halves of the question.

04Step 4: use phrasings instead of parts

Three ways of asking about a broken bike each return a partial list. The example prints each list so you can see who found what.

05Step 5: fuse the lists with RRF

Each list gives 1 / (60 + rank) to its passages. Add them up and sort. The constant 60 is the same as in the search lab and Topic 6.3.

Step 5: fuse the lists with RRFdiagram
Rendering diagram…

06Step 6: check what the fusion rewarded

D5 was in two lists at rank 1 and won. D10 was in one list at rank 1 and came second. D7 and D9 were only in the first list. Agreement counts, but a single strong vote still matters.

Try it yourself

  1. 1

    Break the guard

    Change >= 2 to >= 1 in the split rule and add the question "Is there a fee for the pass and the helmet?". How many parts do you get, and are they useful?

  2. 2

    Add a fourth phrasing

    Add "bike stolen unlocked" as a fourth variant. Predict where D12 lands in the fused list before running.

  3. 3

    Change k

    Set the per-query k to 1 in the fusion example. How does the fused list change? When is a small k per query enough?

Code & diagrams

Split a compound question and merge New tab

Both compound questions return only half the answer when searched whole with k = 1. The third has no "and" and is searched whole.

Sign in to run this example in your browser.

Expected output

Q: What does the monthly pass cost and do I need a helmet?
   whole question, k=1: D8 (2)
   part "What does the monthly pass cost" -> D8 (2)
   part "do I need a helmet" -> D4 (1)
   merged: D8, D4
Q: When do shops close and how long does a battery last?
   whole question, k=1: D2 (2)
   part "When do shops close" -> D2 (2)
   part "how long does a battery last" -> D7 (1)
   merged: D2, D7
Q: What are the rules for riders under 16?
   whole question, k=1: D4 (3)
   part "What are the rules for riders under 16?" -> D4 (3)
   merged: D4
Several phrasings fused with RRF New tab

The variants are written by hand here. In production a model writes them, with the guards of Topic 7.2.

Sign in to run this example in your browser.

Expected output

What if my bike breaks?  -> D5, D7, D9
damaged report           -> D5
flat tyre repair         -> D10
first phrasing alone:    D5, D7, D9
fused:                   D5 0.0328, D10 0.0164, D7 0.0161, D9 0.0159

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Take the maximum instead of the sum

In the Python tab of the second example, replace the sum in rrf with a maximum: change the line to scores[doc_id] = max(scores.get(doc_id, 0.0), 1 / (K + rank)). Run.

terminal
$ Run
── what you'll see ──
first phrasing alone: D5, D7, D9
fused: D5 0.0164, D10 0.0164, D7 0.0161, D9 0.0159

Myth vs fact

Myth

More queries always find more.

Fact

Each query can also bring noise, and agreement on a noisy word is rewarded by RRF. Measure the hit rate.

Myth

Splitting on "and" is always right.

Fact

Many sentences use "and" inside one idea. Guard the split.

Myth

RRF needs the scores to be comparable.

Fact

That is its advantage: it uses only ranks, so keyword and vector scores on different scales can be fused.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Run the searches in parallel and set a deadline. Total latency becomes the slowest query, not the sum, and a query that misses the deadline can simply be dropped from the fusion.

  • ▸

    Deduplicate by passage id before the prompt is built. Fused lists often contain the same passage once, but variants of one document (chunks) can crowd the top. Topic 6.6 covers diversity.

  • ▸

    When a model writes the variants, ask for a fixed number (three) and include the original as a variant. Do not trust "as many as you like": the cost grows and the quality does not.

Remember this

  1. 1

    Why multi-query exists. One search returns one list from one point of view. A compound question has two targets, and a single search tends to find only the louder one. A question that could be phrased three ways may match the right passage under only one phrasing. Searching several times and combining the lists spreads the risk.

  2. 2

    Splitting a compound question. "What does the monthly pass cost and do I need a helmet?" asks two things. Searched whole with k = 1, only the pass passage (D8) comes back. Split at "and", each part retrieves its own passage: D8 for the pass, D4 for the helmet. The same happens for the shops and battery question: whole, only D2 (shops); split, D2 and D7 (battery).

  3. 3

    Splitting needs a guard. Not every "and" joins two questions: "salt and pepper" does not. The example splits only when each part keeps at least two content words. The third question has no "and" and is left whole. Splitting by rule is easy to explain and test. A model can split better ("Compare the monthly pass with single rides" has no "and" yet has two parts) but costs a call, with the guards of Topic 7.2.

  4. 4

    Several phrasings of one question. The second use is to search with variants: the original, a more specific rewrite, a keyword version. In the example the three phrasings of "my bike breaks" return D5, D7, D9 for the first, D5 for the second and D10 for the third. Each list is partial and each finds something the others miss.

  5. 5

    Fusing with RRF. Reciprocal rank fusion (Topic 6.3) needs only ranks: every list gives each passage 1 / (60 + rank), and the scores add. D5 is first in two lists and scores 1/61 + 1/61 = 0.0328. D10 appears once, at rank 1 of its list, with 1/61 = 0.0164, which is enough to place it ahead of D7 (1/62 = 0.0161) and D9 (1/63 = 0.0159), which only came from the first phrasing. A passage found by several searches rises, one found by a single search still gets a place.

  6. 6

    RRF rewards agreement, including bad agreement. If every phrasing contains a common word that matches a wrong passage, that passage is boosted by every list. Multi-query is not free insurance: the break-it below shows that taking the maximum instead of the sum loses the reward for agreement, and a noisy shared word does the opposite.

  7. 7

    Cost and where it pays. Each extra query is another retrieval (cheap for keywords, one embedding call for vectors) and, if a model writes the phrasings, a generation call. A common compromise: run the variants in parallel, set k per query to 3 to 5, and fuse to the final number of passages. Measure the hit rate with and without it (Topic 9.3). On well-formed questions it often adds little. The build topic shows a case where it was slightly worse.

Explain it without notes

01

Why can a single search miss half of a compound question?

02

How does reciprocal rank fusion combine lists, and why does it not need comparable scores?

03

What are the risks of splitting a question by rule, and how do you reduce them?

04

When is multi-query not worth it?

Practice

01

Write split_parts(question) that splits at " and " only when each part has at least two words (by split()). Print the parts for "What does the pass cost and do I need a helmet?" and for "Tea and coffee?", joined with " | ".

02

Write rrf(rankings) returning "id score" pairs (4 decimals) for lists [["a", "b"], ["b", "c"]], best first, with 1 / (60 + rank).

Trade-offs

  • ↔

    Splitting by rule: simple and testable, but it can cut a sentence in the wrong place.

  • ↔

    A model that writes the phrasings: richer variants, at the price of a call and a guard.

  • ↔

    More queries: a better chance of covering the answer, with more latency, load and noise.

Done when you can

  • Done when you can split a compound question with a guard and merge the results.

  • Done when you can compute reciprocal rank fusion by hand for three short lists.

  • Done when you can explain why RRF works across different score scales.

  • Done when you can say when a single query is the better choice.