dspy-signature-designer

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

DSPy Signature Designer

DSPy Signature 设计器

Goal

目标

Design clear, type-safe signatures that define what your DSPy modules should do.
设计清晰、类型安全的signature,定义你的DSPy模块应实现的功能。

When to Use

适用场景

  • Defining new DSPy modules
  • Need structured/validated outputs
  • Complex input/output relationships
  • Multi-field responses
  • 定义新的DSPy模块
  • 需要结构化/经过验证的输出
  • 复杂的输入/输出关系
  • 多字段响应

Inputs

输入

InputTypeDescription
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
输入项类型描述
task_description
str
模块应实现的功能
input_fields
list
必填输入项
output_fields
list
预期输出项
type_constraints
dict
字段的类型提示

Outputs

输出

OutputTypeDescription
signature
dspy.Signature
Type-safe signature class
输出项类型描述
signature
dspy.Signature
类型安全的signature类

Workflow

工作流程

Inline Signatures (Simple)

内联Signature(简单场景)

python
import dspy
python
import dspy

Basic

Basic

qa = dspy.Predict("question -> answer")
qa = dspy.Predict("question -> answer")

With types

With types

classify = dspy.Predict("sentence -> sentiment: bool")
classify = dspy.Predict("sentence -> sentiment: bool")

Multiple fields

Multiple fields

rag = dspy.ChainOfThought("context: list[str], question: str -> answer: str")
undefined
rag = dspy.ChainOfThought("context: list[str], question: str -> answer: str")
undefined

Class-based Signatures (Complex)

基于类的Signature(复杂场景)

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")
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
python
from typing import Literal, Optional, List
from pydantic import BaseModel

Basic types

Basic types

field: str = dspy.InputField() field: int = dspy.OutputField() field: float = dspy.OutputField() field: bool = dspy.OutputField()
field: str = dspy.InputField() field: int = dspy.OutputField() field: float = dspy.OutputField() field: bool = dspy.OutputField()

Collections

Collections

field: list[str] = dspy.InputField() field: List[int] = dspy.OutputField()
field: list[str] = dspy.InputField() field: List[int] = dspy.OutputField()

Optional

Optional

field: Optional[str] = dspy.OutputField()
field: Optional[str] = dspy.OutputField()

Constrained

Constrained

field: Literal['a', 'b', 'c'] = dspy.OutputField()
field: Literal['a', 'b', 'c'] = dspy.OutputField()

Pydantic models

Pydantic models

class Person(BaseModel): name: str age: int
field: Person = dspy.OutputField()
undefined
class Person(BaseModel): name: str age: int
field: Person = dspy.OutputField()
undefined

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")
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()
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")
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

带置信度的RAG

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)"
    )
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

带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"
            )
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

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}")
undefined
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}")
undefined

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
  1. 描述性文档字符串 - 类的文档字符串将作为任务指令
  2. 字段描述 - 使用
    desc
    参数引导模型
  3. 约束输出 - 对分类输出使用
    Literal
  4. 默认值 - 为可选输入提供合理的默认值
  5. 类型验证 - Pydantic模型确保输出结构化

Advanced Field Options

高级字段选项

python
undefined
python
undefined

Constraints (available in 3.1.2+)

Constraints (available in 3.1.2+)

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"
)
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

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:")
undefined
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:")
undefined

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
  • 复杂嵌套类型需要使用Pydantic模型
  • 部分大语言模型难以处理严格的类型约束
  • 字段描述和约束会增加提示词长度
  • 默认值仅适用于InputField,不适用于OutputField

Official Documentation

官方文档