将 Skill 视为可训练权重,用梯度下降思路迭代编辑:冻结执行模型、split train/selection/test 集、用 gate 拒绝编辑,是 SkillOpt 论文的工程复现。
一个 skill 是一份简短的 markdown 指令文件,模型在执行任务前会先读取它。大多数人都是手动编写,然后在几个例子上试运行。问题在于,听起来合理的建议反而可能让效果变差,而没有评分你根本察觉不到这一点。
于是我们选择训练一个。方法来自微软 SkillOpt 论文(arXiv 2605.23904)的精简版:把 skill 当作权重来对待——改动它、打分、只有在未从其构建的タスク上分数提升时才保留改动。
本文由 AI 助手辅助撰写,并对照了仓库的 README 文件——以下所有数字的唯一来源。
执行任务的模型永不改变。
将任务划分为 train、selection 和 test 三部分。Train 提供证据,selection 决定保留什么,test 只在最后触碰一次。
用当前的 skill 运行学生在 train 任务上,记录它的行为。
一个独立的优化器模型读取失败案例,针对反复出现的模式提出修改建议。
每步少量修改(这里是 4 条,然后 3 条,再然后 2 条),这样一次拒绝能让你知道该怪哪条思路。
在 selection 任务上给候选方案打分。只有分数严格更高时才保留。
这个 skill 教模型驱动 agent-browser CLI。学生:Opus 5.5,headless 模式,只使用 Bash 工具。优化器:Claude Fable 5.1。任务划分:13 个 train,8 个 selection,11 个 test。Opus 在无 skill 的情况下就把所有任务做对了,所以分数同时考虑 token 消耗。每个候选方案在 selection 切分上各运行两次。
留出的 test,11 个未见任务,各运行两次:
三条编辑建议中有两条让结果变差,而这三条读起来都像是合理的建议。只有门控能区分它们。
四条有帮助的修改移除的都是模型无法事先知道的冗余操作:将多条命令批量合并为一次调用;不要用 && 把工作链到 open 上,因为页面尚可使用时它可能已超时;处理 JavaScript 对话框和右键菜单的方法;以及一个简短的命令列表,让模型不再反复调用 --help。
那条帮倒忙的修改是一条预防规则:"绝不要在你没见过的页面上猜测选择器"。它在本来靠猜测就能完成的任务上额外加了一次快照调用。
上一个运行需要浏览器且花费真金白银。所以仓库里还附带了一个小型 starter:18 个玩具任务,配合代码检查器,分为三个系列(发票备注转 JSON、用内部格式重写备注、构建文件名)。
任务会要求一种内部风格(日期格式、ID 填充、文件名),但从不说明它是什么。模型无法猜到,所以无 skill 的得分设计为零。风格规范要写在 skill 里。
学生:claude -p --model haiku。优化器:Sonnet。
所有注意事项都是真实的。这只是从 0 到 10 的第 1 步,并非一步登天,而且只有一个候选方案,所以不存在拒绝。每格 12 次 rollout,一个任务 8 分。优化器把一些训练示例粘贴到了 skill 里,违反了我们的指令。虽然没有一个是 selection 或 test 的输入,但这是个需要警惕的泄露风险。
我们还用同一个 c1 skill(在 Haiku 上训练)跑了一个本地 Ollama 模型(qwen3.8:27b,4-bit)。无 skill 时得了 0/18。加上 c1 后在 test 切分上得到 5/6。这只是一次在 6 个任务上的运行,且该 skill 从未针对那个模型调优过。
从更弱的学生或更难的任务入手。在强模型的情况下,浏览器运行几乎没有剩余空间可供训练。
生成更多候选方案,让门控展示一次拒绝,而不仅仅是接受。
在 selection 上运行更多重复,并确保每个任务单独通过后才去怪罪 skill。
把训练示例从提案中剥离出去,再使其成为候选方案。
# setup
git clone https://github.com/proskillpacks/skillopt-agent-browse && cd skillopt-agent-browse/starter
# 1. baseline (mostly FAIL, by design)
python3 run.py --skill none --split sel --tag baseline --model haiku
# 2. roll out the seed on train
python3 run.py --skill skill/seed.md --split train --tag seed-train --model haiku
# 3. reflect: ask an optimizer for at most 4 edits
python3 reflect.py runs/seed-train --skill skill/seed.md --ask --max-edits 4 --model sonnet
对于本地模型,设置 STUDENT_MODEL、OPENAI_BASE_URL=http://localhost:11434/v1 并加上 --adapter openai。完整步骤(含门控命令)见 starter/README.md。
小任务集、starter 里的玩具任务、每轮一个学生模型、每格二到十二次 rollout。请把这些数字当作方法论的演示,而非基准测试。
Repo: https://github.com/proskillpacks/skillopt-agent-browse Paper: https://arxiv.org/abs/2605.23904 Longer write-up (canonical): https://proskillpacks.github.io/research/how-we-train-skills/