SkillOpt · walkthrough
Code ↗ arXiv ↗
Microsoft · SJTU · Tongji · Fudan · arXiv 2605.23904

Train the skill, not the weights.

SkillOpt treats an agent’s skill document as the external trainable state of a frozen model — optimizing it with the same discipline that makes weight training reproducible: a learning rate, a validation gate, momentum, and rejected-step memory. The output is one auditable best_skill.md, and zero extra model calls at deployment.

Frozen target model Separate optimizer model 6 benchmarks · 7 models · 3 harnesses May 2026
Yifan Yang, Ziyang Gong, Weiquan Huang, Qihao Yang, Ziwei Zhou, Zisu Huang, Yan Li, Xuemei Gao, Qi Dai, Bei Liu, Kai Qiu, Yuqing Yang, Dongdong Chen, Xue Yang, Chong Luo  ·  Microsoft · Shanghai Jiao Tong University · Tongji University · Fudan University
52/52
cells best or tied · every (model, benchmark, harness) combination tested
+23.5pts
GPT–5.5 direct chat · average lift over no skill (+24.8 Codex, +19.1 Claude Code)
1–4
accepted edits · the entire gain rides on a handful that pass the gate
<2K
tokens · the deployed skill stays small enough to read and audit in minutes
Start here · no jargon

The big picture, in plain English

Before any equations: here is the whole paper in three pictures. If you read nothing else, read this.

Modern AI agents follow a skill — a page of natural-language instructions telling them how to do a task: which tools to call, what format to output, what mistakes to avoid. Today those pages are hand-written, generated once and frozen, or rewritten by the model in loosely-controlled ways. None of them reliably get better the way a neural network gets better during training. SkillOpt asks: what if we optimized the skill page the same disciplined way we optimize model weights?

💡 The one idea to take away

Imagine you can’t retrain a brilliant but rigid employee. What you can do is keep refining their one-page cheat-sheet. SkillOpt is a coach who watches the employee work, notes the recurring mistakes, and edits the cheat-sheet — but only keeps an edit if a fresh batch of test tasks actually scores higher with it.

The cheat-sheet is the “weights” being trained. The coach is a second AI (the optimizer). The fresh test is the validation gate. And crucially, when you ship the employee, the coach goes home — there’s no extra cost at runtime, just the better cheat-sheet.

👀 As you read on, the technical sections get detailed. Watch for the dashed “In plain English” cards — each re-explains the idea above it with an everyday analogy. Skim the cards alone for a friendly tour, or read everything for the full depth.
01 The 30-second version

What they did, and why it’s surprising

Frontier agents adapt to a domain through their procedures — how they gather evidence, call tools, format answers. SkillOpt makes that procedure layer trainable, without touching a single model weight.

Given a domain, an initial skill, and a frozen target model, SkillOpt loops: it samples batches of scored rollouts, hands the successes and failures to a separate optimizer model, and asks for bounded add / delete / replace edits to the skill. It ranks and clips those edits under a textual learning rate, applies the bounded update, and then — the crucial step — evaluates the candidate skill on a held-out selection split. An edit survives only if it strictly improves that score.

The deployed result is a compact best_skill.md (≈300–2,000 tokens) built from just 1–4 accepted edits. It adds zero optimizer calls at deployment — the agent simply reads a better page. Across six benchmarks, seven target models, and three execution harnesses, SkillOpt is best or tied-best on all 52 evaluated cells.

The thesis in one line

A skill should be trained, not prompted: turn scored rollouts into bounded, validation-gated edits, and the agent’s instruction page improves like weights under SGD — stably, reproducibly, and reusably.

02 Motivation

If skills are the adaptation layer, how should they be optimized?

Frontier models are increasingly deployed as agents — from single-prompt callers to multi-step harnesses with tools, files, and verifiers. In those settings, adapting to a domain isn’t only about weights or prompts: it’s about improving the procedures the agent uses. Agent skills are the natural interface for that — a portable text artifact packaging procedures, heuristics, tool policies, output constraints, and failure modes.

But weight adaptation is unavailable for closed frontier models and expensive for open ones, while hand-written or one-shot skills are brittle. Recent systems convert experience into textual artifacts — distilling trajectory lessons, refining skill folders, building skill libraries — yet leave a more basic question open:

