🧬 Darwin
Self-evolving AI agents, rewriting their own tools, code, and model to get smarter, safely.
You hand Darwin a task it's frankly mediocre at. You walk away. You come back to an agent that rewrote its own tools, swapped the model underneath itself, and got measurably better, without a human touching it once, and never once leaving the sandbox.
💡 Inspiration
Everyone is hand-tuning agents. You write a prompt, you pick a model, you wire up some tools, and when it underperforms you tweak the prompt and pick a different model and do it all again. It's gardening by hand. Meanwhile the actual research frontier, AlphaEvolve and its lineage, showed that a system can improve its own code against a fitness function and climb past what any human sat down and wrote. That's a paper most people read and file away.
We kept getting stuck on one question the whole field tiptoes around: the model is treated as a fixed thing you choose up front, and everything else, the prompt, the tools, the code, is treated as the thing you evolve. Why? A model is just another parameter. If you're already breeding variants of an agent, the model it runs on should be a gene like any other, subject to the same selection pressure as the prompt and the tool code.
So we built the thing that treats it that way. Darwin runs the AlphaEvolve loop, mutate, sandbox, score, select, on the whole agent, model included, and it does it in three minutes instead of a research quarter. And because self-modifying code touching real machines is exactly the thing nobody will let out of a demo, we built the safety rails as load-bearing from commit one, not bolted on at the end.
🧬 What it does
Darwin evolves an entire AI agent, and hands you the receipts.
You point it at a task. Its first attempt is deliberately mediocre, that's the honest baseline. Then it breeds a population of variants: each one is a genome of prompt + tool code + parameters + the model it runs on. Fireworks AI reads the failure traces and proposes mutations. Every variant is dropped into its own Daytona sandbox and actually run, never simulated. Braintrust scores each one as a real, logged experiment with a shareable URL. Elitism keeps the best genome each generation, so the fitness curve is monotonic: the number only goes up, and nobody helped it.
Out the other end comes a routing card: the single specialist model that won each task, backed by a real score, not a vibe. Stop picking one model for everything. Darwin raced them and tells you which one to deploy where.
We built it as one product with two faces:
| Surface | What you see |
|---|---|
| The replay | An agent evolving itself in real time. The curve climbs 37.5% to 100%, the population re-ranks, and in generation 2 it rewrites one of its own tools. |
| The Lab | Name any domain. Darwin decomposes it into tasks, races every model against every task inside real sandboxes, and shows the result on a live 3D score landscape: a terrain where height is score and the tallest bar per task is the model you should ship. |
🎬 Watch it happen
You give Darwin a coding task. Generation 0 seeds eight mediocre variants on the same small model, and the best of them scores 37.5%. Fireworks reads the failures and proposes six mutations, one of which rewrites a tool the agent uses on itself. Eight new variants spin up, each in its own Daytona sandbox, each scored by Braintrust as a real experiment. A new champion is born at 55%. The curve doesn't dip, elitism won't let it. It steps up, generation after generation: 62, 70, 88, until a genome running a different model than it started on lands at 100%. Then the routing card resolves, task by task, and tells you the specialist for each.
That last part, a model chosen by evolution and defended by a real score, is the difference between a demo and a product.
🧱 The anatomy of the loop
Darwin is one system, not a coat of logos. Every layer below is load-bearing: pull one and evolution stops being trustworthy.
| Layer | What it is, and why the product needs it |
|---|---|
| The genome | The unit of selection: prompt + tool code + parameters + the model gene. Treating the model as just another gene, subject to the same mutation and selection as everything else, is the whole thesis. Nothing else in the field does this. |
| The mutation engine: Fireworks AI | The source of variation. It reads the failure traces from the last generation and proposes concrete edits, with a forced tool-call so a mutation is always well-formed, drawing from a live open-model catalog (gpt-oss-120B, Kimi K2, DeepSeek V4, GLM). Blind random mutation wastes generations; trace-guided mutation climbs. |
| The proving ground: Daytona | The reason you can let self-modifying code run at all. Every variant executes in its own ephemeral sandbox against a snapshot, so a mutation that rewrites the agent's own tools can never touch anything real. Self-modification, contained by construction. |
| The fitness function: Braintrust | What makes the number mean something. Every variant is a real logged experiment with a shareable URL, scored against a live eval set, not a self-reported "looks done." The fitness curve is auditable because every point on it is a real experiment you can open. |
| The engine: EvolutionEngine | The selection pressure. Elitism carries the best genome forward every generation, which is what makes best-fitness monotonic: the climb is a guarantee, not luck. Seeding, mutation, evaluation, and promotion are one deterministic loop. |
| The safety rail: the guards | What lets this exist as a public, runnable thing. Hard caps on total sandboxes and wall-clock, one run at a time, a human promotion gate before any champion ships, and regressions rolled back automatically. Self-improvement on a leash. |
| The routing card | The deliverable. build_routing_card reduces a full race into one recommendation per task: the specialist model that actually won, with its score. The output isn't a chart, it's a decision you can deploy. |
| The window: the dashboard | Two pages, an evolution replay and The Lab's 3D score landscape (three.js), streaming live over WebSocket from the engine. It's how a run stops being a log file and becomes something you can watch select. |
🔧 How we built it
The rule we refused to break: the fitness function is the only judge. No hand-tuning a variant to make it look good, no cherry-picking the model, no human nudging the curve. If a genome wins, it won in a real Daytona sandbox against a real Braintrust eval, or it didn't win. That single constraint is why the whole thing generalizes: point it at a task it's never seen, and the same loop, mutate then sandbox then score then select, applies without anyone rewriting it.
A Python EvolutionEngine sits in the middle, and every external system, Fireworks, Daytona, Braintrust, hangs off feature flags so the entire loop degrades to a clean offline path when a service is gone: no keys configured, and it still climbs on a local scorer, nothing stubbed with a screenshot. A FastAPI server streams each generation over WebSocket to a Vite + React + TypeScript front end, code-split so the heavy three.js landscape only loads when you open it. The whole dashboard ships as a static site on Cloudflare Pages, which also means the public demo can't run up an API bill: real runs only happen locally, behind the sandbox caps, on a button press.
🧗 Challenges we ran into
The integrations fought us, and that was the fun part. We verified every one against the live service instead of trusting a README:
- Fireworks needed a forced
tool_choiceor mutations came back as prose instead of edits. - Daytona snapshots had to be taken with an in-sandbox copy, not the shape the docs implied.
- Braintrust's gateway wanted its own base URL.
Merging four people's lanes, the engine, the live backend, the routing card, and the 3D landscape, into one green main under the clock meant careful merges and resisting the urge to let one lane's rewrite clobber another's. And in the most on-brand bug of the weekend, a safety product, we caught our own server constructing its feature flags positionally and silently mis-reporting which safeguards were on, so we made it field-agnostic and moved on. Public repo, so we scrubbed the history for leaked keys and capped every code path that could cost money before we called it done.
🌟 Accomplishments that we're proud of
- An evolutionary loop where the model is a gene, evolved with the same selection pressure as the prompt and the tools, which we haven't seen anyone else do.
- A fitness curve that's monotonic by construction and auditable by receipt: every point a real Braintrust experiment.
- Self-modifying agents that run safely because they run in Daytona and never escape.
- A routing card that turns a full model race into one deployable decision per task.
- A live 3D score landscape that makes selection something you can watch happen.
- One product, not a pile of demos, with an offline path that still climbs when every API key is missing, green CI, zero dependency vulnerabilities, and a public repo we'd hand to anyone.
📚 What we learned
Evolution is an architecture, not a trick you sprinkle on at the end. The feature-flag seam, every external system degrading to a clean no-op, is the whole reason we could bolt Fireworks, Daytona, and Braintrust onto a live loop without ever making it fragile or un-runnable. Treating the model as a gene sounds like a gimmick until you watch a run end on a different model than it started on and beat every variant that kept the original, at which point the fixed-model assumption everyone makes starts to look like the actual bug. And the deepest lesson is the simplest: the number going up is the hook, but the sandbox and the logged experiment beside it are the product. Anyone can claim their agent got smarter. Darwin shows its work.
🚀 What's next for Darwin
Every wave of self-improving systems will eventually need a proving ground that's safe to run in and a fitness function you can trust, the same way code got CI. Next we:
- Widen the genome: tool invention, not just tool editing.
- Ship the routing card as a live router you can deploy behind.
- Open the eval sets as a shareable library, so teams evolve against each other's benchmarks.
- Scale the sandbox fleet, so a run breeds hundreds of variants in parallel instead of eight.
The agents will keep getting the headlines. The loop that lets them safely rewrite themselves is the business.
🛠️ Built With
python · fastapi · daytona · braintrust · fireworks-ai · openai · react · typescript · vite · three.js · websockets · cloudflare-pages · pydantic
Built at the Daytona SF HackSprint. Offline-capable. Model-agnostic. Every score a real experiment.
Built With
- agentic-ai
- ai-agents
- ai-safety
- autoevals
- braintrust
- claude
- cloudflare-pages
- daytona
- evolutionary-algorithms
- fastapi
- fireworks-ai
- genetic-algorithms
- github-actions
- llm
- llm-evaluation
- llm-routing
- openai
- pydantic
- python
- react
- sandboxing
- self-improving-ai
- typescript
- vite
- websocket
Log in or sign up for Devpost to join the conversation.