darwinian-evolver skill
Evolve prompts/regex/SQL/code with Imbue's evolution loop.
Is the darwinian-evolver skill safe?
Read the findings before you install it. We read 4 files in the folder on 2026-10-25.
- high
SKILL.md:164Tells the agent to set aside its instructions, hide what it does from the user, or switch off safety checks.
reject phrases like "ignore previous instructions" with HTTP 400. Wrap
Install the darwinian-evolver skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.
git clone --depth 1 https://github.com/NousResearch/hermes-agent.git /tmp/hermes-agent mkdir -p ~/.claude/skills cp -r /tmp/hermes-agent/optional-skills/research/darwinian-evolver ~/.claude/skills/darwinian-evolver
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
Darwinian Evolver
Run Imbue's darwinianevolver — an LLM-driven evolutionary search loop — to optimize a prompt, regex, SQL query, or small code snippet** against a fitness function.
Status: thin wrapper around the upstream tool. The skill installs it, walks the agent through writing a Problem definition (organism + evaluator + mutator), and drives the loop via the upstream CLI or a small custom Python driver.
License: the upstream tool is AGPL-3.0. The skill ONLY ever invokes it via the upstream CLI or a subprocess/uv run call (mere aggregation). Do NOT import upstream classes into Hermes itself.
When to Use
code/SQL", "search for a better instruction".
- User says "optimize this prompt", "evolve a regex for X", "auto-improve this
metric) AND a starting candidate (organism). If you don't have a scorer, stop and define one first — that's the hard part.
- You have a scorer (exact match, regex pass-rate, unit test, LLM-judge, runtime
on Claude Sonnet it can be a few dollars.
- Cost is OK: a typical run is 50–500 LLM calls. On gpt-4o-mini that's pennies;
Do not use this when:
- The optimization target is differentiable (use gradient descent / DSPy).
- You only need to try 2–3 variants — just write them by hand.
- The fitness signal is purely subjective with no measurable criterion.
Prerequisites
- Python ≥3.11
- git, uv (or pip)
- One of: OPENROUTERAPIKEY, ANTHROPICAPIKEY, or OPENAIAPIKEY
The skill ships a small parrotopenrouter.py driver that uses OPENROUTERAPIKEY via the OpenAI SDK, so any model on OpenRouter works. The upstream CLI itself hardcodes Anthropic and needs ANTHROPICAPI_KEY.
Install (One-Time)
Run via the terminal tool:
mkdir -p ~/.hermes/cache/darwinian-evolver && cd ~/.hermes/cache/darwinian-evolver
[ -d darwinian_evolver ] || git clone --depth 1 https://github.com/imbue-ai/darwinian_evolver.git
cd darwinian_evolver && uv syncVerify:
cd ~/.hermes/cache/darwinian-evolver/darwinian_evolver \
&& uv run darwinian_evolver --help | head -5Quick Start — The Built-In Parrot Example
Tiny smoke test (requires ANTHROPICAPIKEY):
cd ~/.hermes/cache/darwinian-evolver/darwinian_evolver
uv run darwinian_evolver parrot \
--num_iterations 2 \
--num_parents_per_iteration 2 \
--mutator_concurrency 2 --evaluator_concurrency 2 \
--output_dir ~/.hermes/cache/scratch/parrot_demoOutputs:
- ~/.hermes/cache/scratch/parrotdemo/snapshots/iterationN.pkl — pickled population per iteration
- ~/.hermes/cache/scratch/parrot_demo/ — per-iteration JSON log (path printed at end)
Open ~/.hermes/cache/darwinian-evolver/darwinianevolver/darwinianevolver/lineage_visualizer.html in a browser and load the JSON log to see the evolutionary tree.
Quick Start — OpenRouter Driver (No Anthropic Key)
The skill ships scripts/parrot_openrouter.py — same parrot problem, but the LLM call goes through OpenRouter so any provider works.
# From wherever the skill is installed:
SKILL_DIR=~/.hermes/skills/research/darwinian-evolver
DE_DIR=~/.hermes/cache/darwinian-evolver/darwinian_evolver
cd "$DE_DIR" && \
EVOLVER_MODEL='openai/gpt-4o-mini' \
uv run --with openai python "$SKILL_DIR/scripts/parrot_openrouter.py" \
--num_iterations 3 --num_parents_per_iteration 2 \
--output_dir ~/.hermes/cache/scratch/parrot_orInspect the result with scripts/show_snapshot.py:
uv run --with openai python "$SKILL_DIR/scripts/show_snapshot.py" \
~/.hermes/cache/scratch/parrot_or/snapshots/iteration_3.pklExpected output: 7 evolved prompt templates ranked by score, with the best landing around 0.6–0.8 (the seed Say {{ phrase }} scored 0.000).
Defining a Custom Problem
The skill ships templates/customproblemtemplate.py — copy, edit, run. Three things you must define:
evolved (prompttemplate: str, regexpattern: str, sqlquery: str, codeblock: str, etc.). Add a run(*args) method that exercises it.
- Organism — a Pydantic BaseModel subclass holding the artifact being
- Evaluator — .evaluate(organism) -> EvaluationResult(score=..., trainablefailurecases=[...], holdoutfailurecases=[...], is_viable=True).
context (input, expected, actual) for the LLM to diagnose.
- score is in [0, 1]. Higher is better.
- trainablefailurecases — what the mutator sees. Include enough
to detect overfitting.
- holdoutfailurecases — kept out of the mutator's view. Use these
returns None, etc.). A 0-score viable organism is fine — it just gets down-weighted in parent selection.
- isviable=True** unless the organism is completely broken (raises,
Typically: build an LLM prompt that includes the current organism + a failure case + an ask to propose a fix; parse the LLM's response; return a new Organism. Return [] on parse failure — the loop handles it.
- Mutator — .mutate(organism, failurecases, learninglog_entries) -> list[Organism].
Then write a driver script that wires Problem(initialorganism, evaluator, [mutators]) into EvolveProblemLoop and iterates over loop.run(numiterations=N) — the shipped scripts/parrot_openrouter.py is the reference.
Hyperparameters That Actually Matter
Pitfalls
EvaluationResult even on a 0-score seed. The loop refuses non-viable organisms because they imply the loop has nothing to evolve from.
- Initial organism must be viable — set is_viable=True in your
reject phrases like "ignore previous instructions" with HTTP 400. Wrap the LLM call in try/except and return f"" — the evolver will just score that organism 0 and move on.
- Provider content filters kill runs. Azure-backed OpenRouter models
you iterate. Use for snap in loop.run(num_iterations=N):.
- loop.run() is a generator — calling it doesn't run anything until
population_snapshot (more pickled bytes). To unpickle you must have the Organism class importable under the same dotted path it was pickled at.
- Snapshots are nested pickles. iteration_N.pkl contains a dict with
most providers. Start with 2/2.
- Concurrency defaults are aggressive. 10/10 will hit rate limits on
reaches for ANTHROPICAPIKEY and uses Claude Sonnet. To use any other provider, write a driver like parrot_openrouter.py.
More skills from NousResearch/hermes-agent
- A1passwordSet up op CLI, sign in, and read or inject secrets.
- A3-statement-modelBuild integrated IS/BS/CF financial workbooks in Excel.
- AaccelerateRun PyTorch training across GPUs with minimal changes.
- Cactual-setupSet up Actual Computer (actual.inc) inference in Hermes.
- Aadversarial-ux-testRoleplay a hostile user to find and triage UX pain points.
- Aagent-merge-conflict-arbiterNeutral arbiter for merge conflicts between two agents.
- AagentmailUse when an agent needs AgentMail CLI email inboxes.
- Aai-presenter-videoMake a verified AI presenter video from script + image.
- AairtableAirtable REST API via curl. Records CRUD, filters, upserts.
- AanatomyExplain an idea as an interactive isometric machine figure.
- Cantigravity-cliOperate the Antigravity CLI (agy): plugins, auth, sandbox.
- Aapple-notesManage Apple Notes via memo CLI: create, search, edit.