Instruction optimizers: MIPROv2 and GEPA
Demo optimizers choose examples. Instruction optimizers rewrite the signature's instructions, using a model to propose new wording and your metric to pick the best.
So far every optimizer left Triage.instructions, "Sort a support ticket for an online shop.", as you wrote it. The instruction optimizers change it. They need a model that can write good instructions, which is why the course shows them without running them: the stand-in's keyword rules cannot propose wording, and a hosted model's proposals change every run, so no output here could be checked.
MIPROv2
import dspy
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
optimizer = dspy.MIPROv2(metric=exact, auto="light", num_threads=8)
optimized = optimizer.compile(dspy.Predict(Triage), trainset=trainset, valset=devset)
print(optimized.signature.instructions)MIPROv2 works in three stages. It bootstraps demo sets, like lesson 17. It asks the model to propose candidate instructions, showing it a summary of the data, the program's code and example runs. Then it searches combinations of instruction and demo set with Bayesian optimization, evaluating each on batches of the validation set. auto="light", "medium" or "heavy" sets the budget. It needs pip install "dspy[optuna]".
GEPA
def exact_with_feedback(example, prediction, trace=None, pred_name=None, pred_trace=None):
ok = example.category == prediction.category
feedback = "Correct." if ok else f"Expected {example.category}, got {prediction.category}."
return dspy.Prediction(score=float(ok), feedback=feedback)
optimizer = dspy.GEPA(metric=exact_with_feedback, auto="light", reflection_lm=dspy.LM("openai/gpt-4o"))
optimized = optimizer.compile(dspy.Predict(Triage), trainset=trainset, valset=devset)GEPA reads text, not only scores. Its metric returns a Prediction with score and feedback. A reflection_lm, usually a stronger model, reads failed runs with their feedback and writes improved instructions, and GEPA keeps a population of the best variants. Feedback like "Expected billing: money back is always billing" is information a score cannot carry.
Which one
| Situation | Try |
|---|---|
| No budget, first attempt | LabeledFewShot, then BootstrapFewShot |
| Demos help but vary between runs | BootstrapFewShotWithRandomSearch |
| The instructions are the problem | GEPA or MIPROv2 |
| A metric that can explain failures | GEPA |
- Write the feedback message you would want for a shipping ticket sorted as account.
- Look up
BootstrapFinetunein DSPy's docs: what does it change instead of the prompt? - List which optimizers from this part make model calls while compiling.
This is what real progress feels like.