<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eran Raichstein</title>
    <description>The latest articles on DEV Community by Eran Raichstein (@eranra).</description>
    <link>https://dev.to/eranra</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4047722%2Fd217108c-8edd-4385-9992-790cf546934c.jpg</url>
      <title>DEV Community: Eran Raichstein</title>
      <link>https://dev.to/eranra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eranra"/>
    <language>en</language>
    <item>
      <title>CapEvolve: Optimize agentic capabilities - with agents</title>
      <dc:creator>Eran Raichstein</dc:creator>
      <pubDate>Sun, 26 Jul 2026 09:48:24 +0000</pubDate>
      <link>https://dev.to/eranra/optimize-agentic-capabilities-with-agents-3n7j</link>
      <guid>https://dev.to/eranra/optimize-agentic-capabilities-with-agents-3n7j</guid>
      <description>&lt;p&gt;We built a loop that edits an AI agent's tools, prompts, MCP surfaces, and skill packages. Then we let the agent drive the loop itself. Here's what happened.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://github.com/skillberry-ai/cap-evolve" rel="noopener noreferrer"&gt;⭐ Every GitHub star helps. Thank you! ❤️&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;There's a class of agent failure that prompt-tuning alone doesn't fix.&lt;/p&gt;

&lt;p&gt;The agent &lt;em&gt;understands&lt;/em&gt; the policy. It can quote the rule back at you. But it fails on the same task patterns anyway — because the failure isn't a knowledge gap, it's structural. A constraint enforced in tool code &lt;strong&gt;can't be forgotten mid-conversation&lt;/strong&gt;. A validation guard at the tool boundary catches a booking error before the model can reason around it. A composite tool that hard-wires a multi-step workflow removes the opportunity to drop a step.&lt;/p&gt;

&lt;p&gt;And these failures are only visible in the full trajectory: you have to read what the agent actually did across every task, cluster the failure modes, figure out which prior edits broke what was working, propose a fix that addresses every cluster without regressions — and repeat across dozens of iterations.&lt;/p&gt;

&lt;p&gt;This shows up on real benchmarks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/sierra-research/tau2-bench" rel="noopener noreferrer"&gt;τ²-bench&lt;/a&gt;&lt;/strong&gt; — tool-calling agents in customer service domains (airline booking, retail)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/SWE-bench/SWE-bench" rel="noopener noreferrer"&gt;SWE-bench&lt;/a&gt;&lt;/strong&gt; — coding agents resolving real GitHub issues, graded by whether the test suite passes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://arxiv.org/abs/2602.12670" rel="noopener noreferrer"&gt;SkillsBench&lt;/a&gt;&lt;/strong&gt; — agents running from procedural skill packages, tested across 84 real-world tasks with deterministic verifiers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bottleneck in all three is the same: the iteration loop — evaluate, diagnose, edit, gate, repeat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/skillberry-ai/cap-evolve" rel="noopener noreferrer"&gt;cap-evolve&lt;/a&gt; is that loop.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;cap-evolve runs an &lt;a href="https://skillberry-ai.github.io/cap-evolve/architecture.html#phases" rel="noopener noreferrer"&gt;outer optimization loop&lt;/a&gt; over an AI agent's &lt;strong&gt;capabilities&lt;/strong&gt; — the things the agent reads and executes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System prompts&lt;/li&gt;
&lt;li&gt;Executable tool code&lt;/li&gt;
&lt;li&gt;MCP tool surfaces (docs, examples, exposed tools)&lt;/li&gt;
&lt;li&gt;Skill packages (&lt;code&gt;SKILL.md&lt;/code&gt; bodies, references, scripts)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It works across domains: tool-calling agents (τ²-bench), coding agents that patch real GitHub issues (SWE-bench), and agents that run from procedural skill packages (SkillsBench). &lt;a href="https://skillberry-ai.github.io/cap-evolve/adapter-templates.html" rel="noopener noreferrer"&gt;Adapter templates for all three&lt;/a&gt; ship in the repo.&lt;/p&gt;