Research question

If the recurring object of adaptation is the agent’s procedure, the skill document itself should be trainable. So how do you optimize it — with the same controls that make weight-space optimization stable and reproducible?

The key move: treat skill editing as a controllable domain-adaptation process. The skill document is the external state; an additional frontier model is the optimizer; and training-style controls govern evidence, step size, validation, and update direction. The stakes are practical — if consecutive revisions move too far or in inconsistent directions, the optimizer can no longer learn from what helped and what failed. Stability is the whole game.

03 The core idea

The deep-learning analogy is operational, not decorative

Every design choice maps onto a piece of the standard training loop. The skill document plays the role of parameters; trajectory feedback plays the role of the gradient; and a suite of familiar controls keeps the process stable.

💡 In plain English

In normal training, you nudge millions of numbers a little bit each step (the learning rate), check progress on held-out data (validation), and let momentum carry consistent directions forward. SkillOpt does all of that — but the “numbers” are sentences in a document, and the “nudge” is at most a few text edits.

Why bother with the analogy? Because every word of it is load-bearing. The edit budget really does act like a learning rate (too big → the skill thrashes); the gate really does prevent overfitting; the slow update really does behave like momentum across epochs.

Two roles stay strictly separated, and this separation is what makes the method cheap to deploy:

Target model M — frozen

The agent being adapted. It only ever sees the current skill and the task. Its weights never change. At deployment it’s the only model running.

Optimizer model O — training-time only

A separate (often stronger) frontier model that reads rollout evidence and proposes edits. It runs only during the offline training loop — never at deployment.

Why this matters

Because the optimizer is offline-only, a high-capacity frontier optimizer is “free” at runtime — it costs training-time API calls and adds nothing to the deployed agent. You pay once to train a better page; you reuse it forever.

04 The method

One optimization step, end to end

SkillOpt is a loop. Each step is a forward pass (gather evidence), a backward pass (reflect into edits), a bounded update (apply within budget), and a gate (accept only if validation improves). Across epochs, a slow/meta update carries longer-horizon lessons. Click a stage to expand.

FORWARD
Rollout
Frozen model runs a batch of tasks with the current skill.
scored tracesbatch = evidence
BACKWARD
Reflect
Optimizer turns success/failure minibatches into edits.
add/del/replacemerge
UPDATE
Bounded edit
Rank & clip to the top Lt edits — the learning rate.
budget Ltschedule
GATE
Validate
Accept only if held-out score strictly improves; else reject.
Dsel gatereject buffer
Recreation of the SkillOpt pipeline (Figure 2). A frozen target model executes a rollout batch; the optimizer reflects over successes and failures; edits are merged, ranked, and clipped under a scheduled budget; and the candidate skill is accepted only through a held-out validation gate. Across epochs, a slow/meta update retains longer-horizon lessons.

Problem setup: what is being optimized

A skill s is a natural-language policy inserted into the agent’s context before execution. For a harness h, task x, and skill s, running the frozen model M produces a trajectory and a scalar score:

(τ(s),r(s)) =h(M,x,s), r(s)[0,1] (1)
The execution model. A skill is judged only by the scored trajectories it produces under the frozen model and a fixed harness. Everything downstream is search over the text of s.

The data is split three ways. The train split Dtr supplies rollout evidence; the selection split Dsel gates updates; the test split Dtest is locked until the final report. SkillOpt generates candidate skills, picks the best on selection, and reports on test:

ssel= arg maxsC(Dtr) 1|Dsel| xDsel r(s) (2)
Selection objective. Among all candidate skills produced from training rollouts, keep the one with the highest held-out selection score. The reported test score is then computed on the disjoint test split — so the headline numbers measure generalization, not validation-set fit.

Forward pass — rollout evidence

At each step the target model runs a rollout batch from Dtr with the current skill. The harness records everything the optimizer might learn from: messages, tool calls, observations, command outputs, final answers, verifier feedback, and benchmark-specific context (spreadsheet previews, document references, compact execution traces). This batch is the evidence unit: small batches update quickly but noisily; larger batches expose recurring patterns before the skill changes.

