DSPy Fundamentals
🎯 Trigger Conditions
Use when asked about DSPy basics, signatures, modules, or how to structure DSPy programs.
📚 Prerequisites
dspypackage installed- Python 3.10+
🛠️ Core Concepts
1. Signatures
Signatures define the input/output structure of DSPy modules.
import dspy
# Simple signature
class GenerateAnswer(dspy.Signature):
"""Answer questions with short factoid answers."""
question = dspy.InputField()
answer = dspy.OutputField()
# Complex signature with multiple fields
class MultiHopQA(dspy.Signature):
"""Answer multi-hop questions."""
context = dspy.InputField(desc="Relevant context")
question = dspy.InputField()
answer = dspy.OutputField()
reasoning = dspy.OutputField(desc="Step-by-step reasoning")
2. Modules
Modules are composable units that transform input to output.
# Basic module
predictor = dspy.Predict(GenerateAnswer)
response = predictor(question="What is the capital of France?")
# Chained modules
class QAChain(dspy.Module):
def __init__(self):
self.retrieve = dspy.Retrieve(k=3)
self.answer = dspy.Predict(GenerateAnswer)
def forward(self, question):
context = self.retrieve(question).passages
return self.answer(question=question, context=context)
3. Programs
Programs are composed of modules and define the full workflow.
class MultiHopQA(dspy.Module):
def __init__(self, passages_per_hop=3):
self.retrieve = dspy.Retrieve(k=passages_per_hop)
self.generate_question = dspy.Predict(GenerateQuestion)
self.generate_answer = dspy.Predict(GenerateAnswer)
def forward(self, question):
context = []
for _ in range(2): # 2 hops
passages = self.retrieve(question).passages
context = dspy.PythonList()(passages + context)
question = self.generate_question(context=context, question=question)
return self.generate_answer(context=context, question=question)
⚠️ Pitfalls
- Signatures are strict: Field names must match exactly
- Modules are stateless: Don't rely on internal state
- Chaining matters: Order of modules affects output quality
- Context window: Be mindful of context length limits