How It Works
GEPA treats your@evaluation_test as the optimization objective. It:
- Extracts the system prompt from your dataset
- Splits your data into training and validation sets
- Runs your evaluation function on candidate prompts
- Uses a reflection LLM to propose improvements based on failure patterns
- Returns the best-performing prompt
reason field (in EvaluateResult) tells GEPA why examples failed, enabling targeted improvements.
Prerequisites
Install eval-protocol with thedspy extra:
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
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:
- Ground truth generation (SQL queries executed to create expected results)
- 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: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:Running the Example
- Clone the repository:
- Set your API key:
- The repository includes pre-generated data. To run GEPA training:
- To compare original vs optimized prompts on the test set:
Data Generation (Optional)
If you want to regenerate the synthetic data from scratch:- Download real OpenFlights data
- Generate synthetic rows using an LLM
- Generate SQL queries
- Execute queries to get ground truth results
- Generate natural language questions from SQL
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 yourevaluation_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, increasereflection_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.

