Evolutionary Optimizer: Genetic Algorithms

Discover optimal prompts with genetic algorithms and multi-objective optimization.

The EvolutionaryOptimizer uses genetic algorithms to refine and discover effective prompts. It iteratively evolves a population of prompts, applying selection, crossover, and mutation operations to find prompts that maximize a given evaluation metric. This optimizer can also perform multi-objective optimization (e.g., maximizing score while minimizing prompt length) and leverage LLMs for more sophisticated genetic operations.

EvolutionaryOptimizer is a great choice when you want to explore a very diverse range of prompt structures or when you have multiple objectives to optimize for (e.g., performance score and prompt length). Its strength lies in its ability to escape local optima and discover novel prompt solutions through its evolutionary mechanisms, especially when enhanced with LLM-driven genetic operators.

How It Works

The EvolutionaryOptimizer is built upon the DEAP library for evolutionary computation. The core concept behind the optimizer is that we evolve a population of prompts over multiple generations to find the best one.

We utilize different techniques to evolve the population of prompts:

  • Selection: We select the best prompts from the population to be the parents of the next generation.
  • Crossover: We crossover the parents to create the children of the next generation.
  • Mutation: We mutate the children to create the new population of prompts.

We repeat this process for a number of generations until we find the best prompt.

Evolutionary Optimizer

The optimizer is open-source, you can check out the code in the Opik repository.

Quickstart

You can use the EvolutionaryOptimizer to optimize a prompt:

1from opik_optimizer import EvolutionaryOptimizer
2from opik.evaluation.metrics import LevenshteinRatio # or any other suitable metric
3from opik_optimizer import datasets, ChatPrompt
4
5# 1. Define your evaluation dataset
6dataset = datasets.tiny_test() # Replace with your actual dataset
7
8# 2. Configure the evaluation metric
9def levenshtein_ratio(dataset_item, llm_output):
10 return LevenshteinRatio().score(reference=dataset_item["label"], output=llm_output)
11
12# 3. Define your base prompt and task configuration
13initial_prompt = ChatPrompt(
14 messages=[
15 {"role": "system", "content": "You are a helpful assistant."},
16 {"role": "user", "content": "{text}"}
17 ]
18)
19
20# 4. Initialize the EvolutionaryOptimizer
21optimizer = EvolutionaryOptimizer(
22 model="openai/gpt-4o-mini",
23 model_parameters={"temperature": 0.4},
24 population_size=20,
25 num_generations=10,
26)
27
28# 5. Run the optimization
29optimization_result = optimizer.optimize_prompt(
30 prompt=initial_prompt,
31 dataset=dataset,
32 metric=levenshtein_ratio,
33 n_samples=5
34)
35
36# 6. View the results
37optimization_result.display()

Configuration Options

Optimizer parameters

The optimizer has the following parameters:

model
strDefaults to gpt-4o
model_parameters
dict[str, typing.Any] | None
population_size
intDefaults to 30
num_generations
intDefaults to 15
mutation_rate
floatDefaults to 0.2
crossover_rate
floatDefaults to 0.8
tournament_size
intDefaults to 4
elitism_size
intDefaults to 3
adaptive_mutation
boolDefaults to True
enable_moo
boolDefaults to True
enable_llm_crossover
boolDefaults to True
output_style_guidance
str | None
infer_output_style
boolDefaults to False
n_threads
intDefaults to 12
verbose
intDefaults to 1
seed
intDefaults to 42

optimize_prompt parameters

The optimize_prompt method has the following parameters:

prompt
ChatPrompt
The prompt to optimize
dataset
Dataset
The dataset to use for evaluation
metric
Callable
Metric function to optimize with, should have the arguments dataset_item and llm_output
experiment_config
dict | None
Optional experiment configuration
n_samples
int | None
Optional number of samples to use
auto_continue
boolDefaults to False
Whether to automatically continue optimization
agent_class
type[opik_optimizer.optimizable_agent.OptimizableAgent] | None
Optional agent class to use
project_name
strDefaults to Optimization
Opik project name for logging traces (default: “Optimization”)
max_trials
intDefaults to 10
mcp_config
opik_optimizer.mcp_utils.mcp_workflow.MCPExecutionConfig | None
MCP tool calling configuration (default: None)
args
Any
kwargs
Any

Model Support

There are two models to consider when using the EvolutionaryOptimizer:

  • EvolutionaryOptimizer.model: The model used for the evolution of the population of prompts.
  • ChatPrompt.model: The model used to evaluate the prompt.

The model parameter accepts any LiteLLM-supported model string (e.g., "gpt-4o", "azure/gpt-4", "anthropic/claude-3-opus", "gemini/gemini-1.5-pro"). You can also pass in extra model parameters using the model_parameters parameter:

1optimizer = EvolutionaryOptimizer(
2 model="anthropic/claude-3-opus-20240229",
3 model_parameters={
4 "temperature": 0.7,
5 "max_tokens": 4096
6 }
7)

Next Steps

  1. Explore specific Optimizers for algorithm details.
  2. Refer to the FAQ for common questions and troubleshooting.
  3. Refer to the API Reference for detailed configuration options.