dspy-signature-designer — Claude Code skill: typed DSPy signatures
Turns a task description into a typed DSPy signature with declared inputs and outputs. Useful when model replies must fit a fixed schema.
npx skills add OmidZamani/dspy-skills --skill dspy-signature-designer -a claude-codeWhat dspy-signature-designer does
The skill walks from a task to a dspy.Signature class: it lays out fields, assigns types and writes descriptions. Examples cover inline forms such as "question -> answer" and class-based ones built from dspy.InputField and dspy.OutputField. A type reference sits alongside: primitives, collections, Optional, Literal, and Pydantic models.
Sample signatures handle summarisation, entity extraction, multi-label tagging, and grounded answers that carry a confidence label. There is also a full dspy.Module with ChainOfThought, a score clamp, and a fallback dspy.Prediction when the call throws.
DSPy 3.2.1 is the stated target, and that matters: field constraints like min_length, gt and multiple_of arrived in 3.2.1, so on an older release those examples will not run. The skill only reads, writes, globs and greps files. It never executes your code.
What it helps with
- declare typed inputs and outputs for a DSPy module
- get structured model output shaped by a Pydantic schema
- restrict a categorical output with
Literal - add score range checks and a fallback path to a module
- tag one text with several categories at once
Example prompts for the agent
- Write a DSPy signature for sentiment classification with a confidence field
- Build a
dspy.Signatureclass for entity extraction using a Pydantic model - Create a grounded-answer signature with
high,medium,lowconfidence
How to install dspy-signature-designer
1Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-signature-designer -a claude-code2Manually: put the files in place
~/.claude/skills/dspy-signature-designer/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/dspy-signature-designer/
1Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-signature-designer -a codex2Manually: put the files in place
.agents/skills/dspy-signature-designer/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-signature-designer -a cursor2Manually: put the files in place
.cursor/skills/dspy-signature-designer/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install OmidZamani/dspy-skills dspy-signature-designer2Manually: put the files in place
.github/skills/dspy-signature-designer/SKILL.md1Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-signature-designer -a gemini-cli2Platform CLI
gemini skills install https://github.com/OmidZamani/dspy-skills --path skills/dspy-signature-designerManually: put the files in place
.devin/skills/dspy-signature-designer/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-signature-designer -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about dspy-signature-designer
How do I install dspy-signature-designer in Claude Code?
Run npx skills add OmidZamani/dspy-skills --skill dspy-signature-designer -a claude-code. The skill file lands at ~/.claude/skills/dspy-signature-designer/SKILL.md.
What does dspy-signature-designer do?
It helps you design DSPy signatures: input and output fields, their types, descriptions and constraints. The result is a dspy.Signature class you can pass to a module.
Which DSPy version does it need?
The skill targets DSPy 3.2.1. Field constraints such as min_length, gt, lt, ge, le and multiple_of are available from 3.2.1 onward.
Source text
SKILL.md · MIT
---
name: dspy-signature-designer
version: "1.0.0"
dspy-compatibility: "3.2.1"
tags: ["reasoning"]
requires-extras: []
description: Use for DSPy signatures, InputField, OutputField, typed inputs and outputs, signature classes, and Pydantic-style structured schemas.
allowed-tools:
- Read
- Write
- Glob
- Grep
---
# DSPy Signature Designer
## Goal
Design clear, type-safe signatures that define what your DSPy modules should do.
## When to Use
- Defining new DSPy modules
- Need structured/validated outputs
- Complex input/output relationships
- Multi-field responses
## Inputs
| Input | Type | Description |
|-------|------|-------------|
| `task_description` | `str` | What the module should do |
| `input_fields` | `list` | Required inputs |
| `output_fields` | `list` | Expected outputs |
| `type_constraints` | `dict` | Type hints for fields |
## Outputs
| Output | Type | Description |
|--------|------|-------------|
| `signature` | `dspy.Signature` | Type-safe signature class |
## Workflow
### Inline Signatures (Simple)
```python
import dspy
# Basic
qa = dspy.Predict("question -> answer")
# With types
classify = dspy.Predict("sentence -> sentiment: bool")
# Multiple fields
rag = dspy.ChainOfThought("context: list[str], question: str -> answer: str")
```
### Class-based Signatures (Complex)
```python
from typing import Literal, Optional
import dspy
class EmotionClassifier(dspy.Signature):
"""Classify the emotion expressed in the text."""
text: str = dspy.InputField(desc="The text to analyze")
emotion: Literal['joy', 'sadness', 'anger', 'fear', 'surprise'] = dspy.OutputField()
confidence: float = dspy.OutputField(desc="Confidence score 0-1")
```
## Type Hints Reference
```python
from typing import Literal, Optional, List
from pydantic import BaseModel
# Basic types
field: str = dspy.InputField()
field: int = dspy.OutputField()
field: float = dspy.OutputField()
field: bool = dspy.OutputField()
# Collections
field: list[str] = dspy.InputField()
field: List[int] = dspy.OutputField()
# Optional
field: Optional[str] = dspy.OutputField()
# Constrained
field: Literal['a', 'b', 'c'] = dspy.OutputField()
# Pydantic models
class Person(BaseModel):
name: str
age: int
field: Person = dspy.OutputField()
```
## Production Examples
### Summarization
```python
class Summarize(dspy.Signature):
"""Summarize the document into key points."""
document: str = dspy.InputField(desc="Full document text")
max_points: int = dspy.InputField(desc="Maximum bullet points", default=5)
summary: list[str] = dspy.OutputField(desc="Key points as bullet list")
word_count: int = dspy.OutputField(desc="Total words in summary")
```
### Entity Extraction
```python
from pydantic import BaseModel
from typing import List
class Entity(BaseModel):
text: str
type: str
start: int
end: int
class ExtractEntities(dspy.Signature):
"""Extract named entities from text."""
text: str = dspy.InputField()
entity_types: list[str] = dspy.InputField(
desc="Types to extract: PERSON, ORG, LOC, DATE",
default=["PERSON", "ORG", "LOC"]
)
entities: List[Entity] = dspy.OutputField()
```
### Multi-Label Classification
```python
class MultiLabelClassify(dspy.Signature):
"""Classify text into multiple categories."""
text: str = dspy.InputField()
categories: list[str] = dspy.OutputField(
desc="Applicable categories from: tech, business, sports, entertainment"
)
primary_category: str = dspy.OutputField(desc="Most relevant category")
reasoning: str = dspy.OutputField(desc="Explanation for classification")
```
### RAG with Confidence
```python
class GroundedAnswer(dspy.Signature):
"""Answer questions using retrieved context with confidence."""
context: list[str] = dspy.InputField(desc="Retrieved passages")
question: str = dspy.InputField()
answer: str = dspy.OutputField(desc="Factual answer from context")
confidence: Literal['high', 'medium', 'low'] = dspy.OutputField(
desc="Confidence based on context support"
)
source_passage: int = dspy.OutputField(
desc="Index of most relevant passage (0-based)"
)
```
### Complete Module with Signature
```python
import dspy
from typing import Literal, Optional
import logging
logger = logging.getLogger(__name__)
class AnalyzeSentiment(dspy.Signature):
"""Analyze sentiment with detailed breakdown."""
text: str = dspy.InputField(desc="Text to analyze")
sentiment: Literal['positive', 'negative', 'neutral', 'mixed'] = dspy.OutputField()
score: float = dspy.OutputField(desc="Sentiment score from -1 to 1")
aspects: list[str] = dspy.OutputField(desc="Key aspects mentioned")
reasoning: str = dspy.OutputField(desc="Explanation of sentiment")
class SentimentAnalyzer(dspy.Module):
def __init__(self):
self.analyze = dspy.ChainOfThought(AnalyzeSentiment)
def forward(self, text: str):
try:
result = self.analyze(text=text)
# Validate score range
if hasattr(result, 'score'):
result.score = max(-1, min(1, float(result.score)))
return result
except Exception as e:
logger.error(f"Analysis failed: {e}")
return dspy.Prediction(
sentiment='neutral',
score=0.0,
aspects=[],
reasoning="Analysis failed"
)
# Usage
analyzer = SentimentAnalyzer()
result = analyzer(text="The product quality is great but shipping was slow.")
print(f"Sentiment: {result.sentiment} ({result.score})")
print(f"Aspects: {result.aspects}")
```
## Best Practices
1. **Descriptive docstrings** - The class docstring becomes the task instruction
2. **Field descriptions** - Guide the model with `desc` parameter
3. **Constrain outputs** - Use `Literal` for categorical outputs
4. **Default values** - Provide sensible defaults for optional inputs
5. **Validate types** - Pydantic models ensure structured output
## Advanced Field Options
```python
# Constraints (available in 3.2.1+)
class ConstrainedSignature(dspy.Signature):
"""Example with validation constraints."""
text: str = dspy.InputField(
min_length=5,
max_length=100,
desc="Input text between 5-100 chars"
)
number: int = dspy.InputField(
gt=0,
lt=10,
desc="Number between 0 and 10"
)
score: float = dspy.OutputField(
ge=0.0,
le=1.0,
desc="Score between 0 and 1"
)
count: int = dspy.OutputField(
multiple_of=2,
desc="Even number count"
)
# Prefix and format
class FormattedSignature(dspy.Signature):
"""Example with custom prefix and format."""
goal: str = dspy.InputField(prefix="Goal:")
text: str = dspy.InputField(format=lambda x: x.upper())
action: str = dspy.OutputField(prefix="Action:")
```
## Limitations
- Complex nested types require Pydantic models
- Some LLMs struggle with strict type constraints
- Field descriptions and constraints add to prompt length
- Default values only work for InputField, not OutputField
## Official Documentation
- **DSPy Documentation**: https://dspy.ai/
- **DSPy GitHub**: https://github.com/stanfordnlp/dspy
- **Signatures API**: https://dspy.ai/api/signatures/
- **Signatures Guide**: https://dspy.ai/learn/programming/signatures/
© OmidZamani · MIT · OmidZamani/dspy-skills