This skill should be used when working with DSPy.rb, a Ruby framework for building type-safe, composable LLM applications. Use this when implementing predictable AI features, creating LLM signatures and modules, configuring language model providers (OpenAI, Anthropic, Gemini, Ollama), building agent systems with tools, optimizing prompts, or testing LLM-powered functionality in Ruby applications.
Inherits all available tools
Additional assets for this skill
This skill inherits all available tools. When active, it can use any tool Claude has access to.
assets/config-template.rbassets/module-template.rbassets/signature-template.rbreferences/core-concepts.mdreferences/optimization.mdreferences/providers.mdDSPy.rb is a Ruby framework that enables developers to program LLMs, not prompt them. Instead of manually crafting prompts, define application requirements through type-safe, composable modules that can be tested, optimized, and version-controlled like regular code.
This skill provides comprehensive guidance on:
Create input/output contracts for LLM operations with runtime type checking.
When to use: Defining any LLM task, from simple classification to complex analysis.
Quick reference:
class EmailClassificationSignature < DSPy::Signature
description "Classify customer support emails"
input do
const :email_subject, String
const :email_body, String
end
output do
const :category, T.enum(["Technical", "Billing", "General"])
const :priority, T.enum(["Low", "Medium", "High"])
end
end
Templates: See assets/signature-template.rb for comprehensive examples including:
Best practices:
desc: parameterFull documentation: See references/core-concepts.md sections on Signatures and Type Safety.
Build reusable, chainable modules that encapsulate LLM operations.
When to use: Implementing any LLM-powered feature, especially complex multi-step workflows.
Quick reference:
class EmailProcessor < DSPy::Module
def initialize
super
@classifier = DSPy::Predict.new(EmailClassificationSignature)
end
def forward(email_subject:, email_body:)
@classifier.forward(
email_subject: email_subject,
email_body: email_body
)
end
end
Templates: See assets/module-template.rb for comprehensive examples including:
Module composition: Chain modules together to create complex workflows:
class Pipeline < DSPy::Module
def initialize
super
@step1 = Classifier.new
@step2 = Analyzer.new
@step3 = Responder.new
end
def forward(input)
result1 = @step1.forward(input)
result2 = @step2.forward(result1)
@step3.forward(result2)
end
end
Full documentation: See references/core-concepts.md sections on Modules and Module Composition.
Choose the right predictor for your task:
Predict: Basic LLM inference with type-safe inputs/outputs
predictor = DSPy::Predict.new(TaskSignature)
result = predictor.forward(input: "data")
ChainOfThought: Adds automatic reasoning for improved accuracy
predictor = DSPy::ChainOfThought.new(TaskSignature)
result = predictor.forward(input: "data")
# Returns: { reasoning: "...", output: "..." }
ReAct: Tool-using agents with iterative reasoning
predictor = DSPy::ReAct.new(
TaskSignature,
tools: [SearchTool.new, CalculatorTool.new],
max_iterations: 5
)
CodeAct: Dynamic code generation (requires dspy-code_act gem)
predictor = DSPy::CodeAct.new(TaskSignature)
result = predictor.forward(task: "Calculate factorial of 5")
When to use each:
Full documentation: See references/core-concepts.md section on Predictors.
Support for OpenAI, Anthropic Claude, Google Gemini, Ollama, and OpenRouter.
Quick configuration examples:
# OpenAI
DSPy.configure do |c|
c.lm = DSPy::LM.new('openai/gpt-4o-mini',
api_key: ENV['OPENAI_API_KEY'])
end
# Anthropic Claude
DSPy.configure do |c|
c.lm = DSPy::LM.new('anthropic/claude-3-5-sonnet-20241022',
api_key: ENV['ANTHROPIC_API_KEY'])
end
# Google Gemini
DSPy.configure do |c|
c.lm = DSPy::LM.new('gemini/gemini-1.5-pro',
api_key: ENV['GOOGLE_API_KEY'])
end
# Local Ollama (free, private)
DSPy.configure do |c|
c.lm = DSPy::LM.new('ollama/llama3.1')
end
Templates: See assets/config-template.rb for comprehensive examples including:
Provider compatibility matrix:
| Feature | OpenAI | Anthropic | Gemini | Ollama |
|---|---|---|---|---|
| Structured Output | ✅ | ✅ | ✅ | ✅ |
| Vision (Images) | ✅ | ✅ | ✅ | ⚠️ Limited |
| Image URLs | ✅ | ❌ | ❌ | ❌ |
| Tool Calling | ✅ | ✅ | ✅ | Varies |
Cost optimization strategy:
Full documentation: See references/providers.md for all configuration options, provider-specific features, and troubleshooting.
Process images alongside text using the unified DSPy::Image interface.
Quick reference:
class VisionSignature < DSPy::Signature
description "Analyze image and answer questions"
input do
const :image, DSPy::Image
const :question, String
end
output do
const :answer, String
end
end
predictor = DSPy::Predict.new(VisionSignature)
result = predictor.forward(
image: DSPy::Image.from_file("path/to/image.jpg"),
question: "What objects are visible?"
)
Image loading methods:
# From file
DSPy::Image.from_file("path/to/image.jpg")
# From URL (OpenAI only)
DSPy::Image.from_url("https://example.com/image.jpg")
# From base64
DSPy::Image.from_base64(base64_data, mime_type: "image/jpeg")
Provider support:
Full documentation: See references/core-concepts.md section on Multimodal Support.
Write standard RSpec tests for LLM logic.
Quick reference:
RSpec.describe EmailClassifier do
before do
DSPy.configure do |c|
c.lm = DSPy::LM.new('openai/gpt-4o-mini',
api_key: ENV['OPENAI_API_KEY'])
end
end
it 'classifies technical emails correctly' do
classifier = EmailClassifier.new
result = classifier.forward(
email_subject: "Can't log in",
email_body: "Unable to access account"
)
expect(result[:category]).to eq('Technical')
expect(result[:priority]).to be_in(['High', 'Medium', 'Low'])
end
end
Testing patterns:
Full documentation: See references/optimization.md section on Testing.
Automatically improve prompts and modules using optimization techniques.
MIPROv2 optimization:
require 'dspy/mipro'
# Define evaluation metric
def accuracy_metric(example, prediction)
example[:expected_output][:category] == prediction[:category] ? 1.0 : 0.0
end
# Prepare training data
training_examples = [
{
input: { email_subject: "...", email_body: "..." },
expected_output: { category: 'Technical' }
},
# More examples...
]
# Run optimization
optimizer = DSPy::MIPROv2.new(
metric: method(:accuracy_metric),
num_candidates: 10
)
optimized_module = optimizer.compile(
EmailClassifier.new,
trainset: training_examples
)
A/B testing different approaches:
# Test ChainOfThought vs ReAct
approach_a_score = evaluate_approach(ChainOfThoughtModule, test_set)
approach_b_score = evaluate_approach(ReActModule, test_set)
Full documentation: See references/optimization.md section on Optimization.
Track performance, token usage, and behavior in production.
OpenTelemetry integration:
require 'opentelemetry/sdk'
OpenTelemetry::SDK.configure do |c|
c.service_name = 'my-dspy-app'
c.use_all
end
# DSPy automatically creates traces
Langfuse tracing:
DSPy.configure do |c|
c.lm = DSPy::LM.new('openai/gpt-4o-mini',
api_key: ENV['OPENAI_API_KEY'])
c.langfuse = {
public_key: ENV['LANGFUSE_PUBLIC_KEY'],
secret_key: ENV['LANGFUSE_SECRET_KEY']
}
end
Custom monitoring:
Full documentation: See references/optimization.md section on Observability.
gem install dspy dspy-openai # or dspy-anthropic, dspy-gemini
assets/config-template.rb):require 'dspy'
DSPy.configure do |c|
c.lm = DSPy::LM.new('openai/gpt-4o-mini',
api_key: ENV['OPENAI_API_KEY'])
end
assets/signature-template.rb):class MySignature < DSPy::Signature
description "Clear description of task"
input do
const :input_field, String, desc: "Description"
end
output do
const :output_field, String, desc: "Description"
end
end
assets/module-template.rb):class MyModule < DSPy::Module
def initialize
super
@predictor = DSPy::Predict.new(MySignature)
end
def forward(input_field:)
@predictor.forward(input_field: input_field)
end
end
module_instance = MyModule.new
result = module_instance.forward(input_field: "test")
puts result[:output_field]
references/optimization.md):RSpec.describe MyModule do
it 'produces expected output' do
result = MyModule.new.forward(input_field: "test")
expect(result[:output_field]).to be_a(String)
end
end
gem 'dspy'
gem 'dspy-openai' # or other provider
config/initializers/dspy.rb (see assets/config-template.rb for full example):require 'dspy'
DSPy.configure do |c|
c.lm = DSPy::LM.new('openai/gpt-4o-mini',
api_key: ENV['OPENAI_API_KEY'])
end
app/llm/ directory:# app/llm/email_classifier.rb
class EmailClassifier < DSPy::Module
# Implementation here
end
class EmailsController < ApplicationController
def classify
classifier = EmailClassifier.new
result = classifier.forward(
email_subject: params[:subject],
email_body: params[:body]
)
render json: result
end
end
class AnalysisPipeline < DSPy::Module
def initialize
super
@extract = DSPy::Predict.new(ExtractSignature)
@analyze = DSPy::ChainOfThought.new(AnalyzeSignature)
@summarize = DSPy::Predict.new(SummarizeSignature)
end
def forward(text:)
extracted = @extract.forward(text: text)
analyzed = @analyze.forward(data: extracted[:data])
@summarize.forward(analysis: analyzed[:result])
end
end
class ResearchAgent < DSPy::Module
def initialize
super
@agent = DSPy::ReAct.new(
ResearchSignature,
tools: [
WebSearchTool.new,
DatabaseQueryTool.new,
SummarizerTool.new
],
max_iterations: 10
)
end
def forward(question:)
@agent.forward(question: question)
end
end
class WebSearchTool < DSPy::Tool
def call(query:)
results = perform_search(query)
{ results: results }
end
end
class SmartRouter < DSPy::Module
def initialize
super
@classifier = DSPy::Predict.new(ClassifySignature)
@simple_handler = SimpleModule.new
@complex_handler = ComplexModule.new
end
def forward(input:)
classification = @classifier.forward(text: input)
if classification[:complexity] == 'Simple'
@simple_handler.forward(input: input)
else
@complex_handler.forward(input: input)
end
end
end
class RobustModule < DSPy::Module
MAX_RETRIES = 3
def forward(input, retry_count: 0)
begin
@predictor.forward(input)
rescue DSPy::ValidationError => e
if retry_count < MAX_RETRIES
sleep(2 ** retry_count)
forward(input, retry_count: retry_count + 1)
else
# Fallback to default or raise
raise
end
end
end
end
This skill includes comprehensive reference materials and templates:
references/core-concepts.md: Complete guide to signatures, modules, predictors, multimodal support, and best practicesreferences/providers.md: All LLM provider configurations, compatibility matrix, cost optimization, and troubleshootingreferences/optimization.md: Testing patterns, optimization techniques, observability setup, and monitoringassets/signature-template.rb: Examples of signatures including basic, vision, sentiment analysis, and code generationassets/module-template.rb: Module patterns including pipelines, agents, error handling, caching, and state managementassets/config-template.rb: Configuration examples for all providers, environments, observability, and production patternsTrigger this skill when: