dspy-advanced-module-composition
This skill should be used when the user asks to "compose DSPy modules", "use Ensemble optimizer", "combine multiple programs", "use dspy.MultiChainComparison", mentions "ensemble voting", "module composition", "sequential pipelines", or needs to build complex multi-module DSPy programs with ensemble patterns or multi-chain comparison.
git clone --depth 1 https://github.com/OmidZamani/dspy-skills /tmp/dspy-advanced-module-composition && cp -r /tmp/dspy-advanced-module-composition/skills/dspy-advanced-module-composition ~/.claude/skills/dspy-advanced-module-compositionSKILL.md
# DSPy Advanced Module Composition
## Goal
Compose complex DSPy programs using the Ensemble optimizer, MultiChainComparison for reasoning synthesis, and sequential module patterns.
## When to Use
- Need consensus from multiple approaches
- Comparing different reasoning strategies
- Building robust pipelines with fallbacks
- Complex multi-step workflows with branching
- Ensemble methods for improved accuracy
## Related Skills
- Design modules: [dspy-custom-module-design](../dspy-custom-module-design/SKILL.md)
- Define signatures: [dspy-signature-designer](../dspy-signature-designer/SKILL.md)
- Evaluate performance: [dspy-evaluation-suite](../dspy-evaluation-suite/SKILL.md)
## Inputs
| Input | Type | Description |
|-------|------|-------------|
| `modules` | `list[dspy.Module]` | Modules to compose |
| `composition_type` | `str` | "ensemble", "sequential", "comparison" |
## Outputs
| Output | Type | Description |
|--------|------|-------------|
| `composed_program` | `dspy.Module` | Composed multi-module program |
## Workflow
### Phase 1: Ensemble Voting
Combine multiple programs using the Ensemble optimizer:
```python
import dspy
from dspy.teleprompt import Ensemble
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
# Define a signature for the task
class BasicQA(dspy.Signature):
"""Answer questions with short factoid answers."""
question = dspy.InputField()
answer = dspy.OutputField()
# Create multiple program instances (should be optimized/compiled programs)
# For simple demonstration, we'll use different predictors
program1 = dspy.Predict(BasicQA)
program2 = dspy.ChainOfThought(BasicQA)
program3 = dspy.Predict(BasicQA)
# Ensemble is an optimizer that compiles programs together
ensemble = Ensemble(reduce_fn=dspy.majority)
ensembled_program = ensemble.compile([program1, program2, program3])
# Use the ensembled program
result = ensembled_program(question="What is 2 + 2?")
print(result.answer) # Voted answer
```
### Phase 2: MultiChainComparison
Compare multiple reasoning attempts:
```python
import dspy
class BasicQA(dspy.Signature):
"""Answer questions with short factoid answers."""
question = dspy.InputField()
answer = dspy.OutputField(desc="often between 1 and 5 words")
class ComparisonPipeline(dspy.Module):
def __init__(self):
# Generate multiple reasoning attempts
self.cot = dspy.ChainOfThought(BasicQA)
# Compare M attempts and select best
# Must pass a Signature class, not a string
self.compare = dspy.MultiChainComparison(
BasicQA,
M=3, # Number of attempts to compare
temperature=0.7
)
def forward(self, question):
# Generate multiple completions to compare
# Each completion must have rationale/reasoning field
completions = [
self.cot(question=question)
for _ in range(3)
]
# MultiChainComparison synthesizes them into best answer
# Pass completions as positional arg, not keyword arg
return self.compare(completions, question=question)
# Usage
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
pipeline = ComparisonPipeline()
result = pipeline(question="Explain quantum computing")
print(f"Best answer: {result.answer}")
print(f"Rationale: {result.rationale}")
```
### Phase 3: Sequential Composition
Chain modules for multi-step workflows:
```python
import dspy
# Define signatures for each step
class QueryRewrite(dspy.Signature):
"""Rewrite a question for better retrieval."""
question = dspy.InputField()
refined_query: str = dspy.OutputField()
class GenerateAnswer(dspy.Signature):
"""Generate answer from context and question."""
context = dspy.InputField()
question = dspy.InputField()
answer = dspy.OutputField()
class ValidateAnswer(dspy.Signature):
"""Validate answer quality."""
answer = dspy.InputField()
question = dspy.InputField()
is_valid: bool = dspy.OutputField()
confidence: float = dspy.OutputField()
class SequentialRAG(dspy.Module):
"""Multi-step RAG pipeline."""
def __init__(self):
# Step 1: Query rewriting
self.rewrite = dspy.Predict(QueryRewrite)
# Step 2: Retrieval
self.retrieve = dspy.Retrieve(k=5)
# Step 3: Answer generation
self.generate = dspy.ChainOfThought(GenerateAnswer)
# Step 4: Validation
self.validate = dspy.Predict(ValidateAnswer)
def forward(self, question):
# Sequential execution
refined = self.rewrite(question=question)
passages = self.retrieve(refined.refined_query).passages
answer_pred = self.generate(
context=passages,
question=question
)
validation = self.validate(
answer=answer_pred.answer,
question=question
)
return dspy.Prediction(
answer=answer_pred.answer,
is_valid=validation.is_valid,
confidence=validation.confidence
)
# Usage
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
rag = SequentialRAG()
result = rag(question="What causes lightning?")
print(f"Answer: {result.answer} (valid: {result.is_valid})")
```
### Phase 4: Fallback Strategies
Handle failures with fallback modules:
```python
import dspy
import logging
logger = logging.getLogger(__name__)
class BasicQA(dspy.Signature):
"""Answer questions with short factoid answers."""
question = dspy.InputField()
answer = dspy.OutputField()
class RobustQA(dspy.Module):
"""Fallback strategy for errors."""
def __init__(self):
self.primary = dspy.ChainOfThought(BasicQA)
self.fallback = dspy.Predict(BasicQA)
def forward(self, question):
try:
result = self.primary(question=question)
if result.answer and len(result.answer) > 10:
return result
except Exception as e:
logger.error(f"Primary faiUse this skill when you need to QA audit and fix a plugin skill file. Provides a methodology for verifying skill content against official documentation, fixing issues in-place, and producing verification reports.
This skill should be used when the user asks to "choose a DSPy adapter", "use JSONAdapter", "use XMLAdapter", "enable native function calling", "send images, audio, or files to DSPy", mentions `dspy.ChatAdapter`, `dspy.JSONAdapter`, `dspy.XMLAdapter`, `dspy.Image`, `dspy.Audio`, `dspy.File`, structured outputs, or multimodal DSPy signatures.
This skill should be used when the user asks to "use BetterTogether", "combine prompt optimization and fine-tuning", "sequence DSPy optimizers", "run prompt then weight optimization", mentions `dspy.BetterTogether`, strategy strings such as "p -> w -> p", or needs to compose multiple DSPy teleprompters into an evaluated optimization sequence.
This skill should be used when the user asks to "bootstrap few-shot examples", "generate demonstrations", "use BootstrapFewShot", "optimize with limited data", "create training demos automatically", mentions "teacher model for few-shot", "10-50 training examples", or wants automatic demonstration generation for a DSPy program without extensive compute.
This skill should be used when the user asks to "create custom DSPy module", "design a DSPy module", "extend dspy.Module", "build reusable DSPy component", mentions "custom module patterns", "module serialization", "stateful modules", "module testing", or needs to design production-quality custom DSPy modules with proper architecture, state management, and testing.
This skill should be used when the user asks to "debug DSPy programs", "trace LLM calls", "monitor production DSPy", "use MLflow with DSPy", mentions "inspect_history", "custom callbacks", "observability", "production monitoring", "cost tracking", or needs to debug, trace, and monitor DSPy applications in development and production.
This skill should be used when the user asks to "build local DSPy retrieval", "use dspy.Embedder", "use dspy.Embeddings", "save an embeddings index", "add FAISS retrieval", mentions semantic search, hosted embeddings, local embedding models, `EmbeddingsWithScores`, or needs a DSPy retriever over an application-owned text corpus.
This skill should be used when the user asks to "evaluate a DSPy program", "test my DSPy module", "measure performance", "create evaluation metrics", "use answer_exact_match or SemanticF1", mentions "Evaluate class", "comparing programs", "establishing baselines", or needs to systematically test and measure DSPy program quality with custom or built-in metrics.