Stop hand-editing agent skills: SkillOpt, GEPA, and EvoSkill compared

Microsoft SkillOpt treats SKILL.md files like trainable weights. GEPA and EvoSkill take different paths. Here is when each text-space optimizer fits production agent work.

SaifullahSaifullah
7 min read
Stop hand-editing agent skills: SkillOpt, GEPA, and EvoSkill compared

You fix a brittle pagination bug in your agent skill file. Task A passes. Task B regresses. You have no diff history, no validation split, and no idea which sentence caused the damage.

That is the normal state of agent skill work today. The model is strong. The markdown operating procedure is fragile.

A new class of text-space optimizers treats skill files like external trainable state: roll out tasks, score them, reflect on failures, propose bounded edits, and keep only changes that survive a held-out gate. No weight updates. No extra inference calls at deploy time.

Microsoft Research's SkillOpt is the most disciplined implementation I have seen. GEPA and EvoSkill attack the same bottleneck from evolutionary angles. This post is how I pick between them on client projects.

Why manual skill editing does not scale

Modern agent harnesses (Cursor, Claude Code, Codex) treat a skill as a standalone .md file: instructions, tool rules, formatting, recovery logic.

Hand-editing that file has three problems:

  1. No gradient. You cannot backprop through prose. Every edit is guesswork.
  2. Cross-task regressions. A line that fixes spreadsheet parsing can break doc QA.
  3. No audit trail. You rarely know which change moved the metric.

The industry response is to stop treating skills as one-shot prompts and start treating them as trainable external state with verifiers, validation splits, and rejected-edit buffers.

Text-space optimization only works when you have a verifiable score and a representative held-out set. Subjective creative tasks without automated checks are out of scope.

SkillOpt: skills as trainable parameters

SkillOpt reframes the question from "write a better prompt" to "train the skill."

The frozen target model runs a batch of tasks with the current skill. A separate optimizer model reads trajectories in reflection minibatches, proposes small add / delete / replace patches, and merges them under a textual learning rate (max edits per step). A candidate skill is adopted only if it strictly beats the current version on a held-out validation split.

Rejected edits land in a buffer so the optimizer does not repeat the same harmful diagnosis. An epoch-wise slow/meta update carries longer-horizon lessons, like momentum in weight space.

Loop stageWeight-space analogySkillOpt behavior
RolloutForward passTarget model executes tasks with current skill
ReflectionBackward passOptimizer reads trajectories, finds failure patterns
Bounded editGradient clipAdd/delete/replace patches capped by learning rate
Validation gateVal lossAccept skill only if held-out score improves
Rejected bufferNegative examplesStore harmful edits for later reflection
Slow updateMomentumEpoch-level consolidation

The output is a compact best_skill.md, typically 300 to 2,000 tokens, that runs against the unchanged target model at inference with zero extra model calls.

SkillOpt loop diagram: rollout, reflection, bounded edits, validation gate, best_skill.md artifact

Numbers that made me pay attention

Across six benchmarks, seven target models, and three harnesses (direct chat, Codex, Claude Code), SkillOpt is best or tied on all 52 evaluated cells in the paper, beating human skills, one-shot LLM skills, TextGrad, GEPA, and EvoSkill baselines.

On GPT-5.5:

HarnessAverage gain vs no skill
Direct chat+23.5 points
Codex agent loop+24.8 points
Claude Code+19.1 points

Procedural benchmarks saw the largest jumps. SpreadsheetBench on GPT-5.5 moved from 41.8 to 80.7. OfficeQA from 33.1 to 72.1. Optimized skills also transfer across model scales and between Codex and Claude Code without retraining.

SkillOpt on GitHub is MIT licensed. Install with pip install skillopt. Config lives in YAML with explicit optimizer and target backends, cosine learning-rate schedules, and slow-update toggles.

SkillOpt: controllable text-space optimization for agent skills

GEPA: evolutionary prompt evolution with a Pareto frontier

