Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
lebsral avatar

Dspy Signatures

  • 6 installs
  • 11 repo stars
  • Updated June 28, 2026
  • lebsral/dspy-programming-not-prompting-lms-skills

Helps with ai & agent building tasks.

About

dspy-signatures is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.

  • dspy-signatures
  • AI & Agent Building
  • AI-coding skill

Dspy Signatures by the numbers

  • 6 all-time installs (skills.sh)
  • Ranked #12,779 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/lebsral/dspy-programming-not-prompting-lms-skills --skill dspy-signatures

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs6
repo stars11
Last updatedJune 28, 2026
Repositorylebsral/dspy-programming-not-prompting-lms-skills

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

DSPy Signatures

Guide the user through defining DSPy Signatures — typed declarations of what goes into and comes out of an LM call.

Step 1: What kind of signature?

Ask the user before diving in:

1. How complex is your I/O? One input, one output (use inline)? Multiple fields, type constraints, or nested objects (use class-based)? 2. Do you need structured output? If the output maps to a database model or API response, you likely want a Pydantic model as the output type. 3. Are outputs constrained? If you need categories, booleans, or numeric ranges, you need type annotations.

Then jump to the relevant section below.

What is a Signature

A Signature declares the input/output contract for an LM call -- field names, types, and descriptions. DSPy compiles it into an optimized prompt automatically. You define the I/O spec; DSPy handles the prompting.

When to use each style

StyleWhen to useExample
InlineQuick one-liner, 1-2 inputs, 1 output, string types"question -> answer"
Class-basedMultiple fields, type constraints, descriptions, Pydantic outputsclass Classify(dspy.Signature)

Rule of thumb: Start inline for prototyping. Switch to class-based when you need type constraints, field descriptions, or more than one output.

Inline signatures

Inline signatures are strings with -> separating inputs from outputs: "question -> answer", "text -> label: bool". Supported type suffixes: str (default), int, float, bool, list[str].

Class-based signatures

Class-based signatures give you type constraints, field descriptions, and a docstring that acts as the task instruction. Use them when you need more than a one-liner.

Field options

Both InputField and OutputField accept these parameters:

class Example(dspy.Signature):
    """Demonstrate field options."""
    # desc: describes the field to the LM (shows up in the prompt)
    text: str = dspy.InputField(desc="The document to analyze")

    # type constraint via inline annotation (preferred)
    category: Literal["news", "blog", "research"] = dspy.OutputField(desc="The document category")
  • `desc` — a natural language description. Helps the LM understand what the field means. Use this when the field name alone is ambiguous.
  • `type_` — sets the type constraint on the field. Still supported, but prefer an inline Python annotation (category: Literal[...] = dspy.OutputField(...)).

Pydantic models as output types

For complex or nested structured output, use a Pydantic BaseModel as the output type. DSPy handles serialization and validation automatically.

import dspy
from pydantic import BaseModel, Field
from typing import Optional

lm = dspy.LM("openai/gpt-4o-mini")  # or "anthropic/claude-sonnet-4-5-20250929", etc.
dspy.configure(lm=lm)

class LineItem(BaseModel):
    description: str
    quantity: int
    unit_price: float

class Invoice(BaseModel):
    vendor: str
    date: str = Field(description="Invoice date in YYYY-MM-DD format")
    total: float
    items: list[LineItem]
    notes: Optional[str] = None

class ParseInvoice(dspy.Signature):
    """Extract structured invoice data from the raw text."""
    text: str = dspy.InputField(desc="Raw invoice text")
    invoice: Invoice = dspy.OutputField(desc="Parsed invoice data")

parser = dspy.ChainOfThought(ParseInvoice)
result = parser(text="Invoice from Acme Corp, Jan 15 2025. 2x Widget ($10 each), 1x Gadget ($25). Total: $45.")
print(result.invoice.vendor)       # Acme Corp
print(result.invoice.items[0])     # LineItem(description='Widget', quantity=2, unit_price=10.0)
print(result.invoice.total)        # 45.0

When to use Pydantic outputs:

  • You need nested objects (addresses, line items, etc.)
  • You want automatic validation (Pydantic enforces types)
  • The output maps to a database model or API response
  • You need Optional fields for data that may not be present

Common patterns

Docstrings as task instructions

The docstring is the most important part of a class-based signature. DSPy uses it as the primary instruction to the LM.

# Vague — the LM doesn't know what "classify" means in your context
class Bad(dspy.Signature):
    """Classify the text."""
    text: str = dspy.InputField()
    label: str = dspy.OutputField()

# Clear — tells the LM exactly what to do
class Good(dspy.Signature):
    """Classify the customer support message into a department for routing.
    Consider the primary intent, not just keywords."""
    message: str = dspy.InputField(desc="Customer support message")
    department: Literal["billing", "technical", "account", "general"] = dspy.OutputField()

Advanced: dynamic signatures

For runtime customization without defining new classes:

# Override instructions at call time (inline signatures)
predict = dspy.Predict("question -> answer", instructions="Answer in exactly one sentence.")

# Programmatically modify a class-based signature
MySignature = MySignature.with_instructions("New instructions for this run")

# Add/remove fields dynamically
MySignature = MySignature.append("confidence", dspy.OutputField(), type_=float)
MySignature = MySignature.delete("unused_field")

DSPy also supports special input types: dspy.Image for image inputs and dspy.History for conversation history.

When NOT to use class-based signatures

  • Simple extraction or Q&A — if "question -> answer" captures your task, an inline signature is clearer and shorter. Do not over-engineer with a class when a string works.
  • Prototyping — start inline, switch to class-based only when you need type constraints, descriptions, or Pydantic outputs.
  • Too many output fields — if you need more than 4-5 outputs, the LM quality degrades. Split into multiple calls with simpler signatures instead.

Gotchas

1. Field names ARE the prompt -- text -> summary works better than input -> output because DSPy uses field names directly in the generated prompt. Choose descriptive names. 2. Literal types need `tuple()` wrapping for dynamic values -- use Literal[tuple(["a", "b"])] not Literal[["a", "b"]] when constructing from a list at runtime. 3. Keep signatures small -- more than 4-5 output fields degrades quality. Split into multiple calls instead. 4. The docstring on a Signature class becomes the task instruction -- write it carefully, as a clear directive. A vague docstring like "Classify the text" performs much worse than "Classify the customer support message into a department for routing." 5. Field `desc` values are NOT optimized -- DSPy optimizers (GEPA, MIPROv2, COPRO) tune the Signature docstring and/or few-shot demos, but InputField(desc=...), OutputField(desc=...), and Pydantic Field(description=...) values are fixed. If your structured output task relies heavily on field descriptions for guidance, see /dspy-gepa for a workaround that flattens field descriptions into the instruction for optimization.

Additional resources

Cross-references

Install any skill: npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill <name>
  • Using signatures with modules — see /dspy-predict (Predict), /dspy-chain-of-thought (ChainOfThought), /dspy-modules (custom modules)
  • Parsing structured data from text — see /ai-parsing-data
  • Classification and sorting — see /ai-sorting
  • Install `/ai-do` if you do not have it — it routes any AI problem to the right skill and is the fastest way to work: npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill ai-do

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.