Two Levels of Customization
There are two levels depending on what you need:Database Only
Customize
add() and sample() for different parent selection or storage logicDatabase + Controller
Override
run_discovery() for cross-iteration behavior like stagnation response or acceptance gatingLevel 1: Database Only
SubclassProgramDatabase and implement two abstract methods. The default controller runs the loop unchanged.
Complete Implementation Example
Here’s the full implementation of TopK search (56 lines):skydiscover/search/topk/database.py
Key Points
What add() must do
What add() must do
- Store the program:
self.programs[program.id] = program - Update iteration tracking:
self.last_iteration = max(self.last_iteration, iteration) - Persist to disk:
self._save_program(program)(ifconfig.db_pathis set) - Call
self._update_best_program(program)— required for tracking global best
What sample() must return
What sample() must return
Returns
(parent, context_programs) where:parentis a singleProgramto mutatecontext_programsis aList[Program]shown as examples to the LLM
({"island_3": parent}, {"top_performers": context_programs})
Inherited helper methods
Inherited helper methods
self.programs—dict[str, Program]storing all programsself._update_best_program(program)— updates global best (call inadd())self._save_program(program)— persists to diskself.get_top_programs(n)— returns top N by scoreself.get_best_program()— returns highest-scoring program
Program Dataclass
Every program has these fields:Registration
Add your algorithm toskydiscover/search/route.py:
route.py
--search my_algo works:
Simple algorithms at this level:
topk/ (56 lines), best_of_n/ (85 lines), beam_search/ (527 lines)Level 2: Database + Controller
Use this when you need behavior that spans across iterations:- Tracking improvement history
- Reacting to stagnation
- Filtering results before they enter the population
- Multi-island search with migration
- Acceptance gating
_run_iteration(), which runs the full sample → prompt → LLM → evaluate cycle, then decide what to do with the result.
Controller Template
Controller Primitives
async
Runs the full
sample → prompt → LLM → evaluate cycle for one iteration. Returns SerializableResult.method
Stores result to database, logs metrics, and triggers checkpoint callback.
method
Returns the best program seen so far.
property
Returns
True when graceful shutdown is requested.SerializableResult Fields
Registration
Register both database and controller:route.py
Complex algorithms at this level:
adaevolve/ (multi-island UCB search), gepa_native/ (acceptance gating + merge), evox/ (co-evolves the search algorithm itself)Custom Configuration
If your algorithm has custom settings, add a dataclass inskydiscover/config.py:
config.py
config.py
config.yaml:
config.yaml
Complete Reference
ProgramDatabase API
DiscoveryController API
Complete Registration Example
route.py
Next Steps
Custom Benchmarks
Add your own optimization tasks
Context Builders
Customize prompt generation