Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/avnlp/dspy-opt/llms.txt

Use this file to discover all available pages before exploring further.

The HotpotQA pipeline is built for questions that cannot be answered from a single passage — each question requires chaining evidence across two or more documents. The pipeline uses the distractor subset of HotpotQA, which interleaves the relevant supporting paragraphs with distractor passages, making both retrieval precision and multi-hop reasoning critical. Documents are indexed into a HotpotQA Weaviate collection with title and category metadata to guide the hybrid search filter step.

Dataset

PropertyValue
HuggingFace IDhotpotqa/hotpot_qa
Subsetdistractor
Splittrain (optimization) / test (evaluation)
Weaviate collectionHotpotQA
Complexity typeMulti-hop reasoning

Pipeline Class

The HotpotQARAG class is defined in hotpotqa_rag_module.py and subclasses dspy.Module. It composes the five shared utility stages — query rewriting, sub-query generation, metadata extraction, hybrid retrieval, and chain-of-thought answer generation — into a single forward() call.
from dspy_opt.hotpotqa.hotpotqa_rag_module import HotpotQARAG

class HotpotQARAG(dspy.Module):
    def __init__(
        self,
        query_rewriter: QueryRewriter,
        sub_query_generator: SubQueryGenerator,
        metadata_extractor: MetadataExtractor,
        metadata_schema: Dict[str, Any],
        weaviate_retriever: WeaviateRetriever,
        embedding_model: SentenceTransformer,
        top_k: int = 3,
    ): ...

    def forward(self, question: str) -> dspy.Prediction:
        """Execute the complete RAG pipeline."""

forward() Return Fields

forward() returns a dspy.Prediction containing the following fields:
FieldDescription
questionThe original input question (passed through unchanged)
rewritten_querySearch-optimized version of the question produced by QueryRewriter
sub_queriesList of decomposed sub-queries from SubQueryGenerator
retrieved_contextDeduplicated list of passages returned by WeaviateRetriever
answerConcise answer generated by dspy.ChainOfThought
reasoningExplanation of how the answer was derived across multiple hops

Metadata Schema

The MetadataExtractor parses each query against the following JSON schema to produce Weaviate filter values:
FieldTypeDescription
titlestringThe main title or name of the subject
categorystringPrimary category or type of content
metadata_schema:
  properties:
    title:
      type: "string"
      description: "The main title or name of the subject"
    category:
      type: "string"
      description: "Primary category or type of content"
For multi-hop questions, the SubQueryGenerator is especially impactful: it decomposes the original question into independent sub-queries, each of which can retrieve a different supporting document. The MetadataExtractor then filters each sub-query retrieval independently by title and category.

Models

RoleModel
Answer LLMgroq/qwen3-32b
Extractor LLMgroq/llama-3.3-70b-versatile
EmbeddingQwen/Qwen3-Embedding-0.6B
Evaluator LLMgroq/qwen3-32b

Scripts

ScriptDescription
hotpotqa_indexing.pyLoad dataset from HuggingFace, extract metadata, embed, and store in Weaviate
hotpotqa_rag_module.pyPipeline class definition — imported by optimizer and evaluation scripts
hotpotqa_rag_mipro.pyRun MIPROv2 optimization
hotpotqa_rag_copro.pyRun COPRO optimization
hotpotqa_rag_bootstrap_few_shot.pyRun BootstrapFewShot optimization
hotpotqa_rag_simba.pyRun SIMBA optimization
hotpotqa_rag_gepa.pyRun GEPA optimization
hotpotqa_rag_evaluation.pyEvaluate the optimized pipeline with DeepEval metrics

Configuration Files

