smithery/OmidZamani

dspy-signature-designer

Use for DSPy signatures, InputField, OutputField, typed inputs and outputs, signature classes, and Pydantic-style structured schemas.

Installation

$ npx skills add smithery/OmidZamani --skill dspy-signature-designer

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/OmidZamani · top by installs.

npx skills add smithery/OmidZamani

Browse all from smithery/OmidZamani

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0
Allowed toolsRead, Write, Glob, Grep

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,531 B
  • docs SUMMARY.md 372 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

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)

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)

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

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

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

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

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

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

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

# 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