Part 2 of 6 · 2 min read
Rewrite and multi-query
Make the question stand alone, then ask it several ways.
Rewrite: make the question stand alone
Query rewriting
Turning the user's latest message, plus the conversation so far, into a self-contained search query.
Retrieval sees only the string you give it. "How do I fix it?" has no subject, so it matches nothing in particular. The rewrite step uses the history to fill the gap.
rewrite(["What does E-4021 mean?"], "how do I fix it?")
# 'how do I fix E-4021?'
rewrite(["How long are audit logs kept on the Zephyr plan?"], "what about Starter?")
# 'How long are audit logs kept on the Starter plan?'
A real system asks a model something like "given the conversation, rewrite the last message so it makes sense on its own". Watch for two traps: the model may add details the user never said, and a message that is already standalone should come back unchanged (a test checks that the example does so).
Multi-query: ask several ways
Multi-query (query expansion)
Generating several alternative phrasings of the question, searching with each, and fusing the result lists (module 3's RRF works well here).
This targets the vocabulary gap: the user says "money back", the document says "refund". The example swaps informal words for the words the documents use:
multi_query("the app keeps crashing")
# ['the app keeps crashing', 'the app keeps crash', 'the app keeps broken']
The variants are crude (that is a toy), and they still help, because one of them contains a word the right passage has. A real model produces fluent paraphrases. The older, model-free version is pseudo-relevance feedback: search once, take the salient words from the top results and add them to the query. Both versions share a risk, topic drift: expansions that wander away from what the user meant.