Backward pass — minibatch reflection

The optimizer turns trajectories into edits. It first separates failures from successes, then partitions each group into reflection minibatches. This matters: single trajectories produce anecdotal fixes, but a minibatch reveals reusable procedural errors — the agent consistently searches the wrong source, formats the answer wrong, or never verifies a tool result. Failure minibatches propose corrective rules; success minibatches preserve what already works. Proposals are then merged hierarchically — failure and success edits consolidated separately, then combined with priority on failure corrections — filtering duplicate, contradictory, and example-specific suggestions.

💡 In plain English

If a student fails one exam question, you might fix a typo in their notes. If they fail the same kind of question across ten exams, you’ve found a real gap worth writing a rule for. Minibatches force the optimizer to spot the repeated mistake, not chase one-offs.

The bounded update — a textual learning rate

This is the heart of the method. After aggregation, the optimizer ranks the merged edit pool by expected utility and clips it to the top Lt edits. That budget Lt is the learning-rate analogue. Unbounded rewrites can erase useful rules, introduce contradictions, or overfit to a single failure; a bounded update preserves continuity while still letting the skill acquire new procedures. The budget follows a schedule — constant, linear, cosine, or autonomous — with the default cosine starting larger and decaying toward small consolidation steps.

Play with the edit-budget schedule

The budget Lt caps how many edits land per step — exactly like a learning rate caps how far weights move. Pick a schedule and drag the starting budget. (Illustrative — cosine modeled as floor + (L₀−floor)·½(1+cos(πt/T)).)

The validation gate & rejected-edit buffer

Every candidate skill is evaluated on Dsel with the same frozen model and harness. If it improves over the current selection score, it becomes the new current skill; if it also exceeds the best so far, it becomes best_skill.md. Otherwise it’s rejected. The gate is intentionally strict — strictly-greater, ties rejected — so the deployed skill never silently drifts. This turns reflection into propose-and-test optimization rather than unconditional self-editing, which is crucial because plausible textual diagnoses can still hurt the actual target model.

Rejected updates aren’t wasted. An epoch-local buffer records observed failure patterns and, for each rejected step, the edits tried and the score drop they caused. Later reflection calls in the same epoch receive this buffer, so the optimizer avoids repeating failed edits and focuses on unresolved failures — negative feedback during training, with no inference-time cost.

💡 In plain English

The gate is a ruthless editor: a change ships only if a fresh batch of tasks scores higher with it. A clever-sounding rule that doesn’t actually help gets thrown out. But the editor keeps a list of what didn’t work, so the same bad idea isn’t proposed twice.

Epoch-wise slow / meta update — the momentum term

Fast updates learn from the current batch; the slow/meta update learns across adjacent epochs. At an epoch boundary, SkillOpt re-runs the same training items under the previous-epoch skill and the current skill, then sorts the results into improvements, regressions, persistent failures, and stable successes. The optimizer writes a concise longitudinal guidance block into a protected slow-update field that step-level edits cannot overwrite — and even this candidate passes the validation gate. A separate meta skill lives only on the optimizer side: it summarizes which edit patterns helped, which were rejected, and which failures persist, and is prepended to future optimizer prompts — but it is never shipped with the deployed skill.

Separation of concerns

The deployed skill stays compact and portable; the training process keeps a richer record. The protected region keeps fast local edits from clobbering durable lessons — and removing it is one of the most damaging ablations (more below).

The full procedure (Algorithm 1)

The state variables are the current skill scur, the best validation-gated skill sbest, a selection-score cache (so identical candidate skills aren’t re-evaluated), the rejected-step buffer, and the optimizer-side meta skill. In sequence, per step: collect rollouts → split into failure/success minibatches → ask the optimizer to analyze each → merge (failure, then success, then failure-prioritized final) → rank and keep at most Lt → apply → gate on Dsel → accept or push to the rejected buffer. At each epoch boundary (from epoch 2): the slow update and meta-skill update run. Only sbest is exported.

05 Main results

Best or tied on all 52 cells