&lt;p&gt;You bring the agent and an eval you already have. Each iteration:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Evaluate&lt;/strong&gt; the current best candidate on a train/val split&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagnose&lt;/strong&gt; — read the full trajectories (successes &lt;em&gt;and&lt;/em&gt; failures), cluster failure modes, identify which prior edits broke what was working and fixed what wasn't&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Propose&lt;/strong&gt; a large, multi-part edit addressing every failure cluster without regressing the wins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gate&lt;/strong&gt; — accept the edit only if it beats the held-out val split by a significance margin (Δ &amp;gt; k·SE)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit&lt;/strong&gt; — every candidate is a git commit, win or loss&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At the end, a sealed test split — which the optimizer never touched — is scored exactly once. That's the headline number.&lt;/p&gt;




&lt;h2&gt;
  
  
  Two orchestration modes
&lt;/h2&gt;

&lt;p&gt;cap-evolve can run the loop in &lt;a href="https://skillberry-ai.github.io/cap-evolve/agent-orchestration.html" rel="noopener noreferrer"&gt;two ways&lt;/a&gt;, set by a single key in &lt;code&gt;capevolve.yaml&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deterministic mode (default):&lt;/strong&gt; &lt;code&gt;cap-evolve run&lt;/code&gt; sequences the phases itself — intake → baseline → algorithm → finalize — spawning a per-iteration optimizer subprocess (Claude Code, Codex, Gemini CLI, etc.) to propose each edit. The engine evaluates on val, applies the gate, and accepts/rejects. Fully hands-off and reproducible — set it running and come back to a dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent mode:&lt;/strong&gt; &lt;code&gt;cap-evolve run&lt;/code&gt; does check + baseline, hands back the run directory, and returns. The &lt;em&gt;same conversational agent that ran intake&lt;/em&gt; then drives the optimization itself using the &lt;code&gt;agent-optimize&lt;/code&gt; algorithm — reading the failing-task feedback, proposing a targeted edit, evaluating on full val, accepting only on the paired significance gate. No optimizer subprocess; &lt;strong&gt;the agent is the optimizer&lt;/strong&gt;. The user can steer or halt at any round.&lt;/p&gt;

&lt;p&gt;Both modes share the same honesty invariants — seeded splits, val-only gating, sealed test — because those live in &lt;code&gt;core/&lt;/code&gt; and can't be bypassed by any skill, prompt, or CLI flag.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the optimizer actually changed
&lt;/h2&gt;

&lt;p&gt;On the τ²-bench airline run (deterministic mode, Claude Code optimizer), the optimizer didn't just rewrite rules. It expanded &lt;code&gt;tools.py&lt;/code&gt; from &lt;strong&gt;593 to 832 lines&lt;/strong&gt; — adding deterministic enforcement of fare class constraints, input validation that catches booking errors at the tool boundary, and composite helper tools that short-circuit common multi-step patterns.&lt;/p&gt;

&lt;p&gt;The policy prompt grew too (166 → 233 lines), but &lt;strong&gt;most of the gain came from the tool edits&lt;/strong&gt;. Five of ten iterations were gate-accepted; the rest were rejected as within-noise. You can read the five trajectory-verified before/after edits in &lt;a href="https://github.com/skillberry-ai/cap-evolve/blob/main/docs/OPTIMIZATION_EXAMPLES.md" rel="noopener noreferrer"&gt;OPTIMIZATION_EXAMPLES.md&lt;/a&gt; and walk through the full run in &lt;a href="https://github.com/skillberry-ai/cap-evolve/blob/main/examples/tau2_airline/DEMO.md" rel="noopener noreferrer"&gt;DEMO.md&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's what that looks like in the dashboard — the fitness stair only ever steps &lt;em&gt;up&lt;/em&gt;, because the gate refused every change it couldn't distinguish from noise:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiki2p1tx974wojr19t17.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiki2p1tx974wojr19t17.png" alt="Dashboard overview — fitness stair from baseline 0.536 to best 0.712, with 5 of 10 iterations accepted" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's the lineage tree — green accepted candidates, red rejected branches, and the paired-gate math (Δ &amp;gt; k·SE) behind each decision:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzn02jyykol1eqwko2r2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzn02jyykol1eqwko2r2.png" alt="Lineage tree — seed to accepted candidates to champion, rejected branches in red, gate math visible" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Here's what the loop actually produced across different benchmarks and models. (&lt;a href="https://skillberry-ai.github.io/cap-evolve/results.html" rel="noopener noreferrer"&gt;Full results page with all caveats →&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  τ²-bench airline — fit-metric run (committed, reproducible)
&lt;/h3&gt;

