English
Week 4: Production
04. Advanced (DSPy)

04. Advanced: DSPy Prompt Optimization

Overview

DSPy stands for "Declarative Self-improving Language Programs". Instead of manually tweaking prompt strings, you define:

  1. Signature: Input/Output types
  2. Module: The logic flow
  3. Optimizer: A metric to maximize (e.g., faithfulness)

DSPy then "compiles" your program, automatically finding the best few-shot examples and instructions to maximize your metric. This is the future of prompt engineering.

Key Concepts

ConceptDescription
SignatureDefines input/output types for a task
ModuleEncapsulates LLM calls and logic
OptimizerAutomatically improves prompts
TeleprompterDSPy's optimization algorithm

DSPy Signatures

import dspy
 
# Simple signature
class BasicQA(dspy.Signature):
    """Answer questions with short factual answers."""
    question = dspy.InputField()
    answer = dspy.OutputField(desc="often between 1 and 5 words")
 
# Complex signature with chain-of-thought
class ReasonedQA(dspy.Signature):
    """Answer questions with reasoning."""
    question = dspy.InputField()
    reasoning = dspy.OutputField(desc="step-by-step reasoning")
    answer = dspy.OutputField()

DSPy Modules

class RAGModule(dspy.Module):
    def __init__(self, num_passages=3):
        super().__init__()
        self.retrieve = dspy.Retrieve(k=num_passages)
        self.generate = dspy.ChainOfThought(ReasonedQA)
 
    def forward(self, question):
        # Retrieve relevant passages
        passages = self.retrieve(question).passages
 
        # Generate answer with retrieved context
        context = "\n".join(passages)
        return self.generate(question=question, context=context)

Optimization with Teleprompters

from dspy.teleprompt import BootstrapFewShot
 
# Define a metric
def accuracy_metric(example, pred, trace=None):
    return example.answer.lower() == pred.answer.lower()
 
# Create optimizer
teleprompter = BootstrapFewShot(
    metric=accuracy_metric,
    max_bootstrapped_demos=4,
    max_labeled_demos=16
)
 
# Compile (optimize) the module
optimized_rag = teleprompter.compile(
    RAGModule(),
    trainset=train_examples
)

Why DSPy?

Automatic Optimization: DSPy finds optimal prompts and examples without manual tuning

Manual PromptingDSPy
Trial and errorSystematic optimization
Intuition-basedMetric-driven
Hard to reproduceReproducible
Brittle to changesSelf-adapting

DSPy vs Traditional Prompting

# Traditional approach
prompt = """You are a helpful assistant. Answer the question accurately.
Question: {question}
Answer:"""
 
# DSPy approach
class QA(dspy.Signature):
    question = dspy.InputField()
    answer = dspy.OutputField()
 
qa_module = dspy.Predict(QA)
# DSPy optimizes the actual prompt automatically!

Hands-on Practice

Define Signatures

Create input/output specifications

Build Modules

Combine retrieval and generation

Set Up Metrics

Define what "good" looks like

Run Optimization

Let DSPy find optimal prompts

References

Academic Papers