DSPy Optimizers Explained: How to Choose the Right One

 

In one of my previous posts, I explored GEPA (Genetic-Pareto), one of the advanced prompt optimization techniques available in DSPy.

Suppose you already have a working program and a metric (for evaluation). The next question is: which optimizer should you use to improve your program.

DSPy offers several optimization approaches, ranging from simple few-shot demonstration selection to evolutionary prompt optimization and model fine-tuning. Understanding their differences can help you choose the right approach without spending unnecessary time and compute.

What does each optimizer tune?

As illustrated in the figure at the beginning of this post, DSPy optimizers generally target one or more of three components:

  • Demonstrations (demos): In-context examples included in the prompt.
  • Instructions: Natural language instructions that guide the LLM.
  • Model weights: The underlying parameters of the LLM.

The first two approaches optimize the prompt and can therefore work with virtually any LLM, including models accessed through APIs.

Weight optimization, on the other hand, requires a model whose weights can be fine-tuned, such as an open-source model or one supported by an LLM provider’s fine-tuning endpoint.

How to narrow down the options?

DSPy suggests considering two key questions when choosing an optimizer:

  1. What is the bottleneck? Instructions, demos, or model weights?
  2. What is your compute budget? Some optimizers require substantially more LLM calls than others.

The first question helps identify what needs optimization. If the prompt wording is the problem, instruction optimizers (COPRO, GEPA, MIPROv2) can help. If the model needs examples to anchor format and style, demo optimizers (BootstrapFewShot, BootstrapRS) are worth considering. If the model itself is the limit and you can fine-tune it, weight tuning (BootstrapFinetune) is the lever.

The second question determines how extensively you can search for improvements. Zero-config baselines (LabeledFewShot, BootstrapFewShot) cost almost nothing. Search-based optimizers (BootstrapRS, MIPROv2, GEPA) can require considerably more cost. Combined optimizers (BetterTogether) pay both bills.

In practice, however, there is one more important consideration:

How many labeled examples do you have?

The size and quality of your training dataset determine which optimization approaches are practical. With only a handful of labeled examples, sophisticated optimization can easily overfit, particularly when the same examples are used for both optimization and evaluation. There may also be insufficient successful examples to bootstrap useful demonstrations.

In this situation, start with a simple baseline, use demonstrations carefully, and consider generating additional labeled data. With a larger and more representative dataset, you can run more reliable evaluations and explore search-based optimizers with greater confidence. Fine-tuning generally requires a more substantial and suitable training dataset.

Remember that dataset size alone is not enough. Diversity, representativeness, label quality, and evaluation metric reliability matter just as much.

A closer look at each optimizer

Let’s start with optimizers that focus on demonstrations.

dspy.LabeledFewShot(k=16)

  • A simple baseline to start with.
  • No LLM calls during .comple()
  • Samples up to k examples from the trainset, and use them as demos in the prompt

dspy.BootstrapFewShot(metric=None, metric_threshold=None, teacher_settings=None, max_bootstrapped_demos=4, max_labeled_demos=16, max_rounds=1)

  • Another useful baseline.
  • Automatically generates demonstrations from successful model predictions.
  • Instead of manually writing examples into your prompt, DSPy lets the model solve training examples, evaluates its predictions using your metric, and keeps successful ones as bootstrapped demonstrations.
  • The final demonstration set can contain up to max_bootstrapped_demos bootstrapped examples and max_labeled_demos original labeled examples.

dspy.BootstrapFewShotWithRandomSearch(metric, max_bootstrapped_demos=4, max_labeled_demos=16, max_rounds=1, num_candidate_programs=16, num_threads=None, stop_at_score=None)

  • Extends BootstrapFewShot with randomized candidate search.
  • Runs multiple BootstrapFewShot trials with different randomized demonstration selections.
  • Evaluates the resulting candidate programs on a validation set and selects the best-performing one.

This is useful when a single BootstrapFewShot run does not produce consistently good demonstrations.

dspy.KNNFewShot(k, trainset, vectorizer, **bootstrap_kwargs)

  • Demos are chosen dynamically at inference time
  • Uses a k-nearest-neighbor approach to compare the input with training examples and retrieve the most relevant k demonstrations.
  • Particularly useful when different inputs benefit from different examples and you have a sufficiently large, representative training set.

Next, let’s look at optimizers that focus on instructions.

