I Gave My AI Two Evolution Engines, and It Evolved Itself Through 20 Rounds
Anyone who has shipped a real project with AI agents knows the pain: the agent “gets dumber” over time.
It’s not that the model is degrading — it’s that skills are static. The SKILL.md you painstakingly wrote may work well the first time, but as usage scenarios shift and edge cases pile up, it gradually falls behind. Worse, you have to maintain these skills by hand: spot the problem, revise the instructions, verify, deploy — one round of that is more exhausting than writing the code yourself.
So I installed two evolution engines for it: one governs how the skills themselves get optimized (evolution-driver, built in-house), and the other governs how task workflows run better (PRAXIST, open source). The two complement each other without overlapping. Then I discovered something: they were set up — but not actually used yet.
1. The Problem: Why Do AI Agents Need to “Evolve”?
Static skills have three hard flaws.
High maintenance cost. Writing a SKILL.md may take half an hour, but maintaining it is a bottomless pit. I have a blog-writing skill that I’ve used since 2024 and modified no fewer than 20 times; every time I spot a new AI writing tell (like mechanically stacked parallel sentences), I have to add rules, revise the process, and run tests by hand.
Broken feedback loop. Once a skill finishes running, that’s it — there’s no mechanism to automatically collect “what went wrong.” When a user says “this piece isn’t well written,” you have to figure out which step failed on your own, then improve it manually.
No scalability. One skill is manageable, but once you have 10 or 20 of them, manual maintenance becomes a nightmare. I have 11 PRAXIST-related skills — if each needed a human watcher, they wouldn’t be worth using.
2. How the Two Engines Divide the Work
| Component | Source | What It Governs | Prerequisites |
|---|---|---|---|
| evolution-driver | Built in-house from a paper | SKILL.md skill evolution (agent-driven seven-step loop) | None |
| PRAXIST | GitHub open source | Measurable task optimization | Project already runs + goal is measurable |
evolution-driver sharpens the axe; PRAXIST chops the wood.
3. evolution-driver: Skill Self-Evolution
Paper Origin and Why I Built It Myself
evolution-driver draws its inspiration from academic research on “agent self-improvement,” but with substantial simplification for real-world use. The core idea: let the agent find its own blind spots, fix defects, and verify — until preset acceptance criteria are met.
The Seven-Step Loop
Each evolution round (Fast Loop) has 7 steps: first scan real usage scenarios for underperforming samples (gather evidence), analyze root causes to decide what this round will fix (set targets), run the skill on real samples and log defects (live testing), design fixes with multi-model cross-review — K3 for design plus GLM for implementation (fix), then pass a gate check after the fix (integration), run a shadow run to confirm nothing existing broke (verification), and finally check whether acceptance criteria are met: detect_rate ≥ 0.9, min_fixed ≥ 3 (the gate). Every H=5 rounds there’s also a Slow Loop meta-review that evolves “the evolution method itself.”
Gate Design: Fail-Closed, Anti-Bootstrapping
The gate is the safety floor of the evolution system. I designed a fail-closed authorization registry:
1 | # ~/.dimcode/v2/skills/.evolution-registry.yml |
Key design points: opt-in — unregistered skills are always denied evolution, with evolvable defaulting to false; anti-bootstrapping — evolution-driver itself is marked evolvable: false to prevent it from editing itself into an infinite loop; dual-source strictness — if either the registry config or the skill directory’s config.json fails a condition, the request is denied.
The implementation (core logic of the G1 permission gate):
1 | # access_check.py excerpt |
Acceptance Criteria
Evolution is not an infinite loop. config.json defines hard acceptance:
1 | { |
detect_rate ≥ 0.9 means the skill can surface more than 90% of known problems; min_fixed ≥ 3 means at least 3 defects get fixed per round.
4. PRAXIST: Measurable Task Optimization
The Open Source Project
PRAXIST comes from github.com/sapientinc/PRAXIST, an autonomous research system (arXiv 2608.25955). The Python core is roughly 295k lines, plus a substantial amount of Rust. Given a runnable project and a measurable goal, PRAXIST attempts optimization automatically until the target is hit.
Installation and Configuration
Install into an isolated venv so the system Python stays clean:
1 | # Create the venv |
Configure the provider (using DeepSeek):
1 | # ~/.config/praxist/env |
Install Status Check
praxist doctor output (real state):
1 | Praxist doctor |
Every warn in the doctor output is a known non-issue: PRAXIST_MODEL falls back to the provider default, registry_dir is uninitialized (no real run has been executed), and codex_skills resolve through the DimAgent plugin path so no separate installation is needed.
How the Agent Collaborates with PRAXIST
PRAXIST ships its own detached Python runtime; the agent is just the operator console. Core commands:
1 | # Take over project optimization |
PRAXIST’s scheduling is automatic: parallel peers, generational synthesis, evidence lanes — the agent never needs to touch the underlying pipeline.
5. Shipping It: The Plugin-Based auto-evolve
Packaged as a Local Marketplace
I packaged PRAXIST and evolution-driver into a DimAgent plugin called auto-evolve:
1 | ~/Documents/技能开源/auto-evolve/ |
One-Command Install
1 | # 1. Register the local marketplace |
Porting Acceptance
evolution-driver passed its porting acceptance (executed by a sub-agent with acceptance in the main session): 50 files, G1 gate swapped to access_check_dim.py, data source at ~/.dimcode/v2/skills/.evolution-registry.yml, fail-closed design, evolvable denied by default, with the registry pre-registering evolution-driver itself as evolvable: false to prevent bootstrapping; G1/G3/G9 smoke tests all passed.
6. Real Runs: evolution-driver Evolving Itself
evolution-driver hasn’t just run — it has evolved itself.
In the dsh environment, it ran 20 evolution rounds, optimizing itself and 8 other skills (bianque, cangjie, db-design-spec, genui, huatuo, search, shiqu, yushi). From the round-log.jsonl records:
Round 1 (bootstrap evolution): three models cross-audited evolution-driver itself and found 7 major defects — a timing deadlock, a size limit with zero implementation, criteria drift, the tally counting negative contributions on the wrong row, Slow Loop ratchet rollback touching the wrong file, hard anchors not being expanded, and a meta-review vocabulary mismatch.
Round 13 (a real Fast Loop): web_search gathered real samples, 8 patterns were targeted (G1-G8), live testing measured detect_rate at just 0.5, exposing real blind spots — missing permission tiering, missing feedback closure, execution drift rate, and data source credibility.
Rounds 14-16: K3 design plus GLM implemented fixes for 4 blind spots in parallel, moving detect_rate from 0.5 → 0.625 → 0.875 → 1.0.
Rounds 17-20 (integration safety): F1 functional baseline check, F2 feedback closure, F3 config key validation, F4 backup mechanism, F5 functional behavior gate. Overall went 69.2 → 76.9 → 84.6 → 92.3.
Final state: overall 92.3, failed 0, 26+ defects fixed cumulatively.
PRAXIST: installed and configured (Python 3.12 venv + DeepSeek key), but there are no run logs — it has never actually been used to optimize a project. That’s the outstanding risk.
7. Pitfalls and Lessons
Field-Tested Facts About the Plugin Mechanism
install copies from a snapshot: after editing plugin sources you must run dim plugin marketplace upgrade auto-evolve to refresh the snapshot before reinstalling; editing sources and reinstalling directly does nothing. Same-name conflicts block installation; skills are discovered from the plugin’s skills/ directory and don’t occupy ~/.dimcode/v2/skills/, but name conflicts still apply. There is no plugin-level remove CLI — “reinstall” means moving the old directory aside and installing again.
What Upgrades Throw Away
A DimAgent upgrade drops PyYAML from the runtime Python, so setup.sh must be re-run. After a praxist upgrade, the official skills update inside the pip package and must be re-copied from the venv’s site-packages/praxist/resources/skills/ into the plugin package. If the venv is deleted, rebuild it with uv venv.
8. Summary and Outlook
The Value of Two Engines
evolution-driver makes skills improve themselves with no human babysitter, and the gate design (fail-closed, opt-in, anti-bootstrapping) is the safety floor. PRAXIST automates optimization for measurable tasks, with the agent as a mere console. The two complement each other: evolution-driver sharpens the axe; PRAXIST chops the wood.
Next Steps
A real-run validation: run a genuine research project through the full pipeline to verify the framework works in practice. Memory-system skill sharing: register PRAXIST/evolution-driver as unified skills in the memory system so every harness can call them directly (current status: proposed, not yet shipped).
Advice for Readers
If you want your AI agent to get better with use, ask yourself two questions first. Do your skills have explicit acceptance criteria? Without them, the evolution engine doesn’t know what “good” means. Are your tasks measurable? PRAXIST can’t help with unmeasurable tasks. If both answers are “yes,” the evolution engines may be worth a try.
All material in this post comes from real artifacts: config files, command output, and code snippets are actual runtime results — no fabrication or staging for the sake of formatting.
Related posts: For how skill self-evolution applies to the content production line, see The Blog Production Line (Part 3): Six Automated Pre-Publish Checks (Chinese); for the full version of multi-model division of labor, see A Frontline Writer’s Real Workflow, Distilled into Four Patterns (Chinese).
