【SkillOpt】Harness 6 件套之 Skill 组件:把 Skill 训练成可微调参数的微软方案
【SkillOpt】Harness 6 件套之 Skill 组件:把 Skill 训练成可微调参数的微软方案
本篇属于 Harness Engineering 系列 · Skill 组件专题
系列前置阅读:
- 2026-06-26《Harness Engineering 6 大开源项目横评》
- 2026-06-27【AGENTS.md】Harness 6 件套之 Rule 组件
你有没有过这种经历:花了三天给 Claude Code 写了一份精雕细琢的 CLAUDE.md,结果在新任务上表现稳定,复用到隔壁项目却”水土不服”?你以为是 Skill 没写对,但改了三版 prompt,模型表现还是在 60% ~ 70% 之间来回震荡。
问题出在哪?
Skill 不是 prompt 工程。 把 skill 当一次性”配置”来写,本质上是把它当成静态系统提示——而 skill 的真实身份应该是 Agent 的可训练状态(trainable state)。和神经网络权重一样,它需要”梯度”、需要”学习率”、需要”验证集”、需要”早停”。只是神经网络的梯度是反传的 loss,而 skill 的梯度是反思后产生的”文本编辑 (edit)”。
这正是 2026 年 6 月微软开源的 SkillOpt(9.5k⭐,论文 arXiv:2605.23904)想解决的核心问题:把”skill 文档”当神经网络权重一样训练,整套流程叫 ReflACT(Reflective Agent Tuning)。
今天这篇文章会围绕三个核心问题展开:
- 为什么 Skill 必须能”被训练”?——一次性写好 vs 持续优化,差了 23.5 个百分点。
- ReflACT 的 6 阶段循环是怎么工作的?——Rollout → Reflect → Aggregate → Select → Update → Evaluate,文本梯度 + Held-out 验证门。
- 一个生产可用的 Skill 训练管线应该怎么搭?——给 1 个最小可运行 Demo、2 个进阶扩展(lr scheduler / slow update)、3 个项目对比。
读完你能拿到:一份可在本地跑通的 Skill 训练脚本、Skill 优化器的 8 条设计准则、3 个对比项目(Superpowers / STELLA / Affaan ECC)的设计取舍清单。
一、为什么 Skill 是 Harness 6 件套里”最被低估”的一环
1.1 一个反常识的数据
SkillOpt 团队在 6 个 benchmark × 7 个模型 × 3 种执行 harness(直接 chat / Codex CLI / Claude Code CLI)上做了完整评测,横跨 52 个 (model, benchmark, harness) 单元。结果是:
在 GPT-5.5 上,经过 ReflACT 训练后的 skill,相比”无 skill”基线,平均准确率提升 +23.5 个百分点(直接 chat)、+24.8 个百分点(Codex CLI)、+19.1 个百分点(Claude Code CLI)。
关键观察:
- 不是 prompt 写错了,是 skill 不会进化——同样的 skill 跑 100 遍还是 60% 准确率。
- 提升幅度跟模型”聪明程度”无关,反而在更强模型上提升更大(gpt-5.5 > claude-opus-4.6 > llama-3.3),因为强模型更能”读懂”skill 里的细微指引。
- 训练出的
best_skill.md通常只有 300–2000 tokens——skill 不是越长越好,而是越准越好。
1.2 Skill 在 Harness 6 件套里的位置
Harness 6 件套(Rule / Skill / Sub-Agent / Workflow / Script / MCP)里,Skill 是最像”软件”的一环:
| 组件 | 形态 | 变更频率 | 谁来维护 |
|---|---|---|---|
| Rule | 软约束(”不要做 X”) | 月级 | 团队 |
| Skill | SOP(”先做 A,再做 B”) | 周级 | 团队 + Agent 自进化 |
| Sub-Agent | 角色定义 + Context 隔离 | 月级 | 团队 |
| Workflow | 接力协议 | 月级 | 团队 |
| Script | 硬关卡 | 季度 | 团队 |
| MCP | 外部系统桥接 | 半年 | 团队 |
Skill 的特殊性在于它最容易”过时”:业务规则变、模型升级、新工具接入——任何一项变化都可能让旧 skill 失效。所以它必须有进化机制,否则就是死文档。
1.3 当前业界三类”伪训练”方案
你可能用过这些”训练 skill”的方法,但它们都有结构性问题:
| 方法 | 原理 | 问题 |
|---|---|---|
| 手工迭代 | 人看 trajectory 改 prompt | 主观、慢、无法量化 |
| One-shot LLM 生成 | 让 LLM 根据任务直接生成 skill | 不可复现,无法对比 |
| Loose self-revision | LLM 看完 trajectory 自己改 skill | 没有 held-out 验证集,容易过拟合到训练任务 |
ReflACT 的差异点:把 skill 训练变成一个有 数据集划分(train/val/test)、有 小批量梯度(minibatch + hierarchical merge)、有 学习率调度器(constant/linear/cosine/autonomous)、有 验证门(hard/soft/mixed metric) 的标准化流程,类比 SGD 训练神经网络。
二、ReflACT 架构:把 Skill 文档当 Trainable State
2.1 整体数据流
graph TB
subgraph 输入侧["📥 输入层 (Frozen Target Model)"]
Skill["📋 current_skill.md<br/>(trainable state)"]
Tasks["📚 Task Batch<br/>(train / val / test split)"]
end
subgraph 阶段1["① Rollout 阶段"]
R1["🎯 用当前 skill 执行任务<br/>收集 trajectories + scores"]
end
subgraph 阶段2["② Reflect 阶段"]
R2a["❌ 失败分析师<br/>(minibatch trajectories)"]
R2b["✅ 成功分析师<br/>(minibatch trajectories)"]
R2["📝 生成 Raw Patches<br/>(JSON edits list)"]
R2a --> R2
R2b --> R2
end
subgraph 阶段3["③ Aggregate 阶段"]
R3["🌳 层级合并<br/>(hierarchical merge,<br/>ThreadPoolExecutor)"]
end
subgraph 阶段4["④ Select 阶段"]
R4["📏 LLM 排名 + Top-L 选择<br/>(edit budget = LR)"]
end
subgraph 阶段5["⑤ Update 阶段"]
R5["🔧 应用 Edit<br/>(append/insert_after/replace/delete)<br/>+ 保护 slow_update 区"]
end
subgraph 阶段6["⑥ Evaluate 阶段"]
R6["🚧 Validation Gate<br/>(held-out val set,<br/>hard/soft/mixed metric)"]
end
subgraph 输出侧["📤 输出层"]
NewSkill["📋 candidate_skill.md<br/>(新状态)"]
BestSkill["🏆 best_skill.md<br/>(全局最优)"]
end
Skill --> R1
Tasks --> R1
R1 --> R2
R2 --> R3
R3 --> R4
R4 --> R5
R5 --> R6
R6 -->|"accept_new_best"| BestSkill
R6 -->|"accept"| NewSkill
R6 -->|"reject"| Skill
R5 -.->|"生成候选"| NewSkill
style Skill fill:#C7CEEA,stroke:#9FA8DA,color:#333
style Tasks fill:#C7CEEA,stroke:#9FA8DA,color:#333
style R1 fill:#E8D5F5,stroke:#CE93D8,color:#333
style R2a fill:#FFDAB9,stroke:#FFAB91,color:#333
style R2b fill:#FFDAB9,stroke:#FFAB91,color:#333
style R2 fill:#E8D5F5,stroke:#CE93D8,color:#333
style R3 fill:#E8D5F5,stroke:#CE93D8,color:#333
style R4 fill:#E8D5F5,stroke:#CE93D8,color:#333
style R5 fill:#E8D5F5,stroke:#CE93D8,color:#333
style R6 fill:#FFB3C6,stroke:#E57373,color:#333
style NewSkill fill:#B5EAD7,stroke:#80CBC4,color:#333
style BestSkill fill:#B5EAD7,stroke:#4DB6AC,color:#3332.2 关键设计:Trainable State = Skill Markdown
整个 ReflACT 的核心抽象是把 skill 文档当作可训练状态。具体来说:
1 | # skillopt/types.py - 核心数据模型 |
关键设计决策:
- Edit 的 4 种操作 (
append/insert_after/replace/delete) 完整覆盖 markdown 文档的修改需求。 support_count字段:记录这个 edit 被多少个 trajectory 支撑——这是”梯度大小”的近似。source_type区分 failure / success:失败驱动的 edits 优先级高于成功驱动的(更稀缺信号)。- Markdown 而非代码:skill 是给 LLM 读的,不是给机器执行的——所以可读性 > 形式化。
2.3 类比神经网络:ReflACT ↔ SGD
| 神经网络 | ReflACT | 含义 |
|---|---|---|
| 模型参数 θ | skill markdown | 待优化的”状态” |
| Loss L(θ) | rollout score (hard/soft) | 评估函数 |
| ∇L(梯度) | edit patch(编辑指令) | 状态更新方向 |
| Batch size B | minibatch_size | 一次反思用多少 trajectory |
| Learning rate η | max_edits per step | 一次更新最多改多少处 |
| LR scheduler | constant/linear/cosine/autonomous | 学习率衰减策略 |
| Validation set | val split(held-out) | 验证门的数据源 |
| Early stopping | gate reject | 拒绝过拟合的更新 |
| Epoch | 一轮 train_size / batch_size 步 | 数据遍历一遍 |
这是 SkillOpt 最重要的设计哲学:把所有”玄学”变成”可量化、可调参、可复现”的工程量。
三、核心机制原理(带可运行代码)
3.1 机制 1:Held-out Validation Gate(验证门)
这是 ReflACT 区别于其他”训练 skill”方法的关键。其他方法都靠 LLM 自己”判断”新 skill 好不好,但 ReflACT 用 held-out 验证集 + 纯函数判断,保证 skill 严格提升才接受。
1 | # skillopt/evaluation/gate.py - 验证门(纯函数,无 LLM 调用) |
设计要点:
- 纯函数 + 不可变 dataclass:
evaluate_gate没有任何副作用,只返回决策——易于测试、易于在 WebUI 里可视化。 - 三态决策:
accept_new_best/accept/reject区分”接受且创新高”和”接受但未创新高”——后者允许探索但保留 best。 - 三种 metric 切换:
hard适合”答对/答错”二值;soft适合小样本 F1;mixed是默认推荐(加权平均,对小 batch 更鲁棒)。
3.2 机制 2:Protected Region(受保护区)+ 4 种原子 Edit
SkillOpt 用 markdown 注释作为受保护边界,防止高频 step-level edit 破坏 epoch-level 战略指导。
1 | # skillopt/optimizer/skill.py - Edit 应用 + 保护逻辑 |
机制巧思:
- 两层作用域隔离:
SLOW_UPDATE是 epoch 级战略层(每 1 个 epoch 重写一次),APPENDIX是 skill-aware 反思层(每 step 累加)。Step-level 的R2 Reflect不能动这两个区,保证战略稳定性。 - append 插在保护区”前面”:所有 step-level 新增内容会自动堆在保护区上方,自然形成”战术区 / 战略区”分层。
- JSON 报告:
status字段 (applied/skipped_protected_region/skipped_target_not_found) 让 trainer 知道每个 edit 实际命运,便于事后审计。
3.3 机制 3:LR Scheduler(文本学习率调度器)
“学习率”在 ReflACT 里 = 一次 step 最多能改几处 (max edits)。调度器控制这个数字如何随训练变化。
1 | # skillopt/optimizer/scheduler.py - 学习率调度器 |
调度器选择建议:
| 场景 | 推荐 scheduler | 原因 |
|---|---|---|
| 第一次跑 baseline | constant (max=4) | 简单可复现 |
| 已知 skill 体量大 | cosine (max=8, min=2) | 先粗后细 |
| 想做探索性研究 | autonomous | 让 LLM 决定 |
| 小数据集 | linear (max=6, min=1) | 避免过拟合 |
3.4 机制 4:Hierarchical Aggregate(层级合并)
多个 trajectory 的 patch 不能直接拼接——会有矛盾和重复。ReflACT 用 LLM 做层级合并。
1 | # skillopt/gradient/aggregate.py - 层级合并 |
关键设计:
- Tree-reduce 并行:
ThreadPoolExecutor(max_workers=16)让同层 batch 同时 merge,把 O(N) 串行变成 O(log N) 树形。 - 3 层 fallback:LLM merge → 直接拼接 → 失败丢弃,保证训练不会因为 LLM 出错而中断。
merge_level标记:每个 edit 记录它在 merge 树里的深度,便于后续分析哪些 edit 来自”跨多 trajectory 共识”。
3.5 最小可运行 Demo:3 步训练一个 SearchQA Skill
下面是一份可以在 SkillOpt 仓库直接跑的最小 demo(基于 SearchQA 环境,400 个训练样本,4 个 epoch,constant LR=4):
1 | """ |
运行:
1 | git clone https://github.com/microsoft/SkillOpt |
预期结果(基于论文报告的 SearchQA 数字):
- 起始 baseline:~50% exact match
- 训练 2 epoch 后:~60-65%
- 训练 4 epoch 后(论文设置):~75-80%
- 提升幅度:+15-30 个百分点
四、与同类项目的设计对比
4.1 对比矩阵
| 维度 | SkillOpt (Microsoft) | Superpowers (obra) | affaan-m/ECC |
|---|---|---|---|
| 定位 | Skill 训练器 | Skill 框架/加载器 | Skill + Memory + Instincts 全家桶 |
| 形态 | Python 库 + WebUI | 14 个 markdown skill + harness | Claude Code plugin |
| Skill 进化 | ✅ ReflACT 6 阶段循环 | ❌ 静态 skill,需手写 | ⚠️ ECC loop 简化版 |
| 验证机制 | ✅ Held-out gate (hard/soft/mixed) | ❌ 无 | ⚠️ Instincts 投票 |
| 学习率调度 | ✅ constant/linear/cosine/autonomous | ❌ 无 | ❌ 无 |
| 数据集划分 | ✅ train/val/test | ❌ 无 | ❌ 无 |
| 部署开销 | 0 推理时延(只训 markdown) | 0 | 0 |
| Star 数 | 9.5k | 33k+ | 222k+ |
| 论文支撑 | ✅ arXiv:2605.23904 | ❌ | ❌ |
4.2 三个关键设计差异
差异 1:训练范式 — SkillOpt 是”批处理”,Superpowers 是”加载”
- Superpowers 的核心是”14 个写好的 skill markdown”,模型启动时按需加载(progressive disclosure)。它解决的是”skill 怎么被找到和使用”,不是 skill 怎么被变好。
- SkillOpt 反过来:skill 怎么被”训练得更好”才是核心,skill 内容只是中间产物。
- ECC 走中间路线:把 skill / memory / instincts 三类状态混合训练,但没有像 SkillOpt 那样分 train/val/test 严格防过拟合。
差异 2:验证机制 — SkillOpt 唯一引入 Held-out Gate
- Superpowers 完全靠”用着好不好”的人工判断;
- ECC 靠 instincts 之间的”投票”决定保留哪个;
- SkillOpt 是唯一强制”在 held-out 数据上跑过、严格分高才接受”的方案——这直接借鉴了神经网络训练的 model selection。
差异 3:部署哲学 — “零推理时延”的极端优化
- SkillOpt 训完的
best_skill.md直接作为 system prompt 部署,不再需要任何额外调用。 - Superpowers 的渐进式披露每次需要 LLM 决定”要不要加载哪个 skill”,多了一次工具调用。
- ECC 的 instincts 维护需要后台进程。
结论:SkillOpt 适合”我已经知道在哪个固定任务上反复跑、想把 skill 调到极致”;Superpowers 适合”我想用现成 skill 库”;ECC 适合”我想做’Agent 全家桶’,但对每项精度要求没那么极致”。
4.3 为什么 SkillOpt 选择了”训练 markdown”而不是”训练 LoRA”
| 维度 | 训练 markdown (SkillOpt) | 训练 LoRA (典型方案) |
|---|---|---|
| 数据需求 | 几十~几百 trajectory | 几万~几十万 SFT 样本 |
| 训练成本 | 几美元(GPT-4o-mini) | 几百~几千美元 |
| 跨模型迁移 | ✅ 直接迁移到任意 chat 模型 | ❌ 需要每个模型单独训 |
| 可读性 | ✅ 人能读懂、能改 | ❌ 黑盒 |
| 推理时延 | 0 | 略增(LoRA forward) |
| 极端任务 | 略弱 | 略强 |
SkillOpt 押注的是”agent skill 80% 的价值在文本指令,20% 在参数”——这是一个有争议但很有数据支撑的赌注(论文里跨模型迁移实验证实)。
五、优缺点分析(按维度对比)
5.1 左侧:架构简洁性 / 扩展性 / 易用性
| 维度 | 评分 | 说明 |
|---|---|---|
| 架构简洁性 | ⭐⭐⭐⭐ | 6 阶段清晰分层;Edit/EditOp/Patch/GateResult 数据模型极简 |
| 扩展性 | ⭐⭐⭐⭐⭐ | 加新 benchmark 只需实现 EnvAdapter(5 个抽象方法);加新 backend 只需写一个 _backend.py |
| 易用性 | ⭐⭐⭐ | 上手需要懂 trainer / dataloader / env 三个概念;CLI 不够友好;WebUI 实验性 |
| 学习曲线 | 中等 | 比 LangChain 平缓,但比纯 prompt 工程陡 |
5.2 右侧:性能 / 复杂度 / 维护性
| 维度 | 评分 | 说明 |
|---|---|---|
| 性能 | ⭐⭐⭐⭐⭐ | 加 +23.5pp(论文数据);推理时 0 开销 |
| 复杂度 | 高 | 11 万行 trainer.py;6 阶段 + 4 模式(patch/rewrite/rewrite_minibatch/full_rewrite) |
| 维护性 | ⭐⭐⭐ | 微软研究院维护(v0.1.0 PyPI 刚发);prompt 模板多(21 个 .md);版本升级需小心 |
| 依赖成本 | 中 | OpenAI/Anthropic/Claude Code/Codex 4 个 backend 都要分别适配;prompt 缓存要自己实现 |
5.3 适用与不适用场景
| ✅ 适合 | ❌ 不适合 |
|---|---|
| 任务分布稳定(QA / 表格 / 编码) | 任务分布高度动态(每天新领域) |
| 有清晰正确性信号(accuracy / F1) | 没有可量化的”对/错”(开放式创作) |
| 长期复用的 Agent(你的开发助手) | 一次性 demo / hackathon 项目 |
| 团队愿意写 benchmark + dataloader | 只想跑 5 分钟看效果 |
| 想跨模型迁移 skill | 强模型绑定(如必须用某个闭源模型) |
六、从零搭建:MVP Skill 训练管线
如果我下周要在自己项目里复刻这套,我会怎么做?
6.1 最小可行实现(MVP)— 200 行 Python
核心循环(伪代码转真代码):
1 | """mvp_skill_trainer.py - 200 行复刻 SkillOpt 核心循环""" |
6.2 哪些组件必须有,哪些可以省略
| 组件 | 必须 | 原因 |
|---|---|---|
| Train/val/test split | ✅ | 没 val 集就无从判断 skill 是否真提升 |
| Held-out gate | ✅ | 核心机制,省了就退化成”自己说自己好” |
| Minibatch reflect | ✅ | 单条 reflect 容易过拟合到单 trajectory |
| Protected region | ⚠️ 可选 | 短期训练不需要;多次 epoch 后强烈建议加 |
| LR scheduler | ⚠️ 可选 | constant 也能跑,加 cosine 收敛更稳 |
| Slow update | ❌ 可省 | 4 epoch 内收益小,10+ epoch 才有显著效果 |
| Hierarchical merge | ❌ 可省 | < 100 patches 不需要;上千再考虑 |
| WebUI | ❌ 可省 | 终端 + log 足够;想做产品再上 |
6.3 踩坑预警(实际集成时会遇到)
- LLM 输出不是有效 JSON — 必须写 retry 逻辑 + JSON 解析兜底(SkillOpt 的
extract_json处理了 8 种变体)。 - Gate 太严格导致学不动 —
metric="hard"在小 batch 上会全 reject,改metric="mixed"+ 调高mixed_weight(如 0.7)。 - Skill 越训越长,token 成本爆炸 — 监控
len(skill) / baseline_len比例,超过 3x 考虑加lr=cosine加速收敛。 - Reward hacking:模型学会”钻 metric 漏洞” — 软分数(soft metric)能缓解;强信号任务(QA)几乎不会,弱信号任务(创作)风险高。
- 跨模型迁移时 skill 失效 — skill 里写了”用 gpt-4 的方式思考”,切到 claude 后反而变差。解决:skill 文本要写”行为约束”而非”模型假设”。
七、行动建议:什么场景下你应该用 SkillOpt
7.1 立刻用的 3 个信号
✅ 你的 Agent 任务在 5 个以上同类问题上反复跑(如”每周 50 个 PR 审查”)
✅ 你有可量化的对错信号(单元测试 / exact match / F1)
✅ 你愿意花 2 天搭 benchmark + dataloader,换长期 30%+ 准确率提升
7.2 先观望的 3 个信号
⚠️ 你的任务每次都不一样(一次性咨询类)——skill 没机会被训练
⚠️ 你的”对错”无法量化(创意写作、UI 设计)——gate 失效
⚠️ 你的训练数据 < 50 条——小样本下 ReflACT 容易过拟合
7.3 三个层次的复刻路径
| 层次 | 时间 | 你能获得 |
|---|---|---|
| L1: 跑通 demo | 1 天 | 在 SearchQA 上看到 60%→75% 提升 |
| L2: 接入自己的任务 | 1 周 | 自定义 dataloader / adapter;自己数据上 +10-20% |
| L3: 魔改核心算法 | 2-4 周 | 改 Reflect prompt / 加 Slow Update / 接入 RAG-as-skill |
八、总结:Skill 训练是 Harness 工程的”第二曲线”
如果把 Harness 6 件套(Rule / Skill / Sub-Agent / Workflow / Script / MCP)当成一个”AI 应用的工程栈”,那 Skill 训练 就是栈里唯一一个”会随时间自动变好”的组件。其他五件都需要人维护,唯独 Skill 可以在固定任务上自我进化。
SkillOpt 给出的核心方法论:
- Skill 是 trainable state,不是 prompt——给它 mini-batch、给它 learning rate、给它 held-out 验证集。
- 6 阶段循环是类比 SGD —— Rollout / Reflect / Aggregate / Select / Update / Evaluate 每一步都有对应。
- 零推理时延 —— 训练产物是纯 markdown,可以直接作为 system prompt 部署。
- 跨模型可迁移 —— 训好的 skill 切到其他 chat 模型也能用。
2026 年的 AI 工程领域,”让 Agent 越用越聪明“已经从口号变成可落地的工程实践。SkillOpt 正是这条路上目前最严谨、最工程化的开源方案。
下一步值得关注的演进方向:
- 多 skill 联合训练(Multi-Skill ReflACT):现在只能训一个 skill,未来可能多个 skill 一起训并处理冲突。
- Skill 蒸馏回模型权重:当 skill 训练稳定后,能否反向把 skill 知识蒸馏回 LoRA,让”有 skill”和”无 skill”在性能上无差。
- 在线学习:现在的 ReflACT 是离线训练,未来可能做成”每次跑任务时实时更新”。
行动召唤:如果你手头有反复跑的 Agent 任务,今天就花 1 小时做一件事 —— 把任务的 50 个实例 + 答案贴进 spreadsheet,分成 40 train / 10 val,套上面的 200 行 MVP 代码跑一遍。你会惊讶于”光靠改 skill 文本”就能拿到 15-30% 提升。
参考资料
- 项目仓库: github.com/microsoft/SkillOpt (9.5k⭐, MIT)
- 论文: SkillOpt: Executive Strategy for Self-Evolving Agent Skills (arXiv:2605.23904)
- 项目主页: microsoft.github.io/SkillOpt
- PyPI: pypi.org/project/skillopt (
pip install skillopt) - Sleep 模式文档: docs/sleep/README.md
- 对比项目:
- Superpowers (obra/superpowers)
- affaan-m/ECC (222k⭐)
- Harness Engineering 系列:
- 2026-06-26《Harness Engineering 6 大开源项目横评》
- 2026-06-27【AGENTS.md】Harness 6 件套之 Rule 组件
- 2026-06-28【SkillOpt】Harness 6 件套之 Skill 组件(本文)
作者注:本文 Skill 组件专题是 Harness 6 件套系列的第 2 篇。下一篇将进入 Sub-Agent 组件专题——解构 OpenHands / AutoGen / Claude Code Subagents 是如何做 Context 隔离与角色分工的。