Skip to main content
MIPROv2 (Multi-prompt Instruction PRoposal Optimizer v2) is a trace-guided instruction and demo optimizer. It differs from COPRO by running your program first, then using the captured execution traces plus a library of prompting best practices to generate candidate instructions, rather than searching blind. It also bootstraps few-shot demos from successful runs.

How it works

MIPROv2 works in four phases:

Phase 1: Trace collection

One traced teacher pass over the trainset. Every example runs through your module under trace capture, collecting whole-program scores plus per-Predict input/output spans.

Phase 2: Demo bootstrapping

Successful spans scoring at least min_demo_score become few-shot demos on the predictor that produced them (top max_bootstrapped_demos by score, deduplicated on inputs). A span scores as its rollout does, unless the metric attached a span-level eval via TypedMetric::evaluate_spans — that score then takes precedence (see Evaluation). Demos are installed before instruction search, so candidates are scored against the module as it will actually run.

Phase 3: Candidate generation

Uses the traces and a rotation of prompting tips to generate num_candidates instruction variants per predictor. The prompting tips library includes:
  • Use clear, specific language
  • Consider chain-of-thought for complex tasks
  • Specify output formats
  • Use role-playing when appropriate
  • Handle edge cases explicitly
  • Request structured outputs when needed

Phase 4: Trial evaluation

  • Evaluates up to num_trials candidates per predictor on one sampled minibatch (candidates injected ambiently — the module is never touched during evaluation)
  • Computes performance scores
  • Selects the best performing candidate
  • Installs the accumulated winner (demos + best instructions) once at the end through OptimizeTarget::install

Configuration

Default settings:
You can also set eval_concurrency (concurrent LM calls during evaluation, default 16) and seed (fixes minibatch sampling for reproducible runs). The full field table is in the optimizers reference.

Usage example

The metric is the same TypedMetric used by every optimizer: evaluate(&self, example, prediction, trace) -> Result<Eval>, where example is your full trainset row. MIPROv2 only reads the numerical score; feedback is ignored. See the evaluation reference for the trait. train_examples is a slice of any row type implementing ToInput toward the module’s input — a #[derive(Example)] struct or (Input, Output) tuples; see Data. The module must declare its leaves with predictors!; see Modules.

Typed data loading

Use the shared data ingress reference: DataLoader.

Comparison: COPRO vs MIPROv2 vs GEPA

GEPA is the only optimizer that requires textual feedback from the metric (Eval::with_feedback). The others use numerical scores alone. Full configuration tables for all six live in the optimizers reference.

When to use MIPROv2

  • You have decent training data (15+ examples recommended)
  • Quality matters more than speed
  • Task benefits from prompting best practices and few-shot demos
  • Need trace-informed candidate generation

When to use COPRO

  • You need fast iteration
  • Compute budget is limited
  • Task is straightforward

When to use GEPA

  • Complex tasks with subtle failure modes
  • You can provide rich feedback
  • Multi-objective optimization
  • Need diverse solutions

Implementation notes

The code follows standard Rust practices:
  • No unsafe blocks
  • Results for error handling with context via anyhow
  • Strong types (Candidate, PromptingTips)
  • Builder pattern for configuration
  • Async throughout, no blocking calls
Key public types:
  • PromptingTips - the library of best practices (default_tips(), format_for_prompt())
  • Candidate - the shared engine currency MIPROv2 registers its instruction variants as (see Optimizer engine)
compile_module returns (): MIPROv2 installs the winner on the module and reports nothing further (Report::None through the trait). Cost is roughly num_predictors × (trainset_size + num_trials × minibatch_size) LM calls, minus rollout-cache hits.

Testing

Run tests:
The suite covers trace selection, candidate generation, configuration, and edge cases.

Example

MIPROv2 Example

Complete working example with HuggingFace data loading
The example loads data, measures baseline performance, runs optimization, and shows the improvement.

References