Spaces:
Sleeping
Sleeping
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: | |
1. **Signatures** - Define input/output interfaces for LLM tasks | |
2. **Modules** - Combine multiple signatures into complex workflows | |
3. **Structured Output** - Use Pydantic models for reliable data extraction | |
4. **Async Processing** - Handle multiple LLM calls efficiently | |
5. **Chain of Thought** - Enable reasoning for complex decisions | |
## π Quick Start | |
### Prerequisites | |
- Python 3.8+ | |
- An OpenRouter API key (free tier available) | |
### Installation | |
1. **Clone or download this project** | |
2. **Install dependencies:** | |
```bash | |
pip install -r requirements.txt | |
``` | |
3. **Set up your API key:** | |
Create a `.env` file in the project directory: | |
``` | |
OPENROUTER_API_KEY=your_api_key_here | |
``` | |
4. **Run the demo:** | |
```bash | |
python director_bake_off.py | |
``` | |
5. **Try the web interface:** | |
```bash | |
python gradio_interface.py | |
``` | |
Then open http://localhost:7860 in your browser. | |
## π How It Works | |
The Director Bake-Off follows this workflow: | |
1. **User Input**: You provide a video idea and list of directors | |
2. **AI Suggestion**: DSPy suggests an additional director perfect for your idea | |
3. **Parallel Generation**: Each director's unique interpretation is generated simultaneously | |
4. **Intelligent Ranking**: An AI judge ranks all interpretations and explains the reasoning | |
5. **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** | |
```python | |
def setup_dspy_provider(): | |
# Configure DSPy with your chosen LLM provider | |
# Supports OpenAI, Anthropic, OpenRouter, and more | |
``` | |
#### **Section 2: Data Structures** | |
```python | |
class DirectorCut(BaseModel): | |
# Pydantic model defining the structure of cinematic prompts | |
# Ensures consistent, validated output from the LLM | |
``` | |
#### **Section 3: DSPy Signatures** | |
```python | |
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** | |
```python | |
class DirectorBakeOff(dspy.Module): | |
# Combines multiple signatures into a complete workflow | |
# Orchestrates the entire director comparison process | |
``` | |
#### **Section 5: Main Functions** | |
```python | |
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: | |
```python | |
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: | |
```python | |
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: | |
```python | |
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 predictions | |
- **`dspy.ChainOfThought`**: Enables step-by-step reasoning | |
- **`dspy.ReAct`**: Combines reasoning with actions | |
- **`dspy.ProgramOfThought`**: For mathematical/logical problems | |
#### 5. **Async Processing** | |
Handle multiple LLM calls efficiently: | |
```python | |
# 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: | |
```python | |
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: | |
```python | |
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: | |
```python | |
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 | |
```python | |
# 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 | |
- [Official DSPy Documentation](https://dspy-docs.vercel.app/) | |
- [DSPy GitHub Repository](https://github.com/stanfordnlp/dspy) | |
- [DSPy Paper](https://arxiv.org/abs/2310.03714) | |
### LLM Providers | |
- [OpenRouter](https://openrouter.ai/) - Access to many models through one API | |
- [OpenAI](https://platform.openai.com/) - GPT models | |
- [Anthropic](https://www.anthropic.com/) - Claude models | |
### Learning More | |
- [Pydantic Documentation](https://docs.pydantic.dev/) - For data validation | |
- [Gradio Documentation](https://gradio.app/docs/) - For building web interfaces | |
- [Python Asyncio](https://docs.python.org/3/library/asyncio.html) - For async programming | |
## π€ Contributing | |
Found this helpful? Here are ways to contribute: | |
1. **Try it out** and share your results | |
2. **Create variations** for different domains | |
3. **Improve the documentation** with your learnings | |
4. **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.* | |