The main experiment is a matrix: seven target models × six benchmarks in direct chat, plus GPT–5.5 under the Codex and Claude Code harnesses. The benchmarks span single-round QA (SearchQA), spreadsheet code execution (SpreadsheetBench), multi-turn document tool loops (OfficeQA), multimodal document QA (DocVQA), mathematical MCQ (LiveMath), and embodied decision-making (ALFWorld). Baselines: no skill, human skill, one-shot LLM skill, Trace2Skill, TextGrad, GEPA, and (in harnesses) EvoSkill.

GPT–5.5 · direct chat no skill vs. strongest baseline vs. SkillOpt
From Table 1. SkillOpt’s six-benchmark average rises from 58.8 (no skill) to 82.3 — a +23.5 point gain — and clears the best-per-cell oracle baseline (76.9) by +5.4. The largest jumps are on procedural tasks: SpreadsheetBench 41.8→80.7 and OfficeQA 33.1→72.1.
💡 In plain English

The biggest wins are on tasks with strict procedures — spreadsheets and office documents — where frontier models are smart but sloppy about how to do the job. A learned page of “always inspect the workbook first, write static values not formulas” closes most of the gap. On QA, where the model is already near ceiling, the gain is smaller but still positive.

Average lift over no-skill, per target model direct chat, six-benchmark mean
SkillOpt helps every model from frontier GPT–5.5 down to small Qwen–3.5–4B, averaging ≈+17.6 points per model. Small/weak targets benefit most in relative terms (GPT–5.4–nano nearly doubles on DocVQA and triples on ALFWorld) — consistent with the view that a compact skill supplies procedural knowledge small models don’t yet hold in weights.

The same loop works inside agentic harnesses

SkillOpt isn’t a direct-chat trick. The identical optimizer drives GPT–5.5 inside the Codex and Claude Code CLIs, where the skill becomes persistent procedural memory and the harness reads back a compact execution trace for the optimizer to learn from.

GPT–5.5 across three harnesses five-benchmark mean, no skill vs. SkillOpt (ALFWorld omitted in harnesses)
Average gains over no skill: +23.5 direct chat, +24.8 Codex, +19.1 Claude Code. SkillOpt beats EvoSkill — the strongest harness-side competitor — by +14.0 (Codex) and +3.2 (Claude Code), even though EvoSkill itself already lifts the Claude Code five-benchmark mean from 57.8 to 73.7.

The full matrix

The complete Table 1, all models and baselines. Within each model–harness block, the best measured entry per benchmark is in green; SkillOpt rows are highlighted.

Direct-chat block: six benchmarks, seven models. Harness blocks: GPT–5.5 only, five benchmarks (ALFWorld requires persistent embodied interaction not represented in standard Codex/Claude Code adapters). All scores are held-out test percentages.

06 Ablations

Which controls actually matter?

Using GPT–5.5 as both target and optimizer, the paper removes one mechanism at a time. The headline: gains are insensitive to the exact batch sizes and schedule, but highly sensitive to the presence of bounded text-space learning, validation gating, rejected-edit feedback, and the slow/meta update — the choices that make skill editing behave like a controlled training loop.

Component ablations Table 3 · default setting vs. each mechanism removed
Removing the learning-rate bound (“without lr”) drops scores to 84.6 / 75.7 / 57.3. Removing the rejected buffer costs 1.6 / 4.6 / 2.4 points. The sharpest cliff: removing both meta skill and slow update collapses SpreadsheetBench from 77.5 to 55.0 (−22.5) — the largest degradation in the suite.

Evidence beats fragility

How much training evidence does the optimizer need? Procedural benchmarks reward more — SpreadsheetBench climbs steadily as the optimizer sees more of the training partition — while QA saturates early. The point is that the headline gains come from having enough scored evidence per update, not from a fragile prompt-search batch size.

Training evidence vs. score

Drag the fraction of the training partition exposed to the optimizer. Real numbers from Table 2(a) (split fixed 4:1:5). Watch procedural SpreadsheetBench climb while SearchQA plateaus.

The other knobs are reassuringly flat. Sweeping the reflection minibatch from 1→32 keeps SearchQA inside 85.9–87.1; sweeping the rollout batch from 8→full-epoch keeps it inside 85.1–87.2. And on the learning rate itself, every moderate bounded budget (Lt∈{1,2,4,8,16}) beats the unbounded-rewrite baseline — the qualitative claim (bound your edits) holds regardless of the exact scheduler.

