AgentDescent¶
Gradient descent — but the parameters are agents. A parallel, asynchronous framework for self-evolving agents (skills, prompts, harnesses) where diffs are the gradients and the aggregator is the optimizer.
AgentDescent puts the deep-learning training stack on top of agents — data / tensor / pipeline parallelism, parameter servers, decoupled/asynchronous RL, partial rollout — applied to recursive self-improvement, where the "parameters" are a library of evolvable artifacts (skills, prompts, harness modules, verifiers) and the "gradients" are diffs carrying evidence cards.
The core observation
Serial RSI is bounded at 1 diff / T_iter. AgentDescent runs N workers in parallel and merges their diffs into a shared, versioned artifact library, targeting O(N / T_iter) improvement throughput.
The one place the analogy must break defines the whole system:
Gradients add, diffs do not
Aggregation is therefore not averaging but conflict resolution +
statistical acceptance + transactional commit. That merge is what
aggregator.py implements.
Start here¶
Have a dataset¶
That is the whole input.
from agentdescent import evolve_skill, openai_compatible
from agentdescent.dataloader import hf_rows
rows = hf_rows("hotpotqa/hotpot_qa", "validation", config="distractor", limit=40)
result = evolve_skill(rows, model=openai_compatible(model="deepseek-v4-flash"),
prompt="question", gold="answer", score="exact")
print(result.rendered) # the skill it learned
Run as written, that lifted held-out exact match from 0.167 to 0.583 and wrote "Respond with only the requested answer, omitting any extra explanation or restatement." — see Quickstart for the full measurement.
Have a directory¶
A skill folder, a folder of subagent definitions, or the agent's own code:
from agentdescent import evolve_skill_dir
from agentdescent.agents import claude_code, openai_compatible
result = evolve_skill_dir(
"~/.claude/skills/pdf-audit", rows,
agent=claude_code(extra_args=["--permission-mode", "acceptEdits"]),
reflect_with=openai_compatible(model="deepseek-v4-flash"),
prompt="question", gold="answer", score="contains")
result.write_to("~/.claude/skills/pdf-audit") # opt in; backs up first
Each rollout materialises the candidate into a throwaway workspace and a real agent reads the files off disk. See Quickstart — a directory.
Neither is a separate system: both build ordinary arguments and call
evolve(), which is where you go the moment you want more.
Where to go next¶
-
:material-download: Install and first run — start here
Install, then reproduce the central claim in seconds with no API key.
-
:material-rocket-launch: Quickstart — dataset to skill
One call, three decisions: your data, how to score it, which model. With the measured result of running it.
-
:material-folder-cog: Quickstart — a directory
A skill folder, an agent folder, or its code — evolved by an agent that reads the files.
-
:material-star-four-points: The
evolvemethodThe one entry point underneath. Every capability is a plug-in to one
evolve()parameter — this is the map, with an example per module. -
:material-lightbulb-on: Concepts
The why: the training↔RSI analogy, staleness, the aggregator as a discrete-space optimizer, the three long tails, governance.
-
:material-sitemap: Architecture
How the components fit together and how a diff travels from a worker to a committed change.
-
:material-view-grid-plus: Module map
Every module, what it is for, and a reading order for whatever you are doing.
-
:material-api: API reference
Every public name with its real signature — generated from the code, and tested against it.
-
:material-chart-box: Measured results
Every empirical claim with the setup that produced it — including the benchmarks where the honest answer is "nothing to learn here".
Building blocks (each plugs into evolve):
-
:material-connection: Agents & LLMs →
agent=Any
prompt -> textis a completion: Claude, GLM/OpenAI-compatible, a CLI coding agent, a callable, a stub. -
:material-file-tree: Strategies →
strategy=What the artifact is: one slot, a playbook, keyed categories, or a directory. The key space is the design decision.
-
:material-cog-sync: The aggregator →
aggregator_factory=The optimizer — tune the reference merge/acceptance pipeline, or swap in your own.
-
:material-vector-triangle: Parallelism →
parallel=Pluggable DP / TP methods, plus sampling for which rollout to spend and scheduling for when.
-
:material-source-branch-sync: Async →
asynchronous=TrueBarrier-free workers, a lag budget, and the staleness policies that keep it safe.
-
:material-shield-lock: Governance →
blast_radius=L2 skills merge freely, L1 harnesses are oracle-gated, L0 is frozen — and frozen paths for a directory.
The central analogy¶
| Model training | AgentDescent (parallel RSI) |
|---|---|
| parameter tensor θ | library of Evolvable artifacts |
| gradient g | Diff + EvidenceCard |
| parameter server | git-backed, version-vectored Ledger |
| optimizer step | Aggregator merge decision |
| per-param adaptive LR (Adam) | per-artifact Beta-posterior test |
| staleness / decoupled PPO | per-diff η + rebase re-verify |
| partial rollout | straggler detection (ResumeQueue; resume not implemented) |
| EMA (weight averaging) | stable/dev dual branch |
| training code (not self-modifiable) | L0 frozen layer |
30-second tour¶
pip install -e ".[dev]"
python -m examples.run_demo # RQ1: merge vs fork (synchronous DP)
python -m examples.run_async # FlashEvolve-style async + staleness policies
python -m examples.skill_dir_evolution # evolve a skill directory a real agent reads
python -m examples.rq2_staleness # RQ2: staleness tolerance sweep
pytest # the suite, no external services
Step by step: install and first run. Everything runnable, with the output each one produces: run everything.
No LLM or external service is required: the reference domain is a fully deterministic keyword-router skill, so the entire parallel loop runs in-process and is unit-tested — while still producing genuine diffs that measurably improve a held-out metric.
Scope
This is a research reference implementation, faithful to the design's mechanisms and runnable end-to-end on a synthetic domain — not a production system. See the design spec §2 for the honest, narrowed novelty claim relative to FlashEvolve / SkillClaw / CoEvoSkills.