FileDescription
hotpotqa_indexing_config.ymlIndexing parameters: embedding model, metadata schema, collection name
hotpotqa_rag_mipro_config.ymlMIPROv2 parameters: max_bootstrapped_demos, max_labeled_demos, auto
hotpotqa_rag_copro_config.ymlCOPRO parameters: breadth, depth, init_temperature
hotpotqa_rag_bootstrap_few_shot_config.ymlBootstrapFewShot parameters: max_bootstrapped_demos, max_rounds
hotpotqa_rag_simba_config.ymlSIMBA parameters: bsize, num_candidates, max_steps, max_demos
hotpotqa_rag_gepa_config.ymlGEPA parameters: max_full_evals, reflection_minibatch_size, candidate_selection_strategy
hotpotqa_rag_evaluation_config.ymlEvaluation settings and DeepEval metric thresholds

MIPROv2 Configuration

answer_llm:
  model: "groq/qwen3-32b"
  api_key_env: "GROQ_API_KEY"

extractor_llm:
  model: "groq/llama-3.3-70b-versatile"
  api_key_env: "GROQ_API_KEY"

embedding:
  model: "Qwen/Qwen3-Embedding-0.6B"
  tokenizer_kwargs:
    padding_side: "left"

weaviate:
  url_env: "WEAVIATE_URL"
  api_key_env: "WEAVIATE_API_KEY"
  collection_name: "HotpotQA"
  top_k: 5

dataset:
  name: "hotpotqa/hotpot_qa"
  subset_name: "distractor"
  split: "train"

optimizer:
  max_bootstrapped_demos: 3
  max_labeled_demos: 16
  auto: "medium"

Running the Pipeline

All scripts must be run from the hotpotqa/ directory so that relative config file paths resolve correctly.
# Index documents into Weaviate
cd src/dspy_opt/hotpotqa
python hotpotqa_indexing.py

# Run MIPROv2 optimization
cd src/dspy_opt/hotpotqa
python hotpotqa_rag_mipro.py

# Run SIMBA optimization
cd src/dspy_opt/hotpotqa
python hotpotqa_rag_simba.py

# Run GEPA optimization
cd src/dspy_opt/hotpotqa
python hotpotqa_rag_gepa.py

# Evaluate the optimized pipeline
cd src/dspy_opt/hotpotqa
python hotpotqa_rag_evaluation.py

Programmatic Usage

import dspy
from sentence_transformers import SentenceTransformer

from dspy_opt.hotpotqa.hotpotqa_rag_module import HotpotQARAG
from dspy_opt.utils.metadata_extractor import MetadataExtractor
from dspy_opt.utils.query_rewriter import QueryRewriter
from dspy_opt.utils.sub_query_generator import SubQueryGenerator
from dspy_opt.utils.weaviate_retriever import WeaviateRetriever

# Configure LLMs
answer_lm = dspy.LM("groq/qwen3-32b", api_key="your-groq-api-key")
extractor_lm = dspy.LM("groq/llama-3.3-70b-versatile", api_key="your-groq-api-key")
dspy.configure(lm=answer_lm)

# Initialize components
query_rewriter = QueryRewriter()
sub_query_generator = SubQueryGenerator()
metadata_extractor = MetadataExtractor(extractor_llm=extractor_lm)
embedding_model = SentenceTransformer("Qwen/Qwen3-Embedding-0.6B")

retriever = WeaviateRetriever(
    weaviate_url="your-weaviate-url",
    weaviate_api_key="your-weaviate-api-key",
    collection_name="HotpotQA",
    top_k=5,
)

metadata_schema = {
    "properties": {
        "title": {"type": "string", "description": "The main title or name of the subject"},
        "category": {"type": "string", "description": "Primary category or type of content"},
    }
}

# Build and run the pipeline
pipeline = HotpotQARAG(
    query_rewriter=query_rewriter,
    sub_query_generator=sub_query_generator,
    metadata_extractor=metadata_extractor,
    metadata_schema=metadata_schema,
    weaviate_retriever=retriever,
    embedding_model=embedding_model,
    top_k=5,
)

result = pipeline("What nationality was the director of the film that won the 1972 Academy Award for Best Picture?")
print(result.answer)
print(result.reasoning)

Build docs developers (and LLMs) love