mcpbeat

Dspy Miprov2 Optimizer

omidzamani/dspy-miprov2-optimizer

Use for MIPROv2, Bayesian optimization, instruction and demo tuning, and high-performance DSPy program optimization.

2k tokens
context cost
the whole folder, loaded on every use
2
files
ships runnable scripts
0
copies elsewhere
how many repositories repackaged it
119
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/OmidZamani/dspy-skills --skill dspy-miprov2-optimizer

What comes with it

524 bytes besides the instruction
example.py

The instruction itself

17 sections, as written by the author

DSPy MIPROv2 Optimizer

Goal

Jointly optimize instructions and few-shot demonstrations using Bayesian Optimization for maximum performance.

When to Use

  • You have 200+ training examples
  • You can afford longer optimization runs (40+ trials)
  • You need state-of-the-art performance
  • Both instructions and demos need tuning
  • For limited data (10-50 examples): dspy-bootstrap-fewshot
  • For agentic systems: dspy-gepa-reflective
  • Measure improvements: dspy-evaluation-suite

Inputs

| Input | Type | Description |

|-------|------|-------------|

| program | dspy.Module | Program to optimize |

| trainset | list[dspy.Example] | 200+ training examples |

| metric | callable | Evaluation function |

| auto | str | "light", "medium", or "heavy" |

| num_trials | int | Optimization trials (40+) |

Outputs

| Output | Type | Description |

|--------|------|-------------|

| compiled_program | dspy.Module | Fully optimized program |

Workflow

Install the optional Optuna dependency before using MIPROv2:

pip install -U "dspy[optuna]>=3.2.1,<3.3"

Three-Stage Process

  • Bootstrap - Generate candidate demonstrations
  • Propose - Create grounded instruction candidates
  • Search - Bayesian optimization over combinations

Phase 1: Setup

import dspy
from dspy.teleprompt import MIPROv2

lm = dspy.LM('openai/gpt-4o-mini')
dspy.configure(lm=lm)

Phase 2: Define Program

class RAGAgent(dspy.Module):
    def __init__(self):
        self.retrieve = dspy.Retrieve(k=3)
        self.generate = dspy.ChainOfThought("context, question -> answer")
    
    def forward(self, question):
        context = self.retrieve(question).passages
        return self.generate(context=context, question=question)

Phase 3: Optimize

from dspy.teleprompt import MIPROv2

optimizer = MIPROv2(
    metric=dspy.evaluate.answer_exact_match,
    auto="medium",  # Balanced optimization
    num_threads=24
)

compiled = optimizer.compile(RAGAgent(), trainset=trainset)

Auto Presets

| Preset | Trials | Use Case |

|--------|--------|----------|

| "light" | ~10 | Quick iteration |

| "medium" | ~40 | Production optimization |

| "heavy" | ~100+ | Maximum performance |

Production Example

import dspy
from dspy.teleprompt import MIPROv2
from dspy.evaluate import Evaluate
import json
import logging

logger = logging.getLogger(__name__)

class ReActAgent(dspy.Module):
    def __init__(self, tools):
        self.react = dspy.ReAct("question -> answer", tools=tools)
    
    def forward(self, question):
        return self.react(question=question)

def search_tool(query: str) -> list[str]:
    """Search knowledge base."""
    results = dspy.ColBERTv2(url='http://20.102.90.50:2017/wiki17_abstracts')(query, k=3)
    return [r['long_text'] for r in results]

def optimize_agent(trainset, devset):
    """Full MIPROv2 optimization pipeline."""
    
    agent = ReActAgent(tools=[search_tool])
    
    # Baseline evaluation
    evaluator = Evaluate(
        devset=devset,
        metric=dspy.evaluate.answer_exact_match,
        num_threads=8
    )
    baseline = evaluator(agent)
    logger.info(f"Baseline: {baseline:.2%}")
    
    # MIPROv2 optimization
    optimizer = MIPROv2(
        metric=dspy.evaluate.answer_exact_match,
        auto="medium",
        num_threads=24,
        # Custom settings
        num_candidates=15,
        max_bootstrapped_demos=4,
        max_labeled_demos=8
    )
    
    compiled = optimizer.compile(agent, trainset=trainset)
    optimized = evaluator(compiled)
    logger.info(f"Optimized: {optimized:.2%}")
    
    # Save with metadata
    compiled.save("agent_mipro.json")
    
    metadata = {
        "baseline_score": baseline,
        "optimized_score": optimized,
        "improvement": optimized - baseline,
        "num_train": len(trainset),
        "num_dev": len(devset)
    }
    
    with open("optimization_metadata.json", "w") as f:
        json.dump(metadata, f, indent=2)
    
    return compiled, metadata

Instruction-Only Mode

from dspy.teleprompt import MIPROv2

# Disable demos for pure instruction optimization
optimizer = MIPROv2(
    metric=metric,
    auto="medium",
    max_bootstrapped_demos=0,
    max_labeled_demos=0
)

Best Practices

  • Data quantity matters - 200+ examples for best results
  • Use auto presets - Start with "medium", adjust based on results
  • Parallel threads - Use num_threads=24 or higher if available
  • Monitor costs - Track API usage during optimization
  • Save intermediate - Bayesian search saves progress

Limitations

  • High computational cost (many LLM calls)
  • Requires substantial training data
  • Optimization time: hours for "heavy" preset
  • Memory intensive for large candidate sets

Official Documentation

  • DSPy Documentation: https://dspy.ai/
  • DSPy GitHub: https://github.com/stanfordnlp/dspy
  • MIPROv2 API: https://dspy.ai/api/optimizers/MIPROv2/
  • Optimizers Guide: https://dspy.ai/learn/optimization/optimizers/

How to use it

Copy the folder

Take omidzamani/dspy-miprov2-optimizer from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.

Install what it needs

The instructions reference pip. Without those the skill loads but fails at the first command.