07 Transfer

The skill is an artifact, not just a prompt

If the learned skill encodes real procedural knowledge, it should survive being moved. The paper tests three shifts — across model scales, across execution harnesses, and across nearby benchmarks — and every measured transfer is positive (no row falls below the target’s no-skill baseline).

Cross-harness transfer (GPT–5.5) train in one harness, deploy in the other, no further optimization
From Table 4(b). A SpreadsheetBench skill trained inside Codex transfers to Claude Code for a +59.7 gain (22.1→81.8) — slightly exceeding the in-domain Claude Code SkillOpt result. Because the two harnesses expose different tool/file APIs, these positive transfers suggest the rules encode workbook-level procedure (structure-first inspection, static-value materialization), not harness-specific command recipes.

Cross-model

A SpreadsheetBench skill trained on GPT–5.4 lifts GPT–5.4–mini (+9.4, ~82% of in-domain gain) and –nano (+3.0). A LiveMath skill transfers to –mini (+4.5) and –nano (+5.6) — on the latter, the transferred skill even beats the in-domain one.

Cross-benchmark

The strictest shift: an OlympiadBench skill applied to Omni-MATH. Smaller but uniformly positive — +3.7 (GPT–5.4), +1.8 (–mini), +1.3 (–nano) — evidence the skill encodes reusable math procedure, not memorized formatting.

Optimizer strength is a free training-time lever

Because the optimizer never runs at deployment, a stronger optimizer buys larger gains at zero inference cost. A strong frontier optimizer (GPT–5.5) beats a target-matched one on every cell — but the target-matched optimizer still recovers 56–74% of the gain. So SkillOpt is not just distilling a strong teacher into a weak student; the bounded, gated loop itself contributes most of the value. (And the gate is what keeps a stronger optimizer monotone — without it, a stronger model could just as easily push larger but harmful rewrites.)

08 What the skills look like

Compact, cheap, and procedural

A central premise is that the trainable object stays a small, inspectable text document. It does. Final skills range from 379 tokens (LiveMath) to 1,995 (SpreadsheetBench), median ≈920 — well under a typical system-prompt budget. And the gains come from astonishingly few accepted edits: LiveMath’s +29.3-point gain and OfficeQA’s +39.0 each arise from a single accepted edit. The optimizer proposes many more per epoch; only a handful pass the gate.

From Table 6 (GPT–5.5 student / GPT–5.5 teacher). Cost/pt is training tokens per absolute test-point gain. Two regimes: cheap procedural benchmarks (0.6–3.6M tokens/pt) and expensive long-trajectory or multimodal ones (SearchQA 37.9M, DocVQA 46.4M). All of it is paid once during training — deployment adds zero optimizer calls.

💡 In plain English

You don’t end up with a sprawling manual. You end up with a sticky note — a handful of sharp rules a thoughtful practitioner might write after a day with the benchmark, except produced automatically and validated edit-by-edit on held-out data.

One real rule per benchmark

Verbatim from the final best_skill.md of each run (Figure 4). Notice: every rule is procedural, not instance-specific — none names a particular question, file, or entity — and each encodes discipline frontier models lack zero-shot.

SearchQA
“Infer the expected answer type from clue wording, then choose the shortest canonical entity supported by co-occurring distinctive evidence.”
SpreadsheetBench
“Inspect workbook structure and formulas, then write evaluated static values across the full requested target range instead of relying on Excel recalculation.”
OfficeQA
“Treat oracle parsed pages as primary evidence, lock table/date/unit context, and output exactly the requested rounded value without extra labels.”
DocVQA
“For tables, forms, charts, and legends, first bind the question to the exact visual row/header/field, then copy only the aligned answer span.”
LiveMath
“In strongest-statement MCQs, rank choices by theorem strength and prefer a justified stronger-result option over true but weaker corollaries.”
ALFWorld
“Keep a horizon-aware visited/frontier ledger, diversify search after repeated same-type failures, and avoid revisiting the destination until holding the target.”

