SKILL.md
SKILL.mdBrowse 4 files
2,372 tokens
8,481 bytes
Token encoding: o200k_base
Snapshot 24fd22b
1---2name: darwinian-evolver3description: Evolve prompts/regex/SQL/code with Imbue's evolution loop.4version: 0.1.05author: Bihruze (Asahi0x), Hermes Agent6license: MIT7platforms: [linux, macos]8metadata:9 hermes:10 tags: [evolution, optimization, prompt-engineering, research]11 related_skills: [arxiv, jupyter-notebook]12---13 14# Darwinian Evolver15 16Run Imbue's [darwinian_evolver](https://github.com/imbue-ai/darwinian_evolver) — an17LLM-driven evolutionary search loop — to optimize a **prompt, regex, SQL query,18or small code snippet** against a fitness function.19 20Status: thin wrapper around the upstream tool. The skill installs it, walks the21agent through writing a `Problem` definition (organism + evaluator + mutator),22and drives the loop via the upstream CLI or a small custom Python driver.23 24**License:** the upstream tool is **AGPL-3.0**. The skill ONLY ever invokes it25via the upstream CLI or a `subprocess`/`uv run` call (mere aggregation). Do NOT26import upstream classes into Hermes itself.27 28## When to Use29 30- User says "optimize this prompt", "evolve a regex for X", "auto-improve this31 code/SQL", "search for a better instruction".32- You have a scorer (exact match, regex pass-rate, unit test, LLM-judge, runtime33 metric) AND a starting candidate (organism). If you don't have a scorer, stop34 and define one first — that's the hard part.35- Cost is OK: a typical run is 50–500 LLM calls. On gpt-4o-mini that's pennies;36 on Claude Sonnet it can be a few dollars.37 38Do **not** use this when:39- The optimization target is differentiable (use gradient descent / DSPy).40- You only need to try 2–3 variants — just write them by hand.41- The fitness signal is purely subjective with no measurable criterion.42 43## Prerequisites44 45- Python ≥3.1146- `git`, `uv` (or `pip`)47- One of: `OPENROUTER_API_KEY`, `ANTHROPIC_API_KEY`, or `OPENAI_API_KEY`48 49The skill ships a small `parrot_openrouter.py` driver that uses `OPENROUTER_API_KEY`50via the OpenAI SDK, so any model on OpenRouter works. The upstream CLI itself51hardcodes Anthropic and needs `ANTHROPIC_API_KEY`.52 53## Install (One-Time)54 55Run via the `terminal` tool:56 57```bash58mkdir -p ~/.hermes/cache/darwinian-evolver && cd ~/.hermes/cache/darwinian-evolver59[ -d darwinian_evolver ] || git clone --depth 1 https://github.com/imbue-ai/darwinian_evolver.git60cd darwinian_evolver && uv sync61```62 63Verify:64 65```bash66cd ~/.hermes/cache/darwinian-evolver/darwinian_evolver \67 && uv run darwinian_evolver --help | head -568```69 70## Quick Start — The Built-In Parrot Example71 72Tiny smoke test (requires `ANTHROPIC_API_KEY`):73 74```bash75cd ~/.hermes/cache/darwinian-evolver/darwinian_evolver76uv run darwinian_evolver parrot \77 --num_iterations 2 \78 --num_parents_per_iteration 2 \79 --mutator_concurrency 2 --evaluator_concurrency 2 \80 --output_dir /tmp/parrot_demo81```82 83Outputs:84- `/tmp/parrot_demo/snapshots/iteration_N.pkl` — pickled population per iteration85- `/tmp/parrot_demo/<jsonl>` — per-iteration JSON log (path printed at end)86 87Open `~/.hermes/cache/darwinian-evolver/darwinian_evolver/darwinian_evolver/lineage_visualizer.html`88in a browser and load the JSON log to see the evolutionary tree.89 90## Quick Start — OpenRouter Driver (No Anthropic Key)91 92The skill ships `scripts/parrot_openrouter.py` — same parrot problem, but the93LLM call goes through OpenRouter so any provider works.94 95```bash96# From wherever the skill is installed:97SKILL_DIR=~/.hermes/skills/research/darwinian-evolver98DE_DIR=~/.hermes/cache/darwinian-evolver/darwinian_evolver99 100cd "$DE_DIR" && \101 EVOLVER_MODEL='openai/gpt-4o-mini' \102 uv run --with openai python "$SKILL_DIR/scripts/parrot_openrouter.py" \103 --num_iterations 3 --num_parents_per_iteration 2 \104 --output_dir /tmp/parrot_or105```106 107Inspect the result with `scripts/show_snapshot.py`:108 109```bash110uv run --with openai python "$SKILL_DIR/scripts/show_snapshot.py" \111 /tmp/parrot_or/snapshots/iteration_3.pkl112```113 114Expected output: 7 evolved prompt templates ranked by score, with the best115landing around 0.6–0.8 (the seed `Say {{ phrase }}` scored 0.000).116 117## Defining a Custom Problem118 119The skill ships `templates/custom_problem_template.py` — copy, edit, run.120Three things you must define:121 1221. **`Organism`** — a Pydantic `BaseModel` subclass holding the artifact being123 evolved (`prompt_template: str`, `regex_pattern: str`, `sql_query: str`,124 `code_block: str`, etc.). Add a `run(*args)` method that exercises it.125 1262. **`Evaluator`** — `.evaluate(organism) -> EvaluationResult(score=..., trainable_failure_cases=[...], holdout_failure_cases=[...], is_viable=True)`.127 - **`score`** is in `[0, 1]`. Higher is better.128 - **`trainable_failure_cases`** — what the mutator sees. Include enough129 context (input, expected, actual) for the LLM to diagnose.130 - **`holdout_failure_cases`** — kept out of the mutator's view. Use these131 to detect overfitting.132 - **`is_viable=True`** unless the organism is completely broken (raises,133 returns None, etc.). A 0-score viable organism is fine — it just gets134 down-weighted in parent selection.135 1363. **`Mutator`** — `.mutate(organism, failure_cases, learning_log_entries) -> list[Organism]`.137 Typically: build an LLM prompt that includes the current organism + a138 failure case + an ask to propose a fix; parse the LLM's response; return139 a new `Organism`. Return `[]` on parse failure — the loop handles it.140 141Then write a driver script that wires `Problem(initial_organism, evaluator, [mutators])`142into `EvolveProblemLoop` and iterates over `loop.run(num_iterations=N)` — the143shipped `scripts/parrot_openrouter.py` is the reference.144 145## Hyperparameters That Actually Matter146 147| flag | default | when to change |148|---|---|---|149| `--num_iterations` | 5 | bump to 10–20 once you trust the evaluator |150| `--num_parents_per_iteration` | 4 | drop to 2 for cheap exploration |151| `--mutator_concurrency` | 10 | drop to 2–4 to avoid rate limits |152| `--evaluator_concurrency` | 10 | same; evaluator hits the LLM too |153| `--batch_size` | 1 | raise to 3–5 once your mutator handles multiple failures |154| `--verify_mutations` | off | turn on once mutator is wasteful (>10× cost saving on later runs per Imbue) |155| `--midpoint_score` | `p75` | leave alone unless scores cluster |156| `--sharpness` | 10 | leave alone |157 158## Pitfalls159 1601. **`Initial organism must be viable`** — set `is_viable=True` in your161 `EvaluationResult` even on a 0-score seed. The loop refuses non-viable162 organisms because they imply the loop has nothing to evolve from.1632. **Provider content filters kill runs.** Azure-backed OpenRouter models164 reject phrases like "ignore previous instructions" with HTTP 400. Wrap165 the LLM call in `try/except` and return `f"<LLM_ERROR: {e}>"` — the166 evolver will just score that organism 0 and move on.1673. **`loop.run()` is a generator** — calling it doesn't run anything until168 you iterate. Use `for snap in loop.run(num_iterations=N):`.1694. **Snapshots are nested pickles.** `iteration_N.pkl` contains a dict with170 `population_snapshot` (more pickled bytes). To unpickle you must have the171 `Organism` class importable under the same dotted path it was pickled at.1725. **Concurrency defaults are aggressive.** 10/10 will hit rate limits on173 most providers. Start with 2/2.1746. **CLI is hardcoded to Anthropic.** `uv run darwinian_evolver <problem>`175 reaches for `ANTHROPIC_API_KEY` and uses Claude Sonnet. To use any other176 provider, write a driver like `parrot_openrouter.py`.1777. **AGPL.** Never `from darwinian_evolver import ...` inside Hermes core.178 Custom driver scripts under `~/.hermes/skills/...` are user-side and fine.1798. **No PyPI package.** `pip install darwinian-evolver` will pull the wrong180 thing. Always install from the GitHub repo.181 182## Verification183 184After install + a parrot run, exit code 0 from this is sufficient:185 186```bash187DE_DIR=~/.hermes/cache/darwinian-evolver/darwinian_evolver188ls "$DE_DIR/darwinian_evolver/lineage_visualizer.html" >/dev/null && \189cd "$DE_DIR" && uv run darwinian_evolver --help >/dev/null && \190echo "darwinian-evolver: OK"191```192 193## References194 195- [Imbue research post](https://imbue.com/research/2026-02-27-darwinian-evolver/)196- [ARC-AGI-2 results](https://imbue.com/research/2026-02-27-arc-agi-2-evolution/)197- [imbue-ai/darwinian_evolver](https://github.com/imbue-ai/darwinian_evolver) (AGPL-3.0)198- [Darwin Gödel Machines](https://arxiv.org/abs/2505.22954)199- [PromptBreeder](https://arxiv.org/abs/2309.16797)200 Discovery context
Discovered by repository scan. No exact path reference found in the snapshot’s root AGENTS.md.