RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /Advanced Prompt Engineering
  6. /Ch. 8
Advanced Prompt Engineering

08. DSPy Signatures

Chapter 8 of 18 · 20 min
KEY INSIGHT

DSPy signatures declare contracts between inputs and outputs through typed field definitions, separating behavioral specification from implementation details.

A DSPy signature specifies what fields a module should treat as input and what fields it should produce as output. This is the declarative contract between the user and the system. Signatures are not prompts—they describe behavior, not implementation.

The signature format uses field annotations:

class SummarizeDocument(dspy.Signature):
    """Summarize documents concisely for technical readers."""
    document = dspy.InputField(desc="The full document text to summarize")
    summary = dspy.OutputField(desc="3-5 sentence summary focusing on key findings")
    confidence = dspy.OutputField(desc="Confidence score 0.0 to 1.0")

The desc argument provides hints to the compiler about what the content should be. These hints are extracted and used when generating prompts. Well-written descriptions improve compilation outcomes.

Signature inheritance allows extension:

# Base signature
class AnalyzeText(dspy.Signature):
    text = dspy.InputField()
    analysis = dspy.OutputField()

# Extended signature adds another capability
class AnalyzeTextWithSentiment(AnalyzeText):
    sentiment = dspy.OutputField()

# Extended signature narrows scope
class AnalyzeTextBrief(AnalyzeText):
    analysis = dspy.OutputField()  # Same output field
    # But compiler treats brief context differently based on context hints

The output of a signature is a namedtuple-like object with attributes matching the output field names. Accessing result.analysis returns the extracted value. This uniform structure enables easy composition: the output from one module becomes inputs to another.

# Example: Sentiment-aware topic extraction
class ExtractTopic(dspy.Signature):
    """Identify the main topic and subject of the input."""
    text = dspy.InputField()
    topic = dspy.OutputField()
    topic_confidence = dspy.OutputField()

class AssessTopicValence(dspy.Signature):
    """Determine sentiment toward the topic."""
    text = dspy.InputField()
    topic = dspy.InputField()
    valence = dspy.OutputField()  # positive, negative, neutral
    valence_explanation = dspy.OutputField()

# Compose: output of first feeds into second
topic_extractor = dspy.Predict(ExtractTopic)
valence_assessor = dspy.Predict(AssessTopicValence)

def full_analysis(text: str):
    # Module 1: extract topic
    topic_result = topic_extractor(text=text)
    
    # Module 2: assess sentiment toward that topic
    valence_result = valence_assessor(
        text=text,
        topic=topic_result.topic
    )
    
    return {
        'topic': topic_result.topic,
        'topic_confidence': topic_result.topic_confidence,
        'valence': valence_result.valence,
        'explanation': valence_result.valence_explanation
    }

news_article = """
The newly announced QuantumChip processor achieves exceptional 
energy efficiency according to benchmarks released today. The chip 
uses 40% less power than previous generation while delivering 
twice the computational throughput.
"""

result = full_analysis(news_article)
print(result)

A common misunderstanding: when extending a signature, the base specification doesn't carry over. class Extended(Base) creates an independent signature. The fields are copied, not inherited. This means extended signatures won't automatically call base implementations unless explicitly composed.

The signature compilation process extracts all desc values and assembles them into prompt context. If multiple modules use similar field names, the descriptions guide the model toward the right interpretation. A field named summary in a summarization context means something different than summary in a financial analysis context—DSPy disambiguates through descriptions.

EXERCISE

Identify 3 different tasks that share field names but require different content interpretations. Write explicit descriptions for each that disambiguate the interpretation. Verify that a model using these descriptions produces different outputs for the same field name across contexts.

← Chapter 7
DSPy Introduction
Chapter 9 →
DSPy Optimizers