Two qualitative case studies confirm the shape. The ALFWorld skill evolves from a generic search-transform-place plan into a finite-state execution policy with object identity, search memory, and loop breakers (49.3→74.6 in that run). The SpreadsheetBench skill turns generic Python automation into a workbook-forensics policy — inspect the real workbook, normalize cell types, write static values (40.4→78.9).

09 Honest accounting

Limitations & a skeptic’s note

  • Needs reliable feedback. The loop relies on scored trajectories and a held-out gate, so it’s most directly applicable when the task has automatic verifiers, exact-match metrics, or executable checks. Open-ended, subjective domains would need stronger human or model-based evaluation.
  • Training isn’t free. Deployment is cheap, but training spends rollout compute and optimizer calls — order 0.6M–46M tokens per test point. Amortized over reuse, but less attractive for one-off tasks.
  • One skill, one domain. By design SkillOpt optimizes a single portable skill rather than a library — simpler to deploy, but possibly insufficient for highly heterogeneous domains needing many disjoint procedures.
  • Distribution-bound heuristics. Optimized skills can encode training-distribution heuristics, so held-out evaluation remains necessary before transferring to substantially different settings.
A skeptic’s note

The comparison is the method’s strongest evidence: every gain holds the target model, harness, and evaluator fixed, so only the adaptation procedure varies. But a few things to keep in mind — the optimizer-side prompts are reproduced but the full per-benchmark ablations isolating each prompt’s contribution aren’t exhaustive; some appendix split details differ from the main text (4:1:5 in Table 2 vs. a 2:1:7 default elsewhere); and several baselines (EvoSkill) are only measured under harnesses where a matched run exists. The single most convincing result is the +59.7 cross-harness transfer (Codex→Claude Code spreadsheet skill) — different APIs, no re-optimization, still wins — because it’s the hardest to explain away as prompt-fitting.

10 Recap

What to remember

  • The skill is the trainable state. Treat the skill document as parameters of a frozen agent and optimize it like weights — the analogy is operational, every control earns its place.
  • Bound the step. A textual learning rate (the edit budget) keeps revisions close enough that the optimizer can learn from its own history. Unbounded rewriting loses to it.
  • Gate everything. Accept an edit only if a strict held-out check improves — propose-and-test, never unconditional self-editing. This is what prevents plausible-but-harmful edits from accumulating.
  • Failures are feedback. The rejected-edit buffer turns dead ends into negative training signal at zero deployment cost.
  • Momentum across epochs. A protected slow/meta update carries durable lessons; removing it is among the most damaging ablations.
  • It transfers. The exported best_skill.md retains value across model scales, harnesses, and nearby benchmarks — optimize once, audit as text, reuse.

The broader bet: by making the skill itself the trainable object, the full toolkit of optimization — learning rates, schedules, regularization, curricula, validation — becomes available to a part of the agent stack that has so far been hand-engineered.

11 Reference

Glossary

Skill document
A natural-language policy (best_skill.md, ≈300–2,000 tokens) inserted into the agent’s context — procedures, tool policies, output constraints, failure modes. SkillOpt’s “parameters.”
Target model (M) vs. optimizer model (O)
M is the frozen agent being adapted (the only model at deployment). O is a separate frontier model that proposes edits, used only during offline training.
Textual learning rate (edit budget Lt)
The max number of edits applied at step t. Ranked merged edits are clipped to the top Lt; schedules can be constant, linear, cosine, or autonomous.
Validation gate
A candidate skill is accepted only if its held-out selection score is strictly greater than the current one — ties rejected. Turns reflection into propose-and-test.
Rejected-edit buffer
Epoch-local memory of failed edits and the score drops they caused, fed to later optimizer calls as negative feedback.
Slow / meta update
An epoch-boundary “momentum” step. The slow update writes a protected longitudinal-guidance field (shipped, but gated); the meta skill is optimizer-side only and never deployed.
add / delete / replace (patch mode)
The four atomic edit operations (append, insert_after, replace, delete) the optimizer may apply — localized changes that preserve continuity vs. full rewrites.
Harness
The execution environment: direct chat (skill in the system prompt), or tool-use loops like Codex / Claude Code (skill as persistent procedural memory). SkillOpt is harness-agnostic via an adapter.