Pipeline Multi-Hop QA
🎯 Trigger Conditions
Use when asked about multi-hop question answering, complex reasoning chains, or iterative retrieval-augmented generation.
📚 Prerequisites
dspypackage installed- Retriever configured
- Multi-hop dataset available
🛠️ Multi-Hop Patterns
1. Basic Multi-Hop
class MultiHopQA(dspy.Module):
def __init__(self, n_hops=2):
self.n_hops = n_hops
self.retrieve = dspy.Retrieve(k=3)
self.answer = dspy.Predict("context, question -> answer")
def forward(self, question):
context = []
current_question = question
for _ in range(self.n_hops):
# Retrieve relevant passages
passages = self.retrieve(current_question).passages
context.extend(passages)
# Generate next question if needed
if _ < self.n_hops - 1:
next_q = dspy.Predict("context, question -> next_question")(
context=context, question=current_question
).next_question
current_question = next_q
return self.answer(context=context, question=question)
2. Adaptive Multi-Hop
class AdaptiveMultiHopQA(dspy.Module):
def __init__(self, max_hops=3):
self.max_hops = max_hops
self.retrieve = dspy.Retrieve(k=3)
self.answer = dspy.Predict("context, question -> answer")
self.decide = dspy.Predict("context, question -> continue_search")
def forward(self, question):
context = []
for hop in range(self.max_hops):
# Retrieve passages
passages = self.retrieve(question).passages
context.extend(passages)
# Decide if more search is needed
should_continue = self.decide(
context=context, question=question
).continue_search
if not should_continue:
break
return self.answer(context=context, question=question)
3. Multi-Hop with Evidence
class MultiHopWithEvidence(dspy.Module):
def __init__(self):
self.retrieve = dspy.Retrieve(k=3)
self.answer = dspy.Predict("context, question -> answer, evidence")
def forward(self, question):
context = []
evidence = []
# First hop
passages1 = self.retrieve(question).passages
context.extend(passages1)
# Second hop with refined question
passages2 = self.retrieve(question + " from " + passages1[0]).passages
context.extend(passages2)
evidence.extend(passages1)
return self.answer(context=context, question=question)
⚠️ Pitfalls
- Error propagation: Errors compound across hops
- Context length: Manage context window carefully
- Latency: Multi-hop increases response time
- Quality: Later hops may degrade in quality