&lt;p&gt;Run with &lt;code&gt;train == val == test == all 50 tasks&lt;/code&gt; — a fit metric, not a generalization claim, but &lt;a href="https://skillberry-ai.github.io/cap-evolve/run-end-to-end.html" rel="noopener noreferrer"&gt;fully committed and reproducible&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;reward (50 tasks · 10 trials)&lt;/th&gt;
&lt;th&gt;Δ vs baseline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Baseline (seed policy + tools)&lt;/td&gt;
&lt;td&gt;0.536 (53.6%)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best candidate (&lt;code&gt;cand_0007&lt;/code&gt;) — val&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.712 (71.2%)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+32.8% relative&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;cand_0007&lt;/code&gt; — sealed test (fit metric)&lt;/td&gt;
&lt;td&gt;0.694 (69.4%)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Artifact: &lt;a href="https://github.com/skillberry-ai/cap-evolve/tree/main/examples/tau2_airline/run_full" rel="noopener noreferrer"&gt;&lt;code&gt;examples/tau2_airline/run_full/&lt;/code&gt;&lt;/a&gt;. Reproducible via &lt;a href="https://github.com/skillberry-ai/cap-evolve/blob/main/docs/REPRODUCE_tau2.md" rel="noopener noreferrer"&gt;&lt;code&gt;REPRODUCE_tau2.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The dashboard for this committed run is interactive — you can browse every iteration's git diff, cost breakdown, and gate decision offline:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpns9iedfutvc7bwrrquw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpns9iedfutvc7bwrrquw.png" alt="The cap-evolve run dashboard — KPIs, stair chart, heatmap, lineage, and cost panel for the τ²-bench airline run" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  c 20/50 run &lt;em&gt;(reported; artifact pending)&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Same benchmark and capability, run with a real holdout split (30 train /  20 test):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;split&lt;/th&gt;
&lt;th&gt;baseline&lt;/th&gt;
&lt;th&gt;optimized&lt;/th&gt;
&lt;th&gt;Δ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;val (30 tasks)&lt;/td&gt;
&lt;td&gt;56.7%&lt;/td&gt;
&lt;td&gt;70.0%&lt;/td&gt;
&lt;td&gt;+13.3 pp / +23.5% relative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;sealed test&lt;/strong&gt; (20 tasks, scored once)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;30.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;47.5%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+17.5 pp / +58.3% relative&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the &lt;code&gt;run_full&lt;/code&gt; artifact for this run is not yet committed. The numbers are reported; the reproducible artifact-backed run is the fit-metric run above.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  τ²-bench airline — agent orchestration mode (train=val=30, test=20)
&lt;/h3&gt;

