Chapter 2 ยท Section 3

Inline Signatures

The quick, string-based syntax for rapid prototyping and simple tasks.

~10 min read

โšก What Are Inline Signatures?

Inline signatures are a shorthand notation for defining simple signatures using a string format. They're perfect for quick experiments and simple tasks.

import dspy

# Inline signature: input -> output
qa = dspy.Predict("question -> answer")

# Use it immediately
result = qa(question="What is the capital of France?")
print(result.answer)  # Paris

๐Ÿ“ Basic Syntax

The inline signature syntax follows this pattern:

"input_field1, input_field2 -> output_field1, output_field2"
๐Ÿ“ฅ

Left Side: Inputs

Field names before the arrow are input fields. Separate multiple inputs with commas.

โžก๏ธ

Arrow: Separator

The -> arrow separates inputs from outputs.

๐Ÿ“ค

Right Side: Outputs

Field names after the arrow are output fields. The LM will generate these.

๐Ÿ’ก Examples

Single Input, Single Output

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

# Summarization
summarize = dspy.Predict("document -> summary")

# Translation
translate = dspy.Predict("text -> french_translation")

Multiple Inputs

# Context-based QA
qa = dspy.Predict("context, question -> answer")

# Call it with multiple inputs
result = qa(
    context="Paris is the capital of France.",
    question="What is the capital of France?"
)
print(result.answer)  # Paris

Multiple Outputs

# Sentiment with confidence
sentiment = dspy.Predict("text -> sentiment, confidence")

result = sentiment(text="I love this product!")
print(result.sentiment)    # positive
print(result.confidence)   # high

Multiple Inputs and Outputs

# Complex task
analyzer = dspy.Predict("text, task_type -> result, explanation, confidence")

result = analyzer(
    text="The stock market rose 5% today.",
    task_type="sentiment analysis"
)
print(result.result)       # positive
print(result.explanation)  # Market gains indicate positive sentiment
print(result.confidence)   # high

๐Ÿงฉ Using with Different Modules

Inline signatures work with all DSPy modules:

import dspy

# Basic prediction
predict = dspy.Predict("question -> answer")

# With chain-of-thought reasoning
cot = dspy.ChainOfThought("question -> answer")

# With multiple attempts and voting
ensemble = dspy.ChainOfThoughtWithHint("question, hint -> answer")

# ReAct agent with tools
agent = dspy.ReAct("goal -> plan, action")
๐Ÿ’ก

Pro tip: ChainOfThought automatically adds a rationale field to outputs, showing the model's reasoning!

# ChainOfThought adds reasoning
cot = dspy.ChainOfThought("question -> answer")
result = cot(question="What is 25 * 4?")

print(result.rationale)  # Let me calculate: 25 * 4 = 100
print(result.answer)     # 100

โœ… Field Naming Best Practices

โœ…

Use Descriptive Names

Field names become part of the prompt, so make them meaningful.

# Good: descriptive
"customer_review -> sentiment, key_points"

# Bad: vague
"x -> y, z"
โœ…

Use snake_case

Python convention for variable names works best.

# Good
"source_text, target_language -> translated_text"

# Avoid
"sourceText, targetLanguage -> translatedText"
โœ…

Be Specific About Output Format

Field names hint at expected format.

# Suggests yes/no answer
"text -> is_spam"

# Suggests a list
"article -> key_topics"

# Suggests a number
"product_reviews -> average_rating"

๐ŸŽฏ When to Use Inline Signatures

โœ… Great For

  • Quick prototyping and experiments
  • Simple, one-off tasks
  • Interactive exploration (notebooks)
  • Learning DSPy basics
  • Tasks with obvious field names

โŒ Consider Class-Based When

  • You need detailed field descriptions
  • Tasks require documentation
  • Building production systems
  • Fields need type hints
  • Reusing signatures across modules

๐Ÿ”ง Practical Examples

Building a Quick Chatbot

import dspy

# Simple chatbot signature
chat = dspy.Predict("user_message, chat_history -> assistant_response")

# Simulate a conversation
history = ""
while True:
    user_input = input("You: ")
    if user_input.lower() == "quit":
        break
    
    result = chat(user_message=user_input, chat_history=history)
    print(f"Bot: {result.assistant_response}")
    
    # Update history
    history += f"User: {user_input}\nAssistant: {result.assistant_response}\n"

Content Moderation

# Content moderation with reasoning
moderate = dspy.ChainOfThought("content -> is_appropriate, reason")

result = moderate(content="Check out this amazing product!")
print(f"Appropriate: {result.is_appropriate}")  # yes
print(f"Reason: {result.reason}")               # No harmful content detected

Data Extraction

# Extract structured data
extract = dspy.Predict("email_text -> sender_name, subject, action_items")

email = """
From: John Smith
Subject: Q4 Planning Meeting

Hi team,
Please review the attached slides before Friday.
We need to finalize the budget by next week.
"""

result = extract(email_text=email)
print(result.sender_name)    # John Smith
print(result.subject)        # Q4 Planning Meeting
print(result.action_items)   # Review slides, finalize budget

๐Ÿ“ Key Takeaways

Inline signatures use string syntax: "inputs -> outputs"

Separate multiple fields with commas

Field names matter - they become part of the prompt

Works with all modules: Predict, ChainOfThought, ReAct, etc.

Best for prototyping - use class-based for production