Spaces:
Sleeping
A newer version of the Gradio SDK is available:
5.42.0
title: dspy-example
app_file: gradio_interface.py
sdk: gradio
sdk_version: 5.38.2
π¬ DSPy Director Bake-Off: A Beginner's Guide to DSPy Programming
Welcome to the DSPy Director Bake-Off! This project demonstrates core DSPy concepts through a fun, practical example: comparing how different movie directors would approach filming the same video idea.
π― What You'll Learn
This tutorial teaches you the fundamental concepts of DSPy (Declarative Self-improving Python) through hands-on examples:
- Signatures - Define input/output interfaces for LLM tasks
- Modules - Combine multiple signatures into complex workflows
- Structured Output - Use Pydantic models for reliable data extraction
- Async Processing - Handle multiple LLM calls efficiently
- Chain of Thought - Enable reasoning for complex decisions
π Quick Start
Prerequisites
- Python 3.8+
- An OpenRouter API key (free tier available)
Installation
Clone or download this project
Install dependencies:
pip install -r requirements.txt
Set up your API key: Create a
.env
file in the project directory:OPENROUTER_API_KEY=your_api_key_here
Run the demo:
python director_bake_off.py
Try the web interface:
python gradio_interface.py
Then open http://localhost:7860 in your browser.
π How It Works
The Director Bake-Off follows this workflow:
- User Input: You provide a video idea and list of directors
- AI Suggestion: DSPy suggests an additional director perfect for your idea
- Parallel Generation: Each director's unique interpretation is generated simultaneously
- Intelligent Ranking: An AI judge ranks all interpretations and explains the reasoning
- Beautiful Results: View the winner and detailed breakdowns
π Understanding the Code Structure
ποΈ Project Architecture
director_bake_off.py # Main DSPy implementation (heavily commented)
gradio_interface.py # Beautiful web interface
requirements.txt # Python dependencies
.env # Your API keys (create this)
README.md # This guide
π Code Walkthrough
The director_bake_off.py
file is organized into clear sections:
Section 1: LLM Setup
def setup_dspy_provider():
# Configure DSPy with your chosen LLM provider
# Supports OpenAI, Anthropic, OpenRouter, and more
Section 2: Data Structures
class DirectorCut(BaseModel):
# Pydantic model defining the structure of cinematic prompts
# Ensures consistent, validated output from the LLM
Section 3: DSPy Signatures
class FindDirector(dspy.Signature):
# Defines what inputs the LLM expects and what outputs it should produce
# Think of these as "contracts" between your code and the LLM
Section 4: DSPy Module
class DirectorBakeOff(dspy.Module):
# Combines multiple signatures into a complete workflow
# Orchestrates the entire director comparison process
Section 5: Main Functions
def run_bake_off(video_idea, directors):
# Easy-to-use interface that handles everything
# This is what external code calls to use our system
π DSPy Concepts Explained
What is DSPy?
DSPy is a framework for programming with Large Language Models (LLMs). Instead of writing prompts as strings, you define structured interfaces that make your LLM applications more reliable, maintainable, and powerful.
π₯ Key Concepts
1. Signatures - The Heart of DSPy
Signatures define the interface between your code and the LLM:
class GenerateDirectorCut(dspy.Signature):
"""Transform a video idea into a cinematic prompt in a director's style."""
# What goes IN to the LLM
video_idea = dspy.InputField(desc="A simple video concept")
director = dspy.InputField(desc="The director's name")
# What comes OUT of the LLM
director_cut: DirectorCut = dspy.OutputField(desc="Structured cinematic prompt")
Why this is powerful:
- Clear contracts between code and LLM
- Automatic prompt generation
- Type safety and validation
- Reusable across different models
2. Structured Output with Pydantic
Instead of parsing messy text, get structured data:
class DirectorCut(BaseModel):
director: str
subject_description: str
action_description: str
setting_description: str
# ... more fields
def assemble_prompt(self) -> str:
# Combine all parts into a complete prompt
return ", ".join([self.subject_description, self.action_description, ...])
Benefits:
- Guaranteed data format
- Automatic validation
- Easy to work with in code
- No more regex parsing!
3. Modules - Complex Workflows
Modules combine multiple signatures into sophisticated workflows:
class DirectorBakeOff(dspy.Module):
def __init__(self):
self.findDirector = dspy.Predict(FindDirector)
self.genDirectorCut = dspy.Predict(GenerateDirectorCut)
self.directorJudge = dspy.ChainOfThought(DirectorJudge)
async def aforward(self, video_idea, directors):
# Orchestrate multiple LLM calls
# 1. Find additional director
# 2. Generate interpretations (in parallel!)
# 3. Judge and rank results
4. Different Predictor Types
dspy.Predict
: Basic, fast predictionsdspy.ChainOfThought
: Enables step-by-step reasoningdspy.ReAct
: Combines reasoning with actionsdspy.ProgramOfThought
: For mathematical/logical problems
5. Async Processing
Handle multiple LLM calls efficiently:
# Instead of calling one by one (slow):
for director in directors:
result = self.genDirectorCut(video_idea=idea, director=director)
# Call them all at once (fast!):
results = await asyncio.gather(
*[self.genDirectorCut.acall(video_idea=idea, director=d) for d in directors]
)
π οΈ Building Your Own DSPy Applications
Step 1: Define Your Data Structure
Start with a Pydantic model for your expected output:
class MyOutput(BaseModel):
field1: str = Field(..., description="What this field should contain")
field2: int = Field(..., description="A number representing...")
# Add more fields as needed
Step 2: Create Signatures
Define the interface for each LLM task:
class MyTask(dspy.Signature):
"""Clear description of what this task should do."""
# Inputs
user_input = dspy.InputField(desc="What the user provides")
# Outputs
result: MyOutput = dspy.OutputField(desc="The structured result")
Step 3: Build a Module
Combine signatures into a workflow:
class MyModule(dspy.Module):
def __init__(self):
self.task = dspy.Predict(MyTask)
def forward(self, user_input):
return self.task(user_input=user_input)
Step 4: Configure and Run
# Configure DSPy with your LLM
dspy.configure(lm=dspy.LM("openrouter/model-name", api_key="your-key"))
# Use your module
module = MyModule()
result = module.forward("user input here")
print(result.result.field1) # Access structured output
π¨ Customization Ideas
Try modifying the Director Bake-Off to explore DSPy further:
π¬ Different Creative Domains
- Music Producer Bake-Off: Compare how different producers would approach a song
- Chef Bake-Off: See how famous chefs would prepare the same dish
- Architect Bake-Off: Compare building designs for the same space
π§ Technical Enhancements
- Add More Signatures: Include budget estimation, casting suggestions
- Different Predictors: Try
dspy.ReAct
for more complex reasoning - Optimization: Use DSPy's optimization features to improve performance
- Multiple Models: Compare results from different LLMs
π― New Applications
- Content Planning: Generate social media strategies
- Product Design: Compare design approaches for products
- Educational Content: Create lesson plans in different teaching styles
π Useful Resources
DSPy Documentation
LLM Providers
- OpenRouter - Access to many models through one API
- OpenAI - GPT models
- Anthropic - Claude models
Learning More
- Pydantic Documentation - For data validation
- Gradio Documentation - For building web interfaces
- Python Asyncio - For async programming
π€ Contributing
Found this helpful? Here are ways to contribute:
- Try it out and share your results
- Create variations for different domains
- Improve the documentation with your learnings
- Share examples of your own DSPy applications
π License
This project is open source and available under the MIT License.
π What's Next?
After mastering this example, you'll be ready to:
- Build production DSPy applications
- Optimize prompts automatically with DSPy's built-in tools
- Create complex multi-step reasoning systems
- Integrate DSPy into larger applications
Happy coding with DSPy! π
This tutorial was created to make DSPy accessible to beginners. The heavily commented code and step-by-step explanations should help you understand not just how to use DSPy, but why it's such a powerful framework for LLM programming.