Skip to main content
Eval Protocol integrates with GEPA (via DSPy) to automatically optimize your prompts using the evaluations you’ve already written. GEPA analyzes which examples pass or fail, proposes structured edits to the prompt, and keeps changes that improve your metric.

How It Works

GEPA treats your @evaluation_test as the optimization objective. It:
  1. Extracts the system prompt from your dataset
  2. Splits your data into training and validation sets
  3. Runs your evaluation function on candidate prompts
  4. Uses a reflection LLM to propose improvements based on failure patterns
  5. Returns the best-performing prompt
The key insight is that your evaluation’s reason field (in EvaluateResult) tells GEPA why examples failed, enabling targeted improvements.

Prerequisites

Install eval-protocol with the dspy extra:
Set your API key:

Basic Usage

Write a normal @evaluation_test, then wrap it with GEPATrainer.

Step 1: Define Your Evaluation Test

my_eval.py

Step 2: Add GEPA Training

my_eval.py

Step 3: Run

Single System Prompt RequirementGEPA extracts and optimizes only the first system prompt found in your dataset. All rows must share the same system prompt for GEPA to work correctly.If your dataset contains different system prompts per row (e.g., different personas or task variations), GEPA will only optimize the first one and apply it to all examples, which may produce unexpected results. Consider splitting such datasets into separate optimization runs.

Case Study: Text-to-SQL

The text-to-sql-quickstart repository demonstrates GEPA on a text-to-SQL benchmark.

Repository Structure

The Database

The benchmark uses a synthetic OpenFlights database (synthetic_openflights.db) containing tables for airlines, airports, countries, planes, and routes. This database is shared between:
  1. Ground truth generation (SQL queries executed to create expected results)
  2. The MCP server (executes model-generated SQL during evaluation)

The MCP Server

The MCP server is a simple HTTP service that accepts SQL queries and returns results from the DuckDB database:
When you run the training script, the MCP server starts automatically. It receives the model’s generated SQL, executes it against the database, and returns the results for comparison with ground truth.

The Evaluation Function

The evaluation compares the model’s SQL output against ground truth by executing both and checking if they return the same data:
The feedback function provides specific details about failures:

Running the Example

  1. Clone the repository:
  1. Set your API key:
  1. The repository includes pre-generated data. To run GEPA training:
This starts the MCP server automatically, runs GEPA optimization, and prints the optimized prompt.
  1. To compare original vs optimized prompts on the test set:

Data Generation (Optional)

If you want to regenerate the synthetic data from scratch:
This runs:
  1. Download real OpenFlights data
  2. Generate synthetic rows using an LLM
  3. Generate SQL queries
  4. Execute queries to get ground truth results
  5. Generate natural language questions from SQL
The scripts/08_regenerate_balanced_data.py script generates data with consistent column naming for better train/test distribution.

Results

On this benchmark, GEPA discovered that failures clustered around column alias mismatches (avg_altitude vs average_altitude) and missing columns. It rewrote the prompt to include explicit naming conventions and a validation checklist.

Configuration

GEPATrainer Parameters

TestFunction
required
The @evaluation_test decorated function to optimize
float
default:"0.8"
Proportion of data for training
float
default:"0.1"
Proportion of data for validation
int
default:"42"
Random seed for dataset splits
str
default:"problem"
Name of the input field in DSPy signature
str
default:"answer"
Name of the output field in DSPy signature
DSPyModuleType
default:"CHAIN_OF_THOUGHT"
DSPy module type: PREDICT, CHAIN_OF_THOUGHT, or PROGRAM_OF_THOUGHT

train() Parameters

LM
DSPy LM for proposing prompt improvements
int
Total budget of LLM calls for optimization
str
Budget preset: “light”, “medium”, or “heavy”. Alternative to max_metric_calls.
int
default:"3"
Number of examples shown to reflection LLM per iteration
int
Parallel threads for running evaluations

Tips

Provide specific feedback. GEPA learns from your evaluation_result.reason. Instead of “Incorrect”, say “Missing column ‘airport_count’”. Choose appropriate budget. For small datasets (under 50 examples), use auto="light". For larger datasets, increase to "medium" or "heavy". Use the right module type. PREDICT for simple tasks, CHAIN_OF_THOUGHT for reasoning tasks, PROGRAM_OF_THOUGHT for code generation. Keep a held-out test set. GEPA should never see your final test data during optimization.

Troubleshooting

GEPA finds no improvement: Add more detailed feedback, increase reflection_minibatch_size, or increase budget. API timeouts: Reduce num_threads or use a faster model. Memory issues: Reduce num_threads or process smaller batches. Dataset has multiple system prompts: GEPA only optimizes the first system prompt found. If your dataset uses different prompts for different tasks, split it into separate datasets with consistent prompts and run GEPA on each.

Resources

GEPA Paper · DSPy Documentation · Text-to-SQL Quickstart