Packages

Elixir implementation of the GEPA (Genetic-Pareto) optimizer that combines LLM-powered reflection with Pareto search to evolve text-based system components.

Current section

Files

Jump to
gepa_ex examples 04_state_persistence.exs
Raw

examples/04_state_persistence.exs

#!/usr/bin/env elixir
# GEPA State Persistence Example
# ===============================
#
# This example demonstrates how to:
# - Save optimization state to disk
# - Resume interrupted optimizations
# - Inspect saved results
# - Gracefully stop long-running optimizations
#
# ## To run:
# mix run examples/04_state_persistence.exs
#
# ## To resume an optimization:
# # The script will automatically resume if state exists
# mix run examples/04_state_persistence.exs
# Mix.install([{:gepa_ex, path: "."}])
# Configuration
run_dir = "./tmp/gepa_example_run"
max_iterations_per_run = 5
total_desired_iterations = 15
# Training data
trainset = [
%{input: "What is the capital of France?", answer: "Paris"},
%{input: "What is 10 * 12?", answer: "120"},
%{input: "Who wrote Hamlet?", answer: "Shakespeare"},
%{input: "What is the largest ocean?", answer: "Pacific"},
%{input: "What year did World War II end?", answer: "1945"}
]
valset = [
%{input: "What is the capital of Japan?", answer: "Tokyo"},
%{input: "What is 7 * 8?", answer: "56"}
]
seed_candidate = %{
"instruction" => "Answer the question accurately and concisely."
}
IO.puts("""
πŸ’Ύ GEPA State Persistence Example
=================================
Run directory: #{run_dir}
Max iterations per run: #{max_iterations_per_run}
Total desired: #{total_desired_iterations}
""")
# Check if previous state exists
state_file = Path.join(run_dir, "state.etf")
previous_state_exists = File.exists?(state_file)
if previous_state_exists do
# Load previous state to check progress
previous_state = File.read!(state_file) |> :erlang.binary_to_term()
IO.puts("""
♻️ Found previous optimization state!
Previous iterations: #{previous_state.i}
Previous best score: #{Float.round(GEPA.Result.best_score(previous_state), 3)}
Resuming optimization...
""")
else
IO.puts("\nπŸ†• Starting new optimization...\n")
end
# Create adapter
adapter = GEPA.Adapters.Basic.new(llm: GEPA.LLM.Mock.new())
# Run optimization with state persistence
{:ok, result} =
GEPA.optimize(
seed_candidate: seed_candidate,
trainset: trainset,
valset: valset,
adapter: adapter,
# πŸ”‘ This enables state persistence!
run_dir: run_dir,
max_metric_calls: max_iterations_per_run
)
IO.puts("""
βœ… Optimization Run Complete!
=============================
Current iteration: #{result.i}
Best score: #{Float.round(GEPA.Result.best_score(result), 3)}
Total evaluations: #{result.total_num_evals}
State saved to: #{run_dir}/
""")
# Check if we should continue
if result.i < total_desired_iterations do
IO.puts("""
⏸️ Paused at iteration #{result.i}/#{total_desired_iterations}
To continue optimization, run this script again:
mix run examples/04_state_persistence.exs
The optimization will automatically resume from iteration #{result.i + 1}.
πŸ“ Saved files:
- #{run_dir}/state.etf (optimization state)
- #{run_dir}/result.etf (results so far)
πŸ’‘ To stop optimization gracefully, create a file:
touch #{run_dir}/gepa.stop
""")
else
IO.puts("""
πŸŽ‰ Optimization Complete!
=========================
Reached #{result.i} iterations (target: #{total_desired_iterations})
Best candidate:
#{GEPA.Result.best_candidate(result)["instruction"]}
πŸ“Š Final statistics:
- Total iterations: #{result.i}
- Total evaluations: #{result.total_num_evals}
- Best validation score: #{Float.round(GEPA.Result.best_score(result), 3)}
- Candidates evaluated: #{length(result.program_candidates)}
- Pareto front size: #{length(result.program_at_pareto_front_valset)}
""")
end
IO.puts("""
πŸ“š What you learned:
- Use `run_dir` option to enable state persistence
- Optimization automatically resumes from saved state
- State is saved after each iteration
- Graceful stopping with `gepa.stop` file
- Inspect saved state at any time
πŸ”§ Advanced usage:
- Set different max_metric_calls for each run
- Inspect intermediate results between runs
- Copy state to continue with different parameters
- Archive successful optimization runs
🧹 Cleanup:
rm -rf #{run_dir}
""")