GEPA (Genetic-Pareto), from Agrawal et al., takes a different shape. Instead of training one skill document in place, it evolves textual components through reflection on full execution traces and keeps a Pareto frontier of candidates that excel on different task instances.

That matters when a single prompt cannot win everywhere. One variant might handle SQL edge cases; another might win on API pagination. GEPA samples from the frontier, mutates instructions based on natural-language feedback (not just scalar rewards), and can merge complementary winners.

GEPA ships two ways:

  • dspy.GEPA inside DSPy for modular LLM programs
  • Standalone pip install gepa for optimizing any text artifact outside DSPy

The paper reports GEPA beating GRPO by 6% on average (up to 20%) with up to 35x fewer rollouts, and beating MIPROv2 by over 10% on tasks like AIME-2025.

DimensionSkillOptGEPA
Primary artifactSingle best_skill.mdPrompt(s) / program text
SelectionStrict validation gate per editPareto frontier over instances
EcosystemHarness-agnostic skill filesDSPy-first, also standalone
Best whenOne auditable skill doc for an agentMulti-module pipelines or diverse task mix
Inference cost at deployZero extra callsZero extra calls

I reach for GEPA when the "skill" is really several coupled instructions in a DSPy graph, or when I need instance-level specialization before merging.

Comparison of SkillOpt single-document training vs GEPA Pareto frontier over multiple prompt candidates

EvoSkill: git-branched agent programs

EvoSkill extends the GEPA idea from single-file optimization to full agent program evolution. Each program is a versioned combination of system prompt plus skill files, stored on git branches prefixed program/.

The loop:

  1. Base agent runs benchmark questions with the current best program.
  2. Proposer analyzes failures and suggests skill or prompt mutations.
  3. Generator writes new skill files or rewrites the system prompt.
  4. Evaluator scores the variant on held-out data.
  5. Frontier keeps the top-N programs as frontier/* tags; weak variants get evicted.

EvoSkill never touches your working branch. After a run you git checkout program/iter-skill-N to inspect the winner.

This fits coding agents where failures are multi-skill (pagination plus retry logic plus test harness rules). SkillOpt fits when you want one portable skill artifact. EvoSkill fits when the whole agent configuration is the unit of evolution.

Example from the Alpha Signal deep dive: an agent that keeps missing nested pagination on an internal API. EvoSkill evaluates a branch on held-out cases; if pagination accuracy beats the baseline, that variant replaces the weakest frontier member.

Trade-offs nobody glosses over

Automated skill optimization has real prerequisites:

RequirementWhy it matters
Verifiable metricTests, judges, or structured graders, not vibes
Held-out validation setPrevents overfitting edits to training failures
Upfront computeOptimizer reads long trajectories; training is not free
Stable harnessChanging tools mid-training confounds the signal

The cost is front-loaded. Inference at deploy stays cheap because the artifact is plain markdown.

SkillOpt median optimized skills sit around 920 tokens in the paper. Compact enough to audit in a PR review.

What I would run first on a client repo

If you already ship agents with .cursor/skills/ or .claude/skills/ files:

  1. Pick one painful workflow with automated pass/fail (tests, schema validation, benchmark suite).
  2. Split train/val before touching prose. No optimizer saves you from a leaky eval.
  3. Try SkillOpt when one skill file drives the behavior and you want a portable best_skill.md.
  4. Try GEPA when instructions live across a DSPy program or you need Pareto diversity.
  5. Try EvoSkill when you run Claude Code or Codex on a repo and want git-tracked program branches.

Do not optimize skills for tasks you cannot score. That is expensive prompt soup.

The shift behind all three

Manual phrase tweaking in system prompts is giving way to loop engineering: verifiable goals, trajectory storage, bounded updates, exit conditions. SkillOpt, GEPA, and EvoSkill are specialized optimizers inside that control system.

The engineer's job moves up a layer. You design the eval harness and approve the artifact. The optimizer handles the sentence-level surgery.

If you are wiring production agents and want a second pair of eyes on eval design or skill structure, book a free discovery call. I spend most of my week on exactly this: making agent loops stop regressing when the model upgrade ships.

Share this post

Related posts