Home / Articles

Agent Evaluation and Optimisation: DSPy, TextGrad, Reflexion and OPRO Compared

How DSPy, TextGrad, Reflexion and OPRO fit together as feedback loops for agents, which to adopt first, and how to separate evaluation from optimisation in an enterprise.

Publisher: REACTAPP.TOP12 min read2869 words

This article is published in English.

Sources: Automated Agent Evaluation and Optimisation: From Clever Prompts to Controlled Improvement

Teams rarely jump straight to automated evaluation and optimisation of agents. The usual path is gradual: a clever prompt and a few one-off experiments come first, then repeatable measurement, then targeted tuning, and finally enough confidence to release changes under control.

It typically begins with an agent that has a strong system prompt, a handful of tools and a demo that impresses. That is a fine start, but it settles little. As more people depend on the agent, the questions turn practical. Which workflows hold up and which crumble at volume? What happens to behaviour when the underlying model is upgraded? Does the agent do well on the cases that matter most for operations, risk controls or customers?

Prompt engineering is a worthwhile first skill, yet maturity comes from wrapping the agent in a disciplined improvement loop. An agent that can be evaluated systematically can be improved systematically, and one that can be improved systematically can be governed with far more confidence. So the prize is more than better prompts. It is a controlled learning loop for language-model systems: decide what good means, measure behaviour against it, apply targeted optimisation, and keep enough records to trust the outcome.

Five approaches share that thread: DSPy with its MIPRO and COPRO optimisers, TextGrad, Reflexion and OPRO. Their mechanisms, maturity and operational fit differ, but each answers one question: how does an agent move from manual prompt tinkering to repeatable, metric-driven improvement?

Evaluation sits at the centre of every loop

The simplest way to see these methods as one family is as different searches over agent behaviour. All of them presuppose the same four ingredients.

  • Something modifiable: an agent program, a prompt, a workflow or a decision policy.
  • A body of tasks, an evaluation set, standing in for what the agent is supposed to do.
  • A yardstick, whether metric, rubric, reward or success rule, that separates better results from worse.
  • An optimiser, explicit or implicit, which proposes changes based on earlier scores.

Seen that way, these techniques are about closed-loop optimisation more than about prompting. In a company, producing one better prompt is rarely the difficult part. Finding a repeatable way to improve behaviour across many tasks is, because every gain has a price somewhere else:

  • accuracy against latency
  • quality against spend
  • coverage against overfitting
  • autonomy against control
  • broad generality against task-specific tuning
  • a locally improved step against reliability of the whole system

The libraries are therefore better read as positions within a design space for improving agents, not as rival prompt tricks.

Why the pressure is rising

Early enterprise agent projects usually run on expert intuition. A skilled practitioner rewrites prompts, adjusts tool descriptions, adds examples and re-tests until the output looks acceptable. For one or two use cases that is enough.

It breaks down when several teams build agents at once, when prompts drift between environments, when evaluation data ends up scattered, when teams hold different ideas of quality, when a model upgrade shifts behaviour in unpredictable ways, or when audit trails and release confidence start to carry real weight.

Then something resembling MLOps discipline is needed, adapted to systems built on language models. Ordinary software testing is necessary but not sufficient, and classic ML evaluation helps without covering everything. Agents add moving parts of their own: prompts, tool calls, retrieval behaviour, planning structure, memory, retries and sensitivity to the specific model. Automated evaluation and optimisation give practical machinery for taming that variability.

The four main techniques

DSPy with MIPRO and COPRO: optimising the program

Among these tools, DSPy goes furthest toward making model behaviour programmable instead of improvised. Prompts stop being one-off strings, and pipelines are declared in a structured way, which gives improvement a proper surface to work on.

MIPRO and COPRO are the automated optimisers in that ecosystem. MIPRO tunes prompts, instructions and few-shot demonstrations against a metric, and suits teams whose task definition is fairly stable and who want a search to find prompt setups better than a person would by hand. COPRO refines prompts and programs along similar lines. The deeper idea is shared: the program becomes an object that can be compiled, tuned and re-scored, not just edited manually.

In practice this brings automatic prompt compilation, choice of few-shot examples, instruction tuning, metric-guided improvement, and a cleaner split between task logic and the final optimised prompt. The payoff is reproducibility, a firmer base for offline evaluation, less reliance on individual prompt craft, and optimisation that feels like engineering instead of folklore.

For a company wanting a serious internal optimisation workflow rather than a pile of handcrafted prompts, DSPy is among the strongest candidates, particularly for tasks that fit repeatable modules and stable metrics. It has a limit, however. It works best when a task is structured enough for an evaluation set to drive the search, and it is less magical than it looks. With a weak, partial or misaligned signal, the optimiser just gets better at the wrong thing.

TextGrad: critique as a gradient

TextGrad takes a bolder route. In place of numeric gradients it relies on written critique and update signals to improve prompts and prompt-like components. The reasoning is elegant: if a model can say what is wrong with an output and how to fix it, those comments can serve as an optimisation signal.

