Skip to content

Quickstart

Evolve a solution to the bundled circle_packing task (pack 26 circles in the unit square, maximize the sum of radii) with OpenEvolve.

Five lines

import galapagos as gx

model    = gx.GalapagosModel.from_card(name="openai/gpt-4o-mini", host="openrouter")
config   = gx.GalapagosConfig.from_config(scaffold_name="openevolve")
scaffold = gx.GalapagosScaffold.from_card(name="openevolve", config=config, model=model)
task     = gx.GalapagosTask.from_card(name="circle_packing")
result   = scaffold.run(task=task)

print(result.best_score, result.run_dir)

A run calls a real LLM, so set an OpenRouter API key first — Galapagos reads it from the OPENAI_API_KEY environment variable (see Installation):

export OPENAI_API_KEY=sk-or-...

scaffold.run(task=task) drives the evolutionary loop until the budget is hit and returns a RunResult:

Attribute What it gives you
result.best the best Genome found (its content is the solution).
result.best_score its fitness (combined_score), as a float.
result.summary a dict of run statistics — scaffold, task, iterations, evaluations, best_score, cost_usd, no_diff, population_size.
result.run_dir where the trajectory was saved (or None).
result.history every scored Genome, in evaluation order.

Override the budget at call time with run(task=task, max_iterations=100).

The direct scaffold form

Each runnable scaffold also exposes a typed entry point that loads its own card and default config, so you can skip the explicit GalapagosConfig step:

import galapagos as gx

model    = gx.GalapagosModel.from_card(name="openai/gpt-4o-mini", host="openrouter")
scaffold = gx.OpenEvolveScaffold.from_card(model=model)
result   = scaffold.run(task=gx.GalapagosTask.from_card(name="circle_packing"))

Load a local card by path

name= resolves a bundled card from the registry; path= loads a card from disk — the same form you use for a scaffold you wrote yourself or pulled from the Hub:

import galapagos as gx

model    = gx.GalapagosModel.from_card(name="openai/gpt-4o-mini", host="openrouter")
scaffold = gx.GalapagosScaffold.from_card(path="my_scaffolds/banditevolve/card.yaml", model=model)
result   = scaffold.run(task=gx.GalapagosTask.from_card(path="my_tasks/sphere/card.yaml"))

OpenEvolveScaffold.from_card(path=...) works the same way for the typed entry points.

Build your own from components

You can skip cards entirely and compose a scaffold from its six components. Each slot accepts a component instance, a "module.Class" dotted path, or a path to a .py file:

import galapagos as gx

model    = gx.GalapagosModel.from_card(name="openai/gpt-4o-mini", host="openrouter")
scaffold = gx.GalapagosScaffold.from_card(
    model=model,
    population="galapagos.components.population.IslandPopulation",
    selection_policy="galapagos.components.selection.ExploreExploitPolicy",
    prompt_builder="galapagos.components.prompt.DefaultPromptBuilder",
    proposer="galapagos.components.proposer.DiffProposer",
    memory="my_components/scratchpad.py",          # a .py file you wrote
)
result = scaffold.run(task=gx.GalapagosTask.from_card(name="circle_packing"))

The evaluator slot is supplied by the task, not the scaffold — an omitted component simply is not used. See Write your own scaffold for the full component contract.

A short, cheap first run

Every run calls a live LLM and spends budget. Keep the first one small by capping the iteration count inline and starting on the tiny playground_sphere task:

import galapagos as gx

model    = gx.GalapagosModel.from_card(name="openai/gpt-4o-mini", host="openrouter")
config   = gx.GalapagosConfig.from_config(scaffold_name="openevolve")
scaffold = gx.GalapagosScaffold.from_card(name="openevolve", config=config, model=model)
task     = gx.GalapagosTask.from_card(name="playground_sphere")
result   = scaffold.run(task=task, max_iterations=20)

print(result.best_score)

Tune the configuration

GalapagosConfig uses dotted paths via .get / .set (which returns the config, so you can chain):

config = (gx.GalapagosConfig.from_config(scaffold_name="openevolve")
          .set("budget.max_iterations", 100)
          .set("budget.max_usd", 5.0))          # hard cost ceiling

print(config.get("budget.max_iterations"))      # 100

Other budget keys: target_score, patience, wallclock_s. See Cards for the full defaults_config of each scaffold.

Functional aliases

Every *.from_card constructor has a short functional alias:

import galapagos as gx

model    = gx.load_model("openai/gpt-5.5", host="openrouter")
config   = gx.load_config("openevolve")
scaffold = gx.load_scaffold("openevolve", config=config, model=model)
task     = gx.load_task("circle_packing")
result   = scaffold.run(task=task)

From the command line

The galapagos console script mirrors the Python API. --model is required, and the run reads your OpenRouter key from OPENAI_API_KEY:

# run a scaffold on a task (20 iterations)
galapagos run --scaffold openevolve --task circle_packing \
    --model openai/gpt-4o-mini --host openrouter --iters 20

# inspect the catalog
galapagos scaffold list
galapagos task list

See CLI commands for every command, flag, and example output.

Next: understand the Concepts, or jump to a Guide.