&lt;p&gt;First run driven entirely in &lt;a href="https://skillberry-ai.github.io/cap-evolve/agent-orchestration.html" rel="noopener noreferrer"&gt;agent mode&lt;/a&gt; with &lt;code&gt;agent-optimize&lt;/code&gt;: the conversational agent ran the baseline, proposed airline-policy edits itself, gated every candidate on full val, and sealed the test once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Single-trial (pipeline default):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;split&lt;/th&gt;
&lt;th&gt;baseline&lt;/th&gt;
&lt;th&gt;best (&lt;code&gt;cand_5&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;Δ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;val (30, fit)&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.633&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;+26.7% relative&lt;/strong&gt; — gate-significant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sealed test (20, held-out, scored once)&lt;/td&gt;
&lt;td&gt;0.400&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.550&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+37.5% relative&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Honest reading:&lt;/strong&gt; τ²-bench airline is high-variance at a single trial. On a stable 3-trial re-evaluation, the val fit gain is +18.4% (paired-significant, Δ/SE = 1.80) while the held-out test is flat within noise (−0.067, SE 0.105). Because &lt;code&gt;train == val&lt;/code&gt;, the val figure is a fit, not generalization. Agent mode produced the only gate-accepted improvement in a head-to-head against a bounded deterministic run (whose best stayed the seed; sealed test 0.35). A genuine stable held-out gain needs a stronger runner model or tool-level edits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  τ²-bench airline — Qwen 2.5 14B (self-hosted, held-out)
&lt;/h3&gt;

&lt;p&gt;Same benchmark and split (30/20 held-out), replacing the cloud runner with &lt;strong&gt;Qwen 2.5 14B-Instruct&lt;/strong&gt; via vLLM on OpenShift. This is what it looks like on a self-hosted open model with no API dependency.&lt;/p&gt;

&lt;p&gt;Tools + policy optimized jointly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;split&lt;/th&gt;
&lt;th&gt;baseline&lt;/th&gt;
&lt;th&gt;optimized&lt;/th&gt;
&lt;th&gt;Δ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;val (10 tasks)&lt;/td&gt;
&lt;td&gt;20.0%&lt;/td&gt;
&lt;td&gt;38.7%&lt;/td&gt;
&lt;td&gt;+93.5% relative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;sealed test&lt;/strong&gt; (10 tasks)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;17.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;24.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+41.2% relative&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All three capabilities (&lt;code&gt;[skill-package, system-prompt, tools]&lt;/code&gt;) optimized jointly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;split&lt;/th&gt;
&lt;th&gt;baseline&lt;/th&gt;
&lt;th&gt;optimized&lt;/th&gt;
&lt;th&gt;Δ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;val (10 tasks)&lt;/td&gt;
&lt;td&gt;27.3%&lt;/td&gt;
&lt;td&gt;52.0%&lt;/td&gt;
&lt;td&gt;+90.5% relative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;sealed test&lt;/strong&gt; (10 tasks)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;12.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;27.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+125.0% relative&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;3 of 10 iterations accepted in both runs. On a self-hosted 14B model, jointly optimizing all three capability types outperformed the tools-only run (+125% vs +41.2% on test).&lt;/p&gt;

&lt;h3&gt;
  
  
  SkillsBench — skill-package optimization (held-out, committed)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://arxiv.org/abs/2602.12670" rel="noopener noreferrer"&gt;SkillsBench&lt;/a&gt; tests agents across 84 real-world tasks using deterministic verifiers. Agents are evaluated under three conditions: no skills, curated skills, and self-generated skills. cap-evolve targets the &lt;em&gt;curated skills&lt;/em&gt; condition — it optimizes the &lt;code&gt;SKILL.md&lt;/code&gt; packages the agent reads at runtime.&lt;/p&gt;

&lt;p&gt;Setup: four shared office-document skill packages (&lt;code&gt;docx&lt;/code&gt;/&lt;code&gt;pptx&lt;/code&gt;/&lt;code&gt;xlsx&lt;/code&gt;/&lt;code&gt;pdf&lt;/code&gt;). Agent under test: &lt;code&gt;claude-sonnet-4-6&lt;/code&gt; in a Docker sandbox; optimizer: &lt;code&gt;claude-opus-4-8&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;reward&lt;/th&gt;
&lt;th&gt;Δ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Baseline — val&lt;/td&gt;
&lt;td&gt;0.333&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Optimized (&lt;code&gt;cand_0004&lt;/code&gt;) — val&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;+114% relative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Baseline — sealed test&lt;/td&gt;
&lt;td&gt;0.556&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Optimized — sealed test (held-out)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.667&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+20.0% relative&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Artifact: &lt;a href="https://github.com/skillberry-ai/cap-evolve/tree/main/examples/skillsbench/run_full" rel="noopener noreferrer"&gt;&lt;code&gt;examples/skillsbench/run_full/&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The optimizer edited all four &lt;code&gt;SKILL.md&lt;/code&gt; bodies and added executable scripts across 7 iterations (4 accepted). Notably it stopped itself on the last two tasks after diagnosing them as broken oracles — rather than overfitting a general skill to pass a broken verifier.&lt;/p&gt;

&lt;p&gt;The "money shot" in the dashboard is the git diff panel — you can see exactly what prose and code the optimizer added to each skill, and the append-only &lt;code&gt;JOURNAL.md&lt;/code&gt; where each iteration's reasoning meets the framework's objective &lt;code&gt;RESULT&lt;/code&gt; line:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhmp82j4l5vu5qh9cqca9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhmp82j4l5vu5qh9cqca9.png" alt="Per-iteration git diffs panel — the optimizer writing executable code into tool bodies and updating JOURNAL.md memory" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  SWE-bench — coding-agent prompt (adapter ready, production results pending)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/SWE-bench/SWE-bench" rel="noopener noreferrer"&gt;SWE-bench&lt;/a&gt; gives agents real GitHub issues across 12 popular Python repositories. The agent must produce a patch that passes fail-to-pass tests without breaking the regression suite. It is the primary standard for measuring coding agent capability — top agents now score 70–80%+ on SWE-bench Verified.&lt;/p&gt;

&lt;p&gt;cap-evolve &lt;a href="https://skillberry-ai.github.io/cap-evolve/adapter-templates.html" rel="noopener noreferrer"&gt;optimizes the coding-agent's &lt;code&gt;prompt.md&lt;/code&gt;&lt;/a&gt; against a pinned subset of SWE-bench Lite instances. The adapter is fully wired (HuggingFace + Docker harness, binary reward per instance, holdout split). Production results are in progress — and we'd love help running them.&lt;/p&gt;

&lt;p&gt;These are within-run improvements on our own splits, with our models and budgets — not leaderboard comparisons. &lt;a href="https://skillberry-ai.github.io/cap-evolve/results.html" rel="noopener noreferrer"&gt;Full methodology, caveats, and committed artifacts →&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why evaluation honesty matters
&lt;/h2&gt;

&lt;p&gt;The cost panel makes the evaluation accounting transparent — every candidate scored, every dollar spent, and the sealed test row that appears exactly once:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4unw4ozc59mm3v3n2vxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4unw4ozc59mm3v3n2vxr.png" alt="Cost panel — per-candidate evaluations table, sealed test row, cost by role and iteration, total budget usage" width="800" height="926"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you optimize against a metric, it's easy to accidentally overfit to the data you're measuring. We've all seen papers that look great on val and fall apart on test. We made the following hard to violate by putting the rules in code, not docs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The test split is sealed in code.&lt;/strong&gt; &lt;a href="https://skillberry-ai.github.io/cap-evolve/architecture.html#phases" rel="noopener noreferrer"&gt;&lt;code&gt;RunDir.consume_test()&lt;/code&gt;&lt;/a&gt; flips a &lt;code&gt;test_used&lt;/code&gt; flag and raises &lt;code&gt;TestSealError&lt;/code&gt; on any second call. The held-out number is produced exactly once, at &lt;code&gt;finalize&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acceptance gates on val, with significance.&lt;/strong&gt; The gate rejects any candidate that doesn't exceed &lt;code&gt;k · SE&lt;/code&gt; over the current best on the held-out val split. Noise doesn't count as progress — and the threshold is user-configurable so you can be as conservative as you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These rules live in the core, not in editable docs.&lt;/strong&gt; Every algorithm skill calls the same &lt;code&gt;cap_evolve&lt;/code&gt; library. There's no way to configure your way around them.&lt;/p&gt;

&lt;p&gt;This matters in practice: on our τ²-bench runs, &lt;strong&gt;5 of 10 iterations were rejected&lt;/strong&gt;. If we'd accepted every improvement on train, we'd have reported higher numbers that didn't generalize.&lt;/p&gt;




&lt;h2&gt;
  
  
  The optimizer is whatever agent you already use
&lt;/h2&gt;

&lt;p&gt;cap-evolve is &lt;a href="https://skillberry-ai.github.io/cap-evolve/architecture.html#skill-library" rel="noopener noreferrer"&gt;optimizer-agnostic&lt;/a&gt;. The "edit proposer" is any coding agent you can invoke from a shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# optimizers/registry.yaml&lt;/span&gt;
&lt;span class="na"&gt;claude-code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude -p "{prompt}" --permission-mode acceptEdits&lt;/span&gt;
  &lt;span class="na"&gt;cwd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{workdir}"&lt;/span&gt;

&lt;span class="na"&gt;codex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;codex exec --sandbox workspace-write "{prompt}"&lt;/span&gt;
  &lt;span class="na"&gt;cwd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{workdir}"&lt;/span&gt;

&lt;span class="na"&gt;gemini-cli&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gemini -p "{prompt}" --approval-mode=yolo&lt;/span&gt;
  &lt;span class="na"&gt;cwd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{workdir}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;14 backends ship out of the box (Claude Code, Codex, Gemini CLI, Cursor, opencode, IBM Bob, and more), plus a &lt;code&gt;mock&lt;/code&gt; backend for CI that edits deterministically without calling any model.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it in two minutes — no API key
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://skillberry-ai.github.io/cap-evolve/getting-started.html" rel="noopener noreferrer"&gt;&lt;code&gt;toy_calc&lt;/code&gt; example&lt;/a&gt; uses a deterministic mock agent. No model is called, no credentials needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/skillberry-ai/cap-evolve.git
&lt;span class="nb"&gt;cd &lt;/span&gt;cap-evolve

python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
pip &lt;span class="nb"&gt;install&lt;/span&gt; ./core   &lt;span class="c"&gt;# zero runtime deps — pure stdlib&lt;/span&gt;

bash examples/toy_calc/run.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The seed prompt scores &lt;code&gt;0.0&lt;/code&gt; on val. The mock optimizer adds a &lt;code&gt;[CALC]&lt;/code&gt; marker. The sealed test scores &lt;code&gt;1.0&lt;/code&gt;. You get a &lt;code&gt;dashboard.html&lt;/code&gt; showing the full run — splits, gate decisions, per-iteration diffs, cost breakdown.&lt;/p&gt;

&lt;p&gt;This is a toy, but it's not a demo — the same core code runs the τ²-bench and SkillsBench results above. The loop, the gate, the sealing, and the dashboard are all real.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bring your own benchmark
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://skillberry-ai.github.io/cap-evolve/optimize-your-own.html" rel="noopener noreferrer"&gt;Wiring your agent&lt;/a&gt; takes three methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="c1"&gt;# return your eval cases for 'train'|'val'|'test'|'all'
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Rollout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# run your agent with the current candidate as context
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rollout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Rollout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# reward in [0,1] + feedback — never leak the gold answer
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else — splits, trials, pass^k, the gate, the sealed test, memory across iterations, the dashboard — is in the core. You can also copy a &lt;a href="https://skillberry-ai.github.io/cap-evolve/adapter-templates.html" rel="noopener noreferrer"&gt;ready-made adapter template&lt;/a&gt; for JSONL, HuggingFace, tau2-bench, SWE-bench, or SkillsBench and only change the provider.&lt;/p&gt;

&lt;p&gt;The fastest path: drop your coding agent into the repo root and point it at &lt;a href="https://github.com/skillberry-ai/cap-evolve/blob/main/RUN.md" rel="noopener noreferrer"&gt;&lt;code&gt;RUN.md&lt;/code&gt;&lt;/a&gt;. It runs &lt;code&gt;intake&lt;/code&gt;, writes the adapter, passes &lt;code&gt;cap-evolve check&lt;/code&gt;, and starts the loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we learned
&lt;/h2&gt;

&lt;p&gt;A few things genuinely surprised us building this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tool edits outperform prompt edits for structural failures.&lt;/strong&gt; On τ²-bench, the biggest single-iteration gains came from adding deterministic enforcement in tool code, not from rewriting policy prose. A constraint the model can't skip beats a rule it might forget — this maps directly to the class of failures SWE-bench exposes too, where the patch has to make tests pass, not just satisfy a prose description.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jointly optimizing all capability types outperformed tools-only.&lt;/strong&gt; On Qwen 14B, optimizing &lt;code&gt;[skill-package, system-prompt, tools]&lt;/code&gt; together gave +125% on the held-out test vs +41.2% for tools alone. The optimizer distributed edits across code-level guards, policy clarifications, and SKILL.md structured methodology.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The optimizer knows when to stop.&lt;/strong&gt; On SkillsBench, after 4 accepted iterations, the optimizer diagnosed the two remaining failing tasks as broken oracles — the verifier expected a value that wasn't derivable from any data the agent had access to. It stopped rather than overfitting. A loop that can distinguish "this task is hard" from "this oracle is wrong" wastes less budget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rejections are informative.&lt;/strong&gt; Rejected iterations aren't wasted — the optimizer's memory carries forward what was tried and why it didn't clear the gate, so later iterations don't repeat the same dead ends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent mode found improvements that deterministic mode missed.&lt;/strong&gt; On the head-to-head run (same split, same runner), the deterministic &lt;code&gt;hill-climb&lt;/code&gt; run proposed candidates that reached val 0.567 but none cleared the gate — its best stayed the seed, sealed test 0.35. The agent-mode run found a gate-accepted improvement and the only positive held-out test. The difference: &lt;code&gt;agent-optimize&lt;/code&gt; can adjust its search strategy mid-run rather than following a fixed schedule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small task sets make this hard.&lt;/strong&gt; With 10 val tasks, the significance gate is conservative — some real improvements get rejected as within-noise. That's intentional, but it means you need a reasonably large eval to make the loop useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get involved
&lt;/h2&gt;

&lt;p&gt;cap-evolve is beta (0.x), Apache-2.0, zero runtime deps. Made at IBM / Red Hat.&lt;/p&gt;

&lt;p&gt;We're actively looking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;⭐ Stars&lt;/strong&gt; — if the approach resonates, a &lt;a href="https://github.com/skillberry-ai/cap-evolve" rel="noopener noreferrer"&gt;GitHub star&lt;/a&gt; helps others find it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔍 Code reviews&lt;/strong&gt; — the core is small and pure-stdlib; honest critique of the gate logic, adapter contract, or algorithm skills is very welcome&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;💬 Comments here&lt;/strong&gt; — questions about the honesty gate, the two orchestration modes, the tool-vs-prompt tradeoff, how trace diagnosis works, or where this falls over&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🐛 Issues &amp;amp; PRs&lt;/strong&gt; — bug reports, adapter templates for new benchmarks, new optimizer backends, or improvements to existing skills — all welcome via &lt;a href="https://github.com/skillberry-ai/cap-evolve/issues" rel="noopener noreferrer"&gt;GitHub Issues&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/skillberry-ai/cap-evolve" rel="noopener noreferrer"&gt;github.com/skillberry-ai/cap-evolve&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Site + docs:&lt;/strong&gt; &lt;a href="https://skillberry-ai.github.io/cap-evolve/" rel="noopener noreferrer"&gt;skillberry-ai.github.io/cap-evolve&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Results + artifacts:&lt;/strong&gt; &lt;a href="https://skillberry-ai.github.io/cap-evolve/results.html" rel="noopener noreferrer"&gt;skillberry-ai.github.io/cap-evolve/results.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent mode:&lt;/strong&gt; &lt;a href="https://skillberry-ai.github.io/cap-evolve/agent-orchestration.html" rel="noopener noreferrer"&gt;skillberry-ai.github.io/cap-evolve/agent-orchestration.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Getting started:&lt;/strong&gt; &lt;a href="https://skillberry-ai.github.io/cap-evolve/getting-started.html" rel="noopener noreferrer"&gt;skillberry-ai.github.io/cap-evolve/getting-started.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
