class MultiHopHyDESearch(dspy.Module): def __init__(self, retriever): self.generate_queries = dspy.ChainOfThought(QueryGeneration) self.retriever = retriever def forward(self, query, n_hops=3): results = [] for hop in range(n_hops): # Notice we loop multiple times # Generate optimized search queries search_queries = self.generate_queries( query=query, previous_jokes=retrieved_jokes ) # Retrieve using both semantic and keyword search semantic_results = self.retriever.semantic_search( search_queries.semantic_query ) bm25_results = self.retriever.bm25_search( search_queries.bm25_query ) # Fuse results hop_results = reciprocal_rank_fusion([ semantic_results, bm25_results ]) results.extend(hop_results) return results