It supports repeated refinement of prompt text, optimiser-style updates, and work on system prompts, rubrics, plans or even evaluation instructions. Optimisation becomes an iterative process instead of a single search. It fits cases where the right feedback is easier to say in words than in numbers, and it can improve the evaluator's rubric as well as the task prompt.

It is best viewed as a promising primitive and not a finished enterprise answer. It appeals where teams want to refine prompts, plans and grading criteria through language-based feedback, but it is not an obvious organisation-wide default. Its main strength is also its main danger: the update signal is itself language, produced by a model. Without a disciplined evaluation wrapper, that can make optimisation less stable, less interpretable and harder to audit.

Reflexion: learning from failed attempts

Reflexion differs from the previous two. Offline prompt compilation is not its focus. It concerns self-improvement at runtime, driven by reflecting on failure. After an unsuccessful attempt, the agent writes a critique, and that remembered reflection guides later retries. The result is a light learning loop that needs no model fine-tuning.

It offers retry with self-critique, a memory of past failure modes, repair of the agent's trajectory and adaptation within or across attempts. Many agent problems are not prompt problems at all; they are execution problems, such as poor reasoning steps, wrong tool use or skipped checks, and reflection helps recover from those. It also moves learning closer to real operating conditions than offline benchmarks alone can.

For agents that act as workflows rather than single-turn generators, Reflexion is highly relevant, especially where a retry is affordable and collecting recurring failure patterns adds value. It usually arrives as a pattern implemented in code, not as one canonical library, so a company should treat it as a design pattern to standardise in its orchestration layer, not as a vendor decision. The danger is noise: unbounded self-critique adds delay, cost and inconsistency. Reflection should be policy-driven, triggered selectively and evaluated like any other behaviour.

OPRO: a model as the optimiser

OPRO, short for Optimization by PROmpting, makes a language model the optimiser. It proposes better prompt candidates using the history of earlier scores, so one model searches the space of instructions for another model or program.

It covers prompt search, candidate generation and ranking, and iterative improvement. Its logic rests on the fact that language models are good at coming up with alternative wordings, so a diverse search space appears quickly and the approach adapts to many kinds of task.

OPRO is strategically interesting, though it often belongs to the experimentation toolkit more than the default platform stack. It tends to show up in research-style code or custom loops, not in a standardised production library. Its best use may be as a controlled search component inside a larger optimisation service, not as a standalone primitive offered directly to developers.

Two ways to sort the options

The techniques can be arranged along two axes: where optimisation takes place, and what is being optimised.

By location:

  • Offline optimisation covers DSPy with MIPRO and COPRO, TextGrad and OPRO.
  • Runtime or per-episode adaptation is where Reflexion belongs.
  • Hybrid use is possible too, since signals from Reflexion runs can be gathered offline and fed into DSPy-, TextGrad- or OPRO-style loops.

By target:

  • Prompt text and instructions are handled by MIPRO, COPRO, TextGrad and OPRO.
  • Few-shot examples are tuned by MIPRO and COPRO.
  • Program structure and pipeline components fall to the wider DSPy ecosystem.
  • Execution trajectories and error recovery are Reflexion's territory.

The pattern behind both tables is that these methods complement each other, provided they sit inside the right control architecture.

Keep measuring and improving as separate layers

The costliest architectural error is adopting optimisation before a dependable evaluation practice exists. With weak evaluation, optimisation turns hazardous, because the optimiser will improve whatever proxy it is handed, including proxies unrelated to real business value. A sound design splits two layers.

The evaluation fabric defines and runs the measurements. It should hold benchmark datasets and representative tasks, task-specific metrics and rubrics, captured traces of agent trajectories, measures of cost, latency and reliability, slice-level analysis for important sub-populations or failure modes, and release gates with regression detection.

The optimisation fabric takes evaluation results and proposes and validates improvements. Its scope: tuning prompts, picking examples, setting reflection policies for runtime, generating and searching candidates, tracking experiments side by side, and promotion rules that decide when a promising candidate becomes an approved default.

The split matters because evaluation is a governance capability while optimisation is a mechanism for change. A company needs both, and mixing them up is a mistake.

A narrow shortlist

For a practical enterprise stack, as opposed to academic coverage, the shortlist should be cut hard. Not every promising research idea deserves to be a first-class platform dependency.

DSPy as the main optimisation framework. It gives the strongest structure for treating model programs as artefacts that can be optimised. MIPRO and COPRO map directly onto practical prompt and example tuning, and the whole approach suits repeatable internal workflows better than ad hoc prompting. Its role is as the default engine for stable tasks, the base for offline prompt compilation, and the main abstraction for teams that want repeatable, metric-driven gains.

Reflexion as a standard runtime pattern. It need not be a standalone dependency. It targets a different problem from DSPy, namely recovery during execution, and helps tool-using agents and multi-step workflows. It slots into orchestration layers such as LangGraph or plain Python runners. Its role: a selective retry-and-reflect policy for workflow agents, a source of structured failure data for later offline tuning, and a standard way of doing bounded self-correction.