dspy.COPRO(prompt_model=None, metric=None, breadth=10, depth=3, init_temperature=1.4, track_stats=False)

  • A breadth-and-depth instruction search optimizer.
  • At each depth level, generates multiple candidate instructions for each predictor and evaluates them, retaining the better-performing candidates.
  • Useful when your existing demonstrations are already strong, but the instruction wording needs improvement.

dspy.GEPA(metric, auto=None, max_full_evals=None, max_metric_calls=None, reflection_lm=None, skip_perfect_score=True, instruction_proposer=None, use_merge=True, num_threads=None)

  • An evolutionary optimizer that uses natural-language feedback and reflection to improve programs.
  • GEPA maintains a population of candidate programs, evaluates them on the training examples, and uses feedback from the metric to identify opportunities for improvement.
  • A reflection LLM (reflection_lm) analyzes the feedback and proposes instruction edits. GEPA also uses Pareto-based selection to retain promising candidates that perform well across different examples.

For a deeper explanation of how GEPA works, see my previous post: Demystifying GEPA: Genetic-Pareto Prompt Optimizer.

Write on Medium

The following optimizers combine instruction and demo optimization.

dspy.MIPROv2(metric, prompt_model=None, task_model=None, teacher_settings=None, max_bootstrapped_demos=4, max_labeled_demos=4, auto="light", num_candidates=None, num_threads=None, init_temperature=1.0, track_stats=True)

  • Uses Bayesian-optimization search over the joint instruction and demo space.
  • The prompt_model (often a stronger LLM) proposes candidate instructions, while the task_model (your student) executes the program and evaluate it.
  • Searches for effective combinations of instructions and demonstrations rather than optimizing each independently.

MIPROv2 is a strong choice when both instructions and demonstrations need improvement.

dspy.SIMBA(metric, bsize=32, num_candidates=6, max_steps=8, max_demos=4, prompt_model=None, teacher_settings=None, num_threads=None)

  • Mini-batch SGD-flavored search.
  • Each optimization step samples a minibatch of examples, finds the worst-scoring examples, and uses prompt_model to propose improvements.
  • Improvements can take the form of a natural-language rule (instruction patch) or a new demo.

dspy.InferRules(num_candidates=10, num_rules=10, num_threads=None, **bootstrap_kwargs)

  • Built on top of BootstrapFewShot
  • First bootstraps successful demonstrations from the training set.
  • Then asks a teacher LLM to analyze these demonstrations and extract generalizable rules.
  • Appends the extracted rules to the program instructions.

This is useful when successful examples contain recurring patterns that can be expressed as explicit instructions.

Next, let’s look at weight optimization.

dspy.BootstrapFinetune(metric=None, multitask=True, train_kwargs=None, adapter=None, exclude_demos=False, num_threads=None)

  • Fine-tunes the underlying model weights using successful execution traces.
  • First bootstraps successful traces in a similar way to BootstrapFewShot.
  • Converts these traces into training data and uses them to fine-tune the student LLM.

Unlike prompt-only optimization, this approach requires a model and training infrastructure that support fine-tuning.

Finally, DSPy also provides several composite and specialized optimizers.

  • dspy.BetterTogether: A meta-optimizer that combines different optimization approaches in sequence. For example, it can optimize prompts first, fine-tune model weights, and then optimize prompts again.
  • dspy.Ensemble: Not an optimizer in the traditional sense, but a way to combine multiple candidate programs during inference. It uses a custom reduce_fn to aggregate their outputs.
  • dspy.AvatarOptimizer: Designed for agent-style programs. It partitions the training set into positive and negative examples based on metric scores. An LLM then analyzes the differences between successful and unsuccessful examples and proposes instruction edits to improve the program.

DSPy optimizer selection guide

Now that we’ve covered the different optimizers, let’s summarize when to choose each one.

1. Just starting — unsure what helps

  • Try: BootstrapFewShot
  • Automatically generates demonstrations from successful model predictions.

2. Demonstrations vary in quality across attempts

  • Try: BootstrapFewShotWithRandomSearch
  • Explores different combinations of demonstrations to find better-performing sets.

3. Large training set — different inputs need different demonstrations

  • Try: KNNFewShot
  • Selects relevant demonstrations based on input similarity.

4. Instructions look wrong, but demonstrations look fine

  • Try: COPRO or GEPA
  • Optimizes the instructions while retaining useful demonstrations.

5. Both instructions and demonstrations look weak, and you have compute budget

  • Try: MIPROv2 or GEPA
  • Optimizes instructions and demonstrations together.

6. Failure cases share a recognizable pattern

  • Try: SIMBA or InferRules
  • Uses failure analysis to improve the prompt or derive better rules.

7. Prompt-only optimization has plateaued, but the model is tunable

  • Try: BootstrapFinetune
  • Uses successful demonstrations to help fine-tune model weights.

8. You want to combine prompt optimization and weight tuning

  • Try: BetterTogether
  • Combines prompt optimization with model fine-tuning.

9. You have multiple competent programs to combine

  • Try: Ensemble
  • Combines multiple programs to improve overall performance.

10. Agent or tool-use tasks

  • Try: AvatarOptimizer or GEPA
  • Optimizes agent behavior and tool-use performance.

Final thoughts

DSPy provides a broad range of optimizers, but there is no universally best choice. The right optimizer depends on what is limiting your program, the quality and quantity of your labeled data, and how much compute you can afford.

It is good to start with a simple baseline such as BootstrapFewShot, establish a reliable evaluation process, and then identify whether instructions, demonstrations, or model weights are the actual bottleneck.

More sophisticated optimization is not necessarily better. The goal is to find the simplest approach that delivers measurable improvements on representative, unseen data.

What Is Jev? What Pain Points in LLMs Does It Solve?

 The Jev model has been gaining attention across social media platforms such as Twitter and LinkedIn over the past few days, with many people welcoming this new type of frontier model.

In this post, we’ll take a closer look at what Jev is, and why it has attracted so much attention, and what pain points of existing LLMs it aims to address.


What is Jev?

According to Typesafe —the startup behind Jev, the company founded in 2024, raised $40M in seed funding, and remained in stealth for about two years before publicly launching in September 2026:

Jev is Typesafe’s first System One Model: a new class of frontier models built to make fast, structured decisions that software can use directly.

What does “system one model” mean?

The name inspired by Daniel Kahneman’s popular book Thinking, Fast and Slow. The model class name draws on Kahneman’s distinction between two modes of human thinking:

  • System 1: fast, intuitive, and automatic thinking
  • System 2: slow, deliberate, and effortful reasoning

The idea behind a System One Model is therefore to emphasize fast, structured decision-making

You give it:

  • some state/context — e.g. a social media post
  • one or more questions
  • a predefined answer space

and it returns a structured decision rather than generating text.

For example, suppose we give Jev a social media post

{
"post": "Blackpink member Lisa's new song Sawadika is so awesome! I highly recommend it!"
}

and questions

{
"lisa-mention": {
"type": "noul",
"instructions": "Is Blackpink member Lisa mentioned?",
"criteria": {
"true": "",
"false": ""
}
},
"sentiment": {
"type": "noul",
"instructions": "Is the sentiment of the post postive?",
"criteria": {
"true": "",
"false": ""
}
}
}

it can then return a structured results like:

{
"model": "jev-1.13.0",
"answers": {
"lisa-mention": {
"type": "noul",
"noul": 0.99,
"stats": {}
},
"sentiment": {
"type": "noul",
"noul": 0.98,
"stats": {}
}
},
"usage": {
"input_tokens": 348,
"output_tokens": 41
},
"request_id": "playground_145bf5fb0a91b2e44fd9add60eeece28811",
"evaluation_time_ms": 158.65631199994823
}

What pain points does Jev solve?

LLMs and LLM-powered agents have become increasingly popular, so why has a new frontier model like Jev attracted so much attention all of a sudden?

The answer lies in a fundamental difference in what Jev is designed to do. Rather than generating text for humans to read, Jev is designed to make structured decisions that software can consume directly.

This addresses several important pain points when using conventional LLMs in production.

First, structured output is not guaranteed.

If you have deployed LLMs in production workflows, you probably know the problem: asking an LLM to return a specific JSON schema does not necessarily guarantee that the output will always conform to that schema.

LLMs generate output token by token, and their outputs are inherently probabilistic. Even when the probability of producing an invalid response is very low, a single malformed JSON response can still break a downstream workflow. In production systems, even a small failure rate can become significant when a model is called millions of times.

This is one of the areas where Jev takes a fundamentally different approach. Its outputs are type-safe structured values, with the possible output structure defined in advance. TypeSafe claims that Jev cannot produce type errors because the model does not generate arbitrary strings that need to be parsed and validated.

Second, cost.

The cost of frontier LLMs has fallen significantly, especially with the growing number of open-weight and highly competitive models. However, inference is still generally priced around input and output tokens, with output tokens often costing substantially more than input tokens.

Jev takes a different approach. TypeSafe currently lists its input price at $0.042 per million tokens, while its structured outputs have no metered output-token cost.

This matters particularly for large-scale automation, where a system may need to make millions or even billions of relatively small decisions.

Third, latency.

LLMs generate text sequentially, producing one token at a time. Even with highly optimized inference systems, generating a response can introduce substantial latency — especially when reasoning is involved.

Jev uses a different sampling approach: instead of autoregressively generating a sequence of output tokens, it generates its structured outputs in parallel. TypeSafe reports 70–500 ms end-to-end response times for Jev, compared with 3–329 seconds for the frontier LLMs in its comparison. The company says this translates to roughly 40×–200× faster performance for comparable System One tasks.

Taken together, these differences point to a different role for AI models. Traditional LLMs are optimized to generate flexible language for humans, while Jev is designed to provide fast, structured, machine-consumable decisions.

source: https://typesafe.ai/blog/introducing-system-one-models-and-jev?utm_source=chatgpt.com

Although Jev addresses a subset of the problems that LLMs struggle with, it is clearly not designed to replace LLMs altogether. Instead, it can complement them by handling certain tasks in a cheaper and faster way, rather than using a full LLM for every decision.

So obviously, you cannot have a conversation with Jev in the way you would with a traditional LLM.

In fact, this Twitter post by @ryanvogel shows this quite nicely. He conducted an interesting experiment: he tried to turn Jev into a chat model by asking it to predict which character should come next. The results were predictably poor — which makes sense given that Jev is designed for structured decision-making rather than open-ended text generation.

It is also important to distinguish output reliability from prediction accuracy. Eliminating hallucinations in the output schema and guaranteeing a valid structured response does not automatically make the underlying decision correct.

Jev may be cheap and fast, but the real question is how accurate its decisions are across different tasks and use cases. Ultimately, we need to look beyond latency and cost and evaluate how well Jev performs on the problems it is designed to solve.

For example, this LinkedIn post describes another interesting test. The author asks Jev to assign probabilities to the outcome of an unfair coin flip, where the coin is known to land on heads 60% of the time. Given that information, we would expect the probabilities for the next flip to be 60% heads and 40% tails.

However, Jev reportedly returned 99% heads and 1% tails.

This is a useful example of why a guaranteed structured output does not necessarily mean a correct output. Jev can reliably return a valid answer in the expected format, but the quality of the underlying decision still needs to be evaluated.


What is the gist of training Jev?

At this point, we should have a good understanding of how Jev works and how its outputs differ from those of traditional LLMs.

Although not many technical details about the training process have been revealed so far, Jev is optimized with RLCD (Reinforcement Learning for Calibrated Decisions). The goal is to teach the model not only to make decisions, but also to accurately reflect its probability of being correct — in other words, to make calibrated decisions.

This is different from how LLMs are commonly optimized. RLHF (Reinforcement Learning from Human Feedback) trains models to produce responses that humans tend to prefer, while RLVR (Reinforcement Learning with Verifiable Rewards) optimizes models against rewards that can be objectively verified, such as whether a mathematical answer or piece of code is correct.

In simplified terms, we can think of the difference as:

  • RLHF: “Give an answer that people prefer.”
  • RLVR: “Give an answer that can be objectively verified.”
  • RLCD: “Make a decision and be well-calibrated about how likely you are to be correct.”

The community is responding to this idea pretty quickly. There are already open-source System One models trained with RLCD, such as laya, emerging.


Jev represents an interesting shift in how we think about frontier models. Rather than trying to make an LLM generate better and longer responses, it focuses on a different problem: making fast, structured decisions that software can use directly.

This approach addresses some practical pain points of using LLMs in production, particularly the cost and latency of inference and the difficulty of guaranteeing structured outputs. At the same time, these engineering advantages should not be confused with decision accuracy. A model can be fast, cheap, and perfectly structured while still making the wrong decision.

For this reason, Jev is perhaps better viewed not as a replacement for LLMs, but as another component in the AI stack. LLMs remain useful for open-ended language generation and complex reasoning, while a System One model like Jev could handle the many smaller, faster, structured decisions that surround them.

The most interesting question, then, is not whether Jev will replace LLMs, but where this new class of models fits — and how much of the work currently done by LLMs can ultimately be handled more efficiently by specialized decision models.