VereskLearn

Module 4 · Retrieval

Lesson 4.6

Query rewriting

Query rewriting turns one question into several search queries, then merges the results.

Lesson 25 of 622 min read

The problem

Why it matters

Without it

A user writes "my card was charged twice". The documents say "duplicate charge" and "double payment", so one search finds nothing.

With it

A model writes new queries that use the words the documents use. Each query runs, and the hits are merged for the next step.

How it works

  • The question words miss the documents

    A user writes "my card was charged twice". None of the three chunks shares a whole word with that question, so the search returns 0 chunks. The documents say "duplicate charges" and "double payment" instead.

    QueryChunks found
    my card was charged twice0
    duplicate card charge1
    refund for a double payment1
    Chunks found by each query, using whole-word matches over three chunks.
    // A fake model. A real model writes these from the question.const fakeModel = (question: string): string[] => {  return ["duplicate card charge", "refund for a double payment"];};console.log(fakeModel("my card was charged twice"));

    Output

    [ 'duplicate card charge', 'refund for a double payment' ]
  • A model writes other wordings

    A model writes two or three variants of the question, using the words that documents tend to use. Here a fake model returns two fixed variants, so the example runs without a network call. Each variant is searched next to the original question.

    • my card was charged twiceoriginal
    • duplicate card chargevariant 1
    • refund for a double paymentvariant 2
    The original question and its two variants.
  • Each query runs its own search

    A chunk matches when it shares at least one whole word with the query. The word "charged" does not match "charges", so the original question finds nothing. Each variant finds one chunk of its own.

    Chunks found by each query.
    // Whole-word match: "charged" is not the same word as "charges".const query = "my card was charged twice".split(" ");const chunk = "Duplicate charges are refunded in 5 days".split(" ");console.log(query.filter((w) => chunk.includes(w)));

    Output

    []
  • Merging the hits without repeats

    The hits from all queries are joined into one list. A Set keeps one copy of each chunk, so repeats are dropped. The three queries together find 2 different chunks, one from each variant.

    • Duplicate charges are refunded within 5 daysfound by variant 1
    • A double payment is reversed by the bankfound by variant 2
    The two chunks found after merging, with the query that found each.
    // A Set keeps one copy of each value.const hits = ["chunk A", "chunk B", "chunk A"];console.log(new Set(hits).size, [...new Set(hits)]);

    Output

    2 [ 'chunk A', 'chunk B' ]
  • A made-up answer can be searched instead

    HyDE, short for hypothetical document embeddings, asks the model for a short made-up answer. That answer often uses the words the documents use, so its search can find chunks the question missed. The made-up answer can be wrong, so a check is still needed.

    Query variants

    • Rewrites the question
    • Several short queries
    • Hits merged without repeats

    HyDE

    • Writes one made-up answer
    • Searches with that answer
    • Can be wrong, so it needs a check
    Two ways to build the search from the question.

Full code

Read the program

See the full code

Common mistakes

What goes wrong

  • Writing variants that drift from the intent. A variant about replacing a card finds the wrong chunks.
  • Adding too many variants. Each one is a search and a model call, and the merged list grows with noise.
  • Using HyDE without a check. A made-up answer can be wrong, so its search can pull in wrong chunks.

Use it when and skip it when

Is it the right tool?

Use it when

  • Users write short, vague, or informal questions.
  • The documents use different words for the same idea.

Skip it when

  • The question already uses the document words, such as an exact product name.
  • Each extra search or model call adds delay or cost that the product cannot afford.

Words to know

Terms in this lesson

Query variant
A second wording of the same question, written to match the documents.
Merge
Combine several result lists into one list without repeats.
HyDE
A method that searches with a made-up answer instead of the question.
Union
All items found in any list, with repeats removed.
Full code