TextGrad as an advanced, experimental option. It offers a novel refinement primitive that suits prompts, rubrics or plans that benefit from critique-driven iteration. It is best added once a stable evaluation harness exists. Its role is a specialist tool for optimisation teams, applied where written feedback is richer than a simple score.

OPRO, lower priority as a platform standard. It is often better as an internal optimisation mode than as a central library choice. Many of its ideas can be reproduced with custom search loops around a stronger evaluation framework, and it is a less natural default for average developers. If used, it should serve as a search strategy inside a central optimisation service, or as an experimentation capability for platform teams.

What to build on top

Developers should not have to assemble these techniques from raw libraries on every project. Most teams have no use for five optimisation paradigms at the application layer. They need a simpler internal framework that fixes how agent quality is defined, measured, improved and promoted. The sensible move is a thin but opinionated internal platform built over a selective set of libraries. It should hide accidental complexity while standardising the controls that matter.

  1. An evaluation SDK. One shared way to define agent tasks, datasets and metrics. It standardises the test-case schema, expected outputs or grading rubrics, trace logging format, capture of cost and latency, dataset versioning and regression baselines. The goal: a team can state its agent, its evaluation set and its success measure without writing a custom harness.
  2. An optimisation service. A controlled service runs optimisation jobs so teams do not wire up their own loops. It supports DSPy-based prompt and example tuning, optional TextGrad refinement, optional OPRO-inspired search, experiment comparison with leaderboard-style reporting, and candidate approval workflows. A developer could request tuning of an agent on a pinned dataset version, within fixed limits on response time and spend, and receive candidates that can be compared like for like.
  3. A runtime reflection policy layer. Reflexion-like behaviour becomes configuration instead of custom code in each agent. Policies cover when retries are allowed, when reflection kicks in, how many retries are permitted, what memory of earlier failures is kept, and when to escalate to a person or fallback workflow. Teams get bounded self-correction from templates and avoid inventing inconsistent retry logic.
  4. A prompt and policy registry. Prompts, rubrics and optimisation artefacts are treated as governed assets: versioned storage, lineage from prompt to experiment to release, notes on model compatibility, rollback support and approval records for production variants. Prompts then behave like deployable configuration, not text copied between notebooks and repositories.
  5. Hooks into the enterprise control plane. The framework connects to CI/CD gates, observability tools, model catalogues, secrets and environment management, data governance controls and approval workflows for high-risk uses. That connection separates a technique library from an enterprise capability.

For most developers this should shrink to four ideas: define the agent's contract, supply evaluation cases, pick an optimisation mode, and review the promoted candidate with its deployment report. Underneath, any of the four techniques may be in play, but what developers see should stay small. The scaling problem is rarely a shortage of algorithms. It is the spread of bespoke, inconsistent improvement loops across teams.

A staged rollout

Stage one: evaluation discipline. Before any broad optimisation, set up shared evaluation schemas, curated benchmark datasets, trace capture and replay, and baseline numbers for cost, latency and task quality.

Stage two: offline optimisation with DSPy. Make DSPy with MIPRO and COPRO the main path for stable task classes, covering prompt compilation, example selection, instruction tuning and repeatable comparison of experiments.

Stage three: bounded runtime reflection. Bring in Reflexion-style policies for agents whose failures can often be recovered by retrying with critique, with selective retries, structured reflection memory and diagnostics at trajectory level.

Stage four: advanced modes, sparingly. Add TextGrad and OPRO-like search only where a clear need exists and evaluation is mature enough to govern them. This should usually stay a platform-team capability before reaching general developers.

Where it goes wrong

  • Metric overfitting. A narrow or stale benchmark teaches the optimiser the benchmark instead of the real task.
  • Fragile rubrics. If grading rests on weak or inconsistent model judges, optimisation chases the quirks of the evaluator.
  • Local wins, global losses. Tuning one subtask can quietly raise cost or slow other steps, or change how the rest of the workflow behaves.
  • Noisy reflection. Reflexion without policy bounds produces more tokens and more delay for little real gain.
  • Organisational fragmentation. When each team picks its own optimisation libraries and evaluation conventions, the company loses comparability and control.

All of these point to the same conclusion: optimisation is only as strong as the evaluation and governance around it.

The shape of the answer

What unites DSPy, MIPRO, COPRO, TextGrad, Reflexion and OPRO is not that each makes prompts better. Each tries to make agent improvement a feedback system. The strategic move is not exposing every idea to every developer, but building a controlled internal framework where evaluation is standardised, optimisation is selective, runtime reflection follows policy, and prompt variants are governed like production assets.

For a tighter recommendation, the strongest position is to let DSPy with MIPRO and COPRO carry offline optimisation, adopt Reflexion as the shared runtime pattern for capped self-correction, reserve TextGrad for specialist teams, and treat OPRO mainly as an internal search technique rather than a developer-facing dependency. The winners among enterprise agents will be decided by the quality of the feedback loop surrounding them, with prompt cleverness counting for much less.