Logo
热心市民王先生

研究方法

学术论文 方法论 技能优化

拆解 SkillOpt 的文本空间优化算法:rollout evidence、minibatch reflection、bounded edits、validation gate 和 slow/meta update

方法总览

SkillOpt 的算法可以理解为一个不更新模型权重的训练循环。可训练对象不是参数矩阵,而是一个自然语言技能文档。目标模型负责执行任务,优化器模型负责从执行轨迹中提出技能编辑,验证集负责决定编辑是否进入当前技能。

flowchart TD
    A["当前技能 s_cur"] --> B["目标模型执行训练 batch"]
    B --> C["收集轨迹与评分"]
    C --> D["成功失败样本分组"]
    D --> E["minibatch reflection"]
    E --> F["合并候选编辑"]
    F --> G["按文本学习率裁剪"]
    G --> H["生成候选技能 s_candidate"]
    H --> I["selection split 评估"]
    I --> J{"是否严格提升"}
    J -->|是| K["接受为新当前技能"]
    J -->|否| L["拒绝并写入 rejected buffer"]
    K --> M["更新 best_skill.md"]
    L --> A
    M --> A

这个流程的关键不是某个单点技巧,而是多个控制机制共同防止“反思失控”:

  • 每次只允许有限编辑,避免自由重写破坏已有有效规则;
  • 每个候选技能必须通过 held-out gate,避免训练轨迹上的合理解释伤害泛化;
  • 被拒绝的编辑不丢弃,而是作为负反馈指导后续优化器调用;
  • slow/meta update 处理跨 epoch 的长期规律,但部署时只输出 compact skill。

形式化设置

论文把技能记为 ss,冻结目标模型记为 MM,执行 harness 记为 hh。给定任务 xx 和技能 ss,执行会产生轨迹和标量分数:

(τ(s),r(s))=h(M,x,s),r(s)[0,1](\tau(s), r(s)) = h(M, x, s), \qquad r(s) \in [0,1]

数据分为 train、selection、test 三部分:

  • DtrD_{\mathrm{tr}}:用于收集轨迹和生成候选编辑;
  • DselD_{\mathrm{sel}}:用于接受或拒绝候选技能;
  • DtestD_{\mathrm{test}}:只用于最终报告。

最终选择的是在 selection split 上最好的技能:

ssel=argmaxsC(Dtr)1DselxDselr(s)s^\star_{\mathrm{sel}} = \arg\max_{s \in \mathcal{C}(D_{\mathrm{tr}})} \frac{1}{|D_{\mathrm{sel}}|} \sum_{x \in D_{\mathrm{sel}}} r(s)

然后在 test split 上报告:

Test(ssel)=1DtestxDtestr(ssel)\mathrm{Test}(s^\star_{\mathrm{sel}}) = \frac{1}{|D_{\mathrm{test}}|} \sum_{x \in D_{\mathrm{test}}} r(s^\star_{\mathrm{sel}})

这个设置把 skill optimization 明确变成 train/validation/test 问题,而不是在测试集上反复试 prompt。

Forward Pass:rollout evidence

每个优化 step 开始时,目标模型用当前技能执行一批训练任务。harness 会记录:

  • task metadata;
  • messages;
  • tool calls;
  • observations;
  • command outputs;
  • final answers;
  • verifier feedback;
  • benchmark-specific context,例如 spreadsheet preview、document reference、execution trace。

这些轨迹就是 SkillOpt 的“训练数据”。和普通监督学习不同,它不是静态 (input, label),而是 Agent 在某个 skill 下真实执行后的行为证据。

论文特别强调 batch 的作用:单条失败轨迹容易诱导例子特化规则,而一批轨迹能暴露反复出现的程序性缺陷。例如,Agent 总是不检查 workbook 边界行,或者总是在 strongest-statement MCQ 里选择弱推论。

Backward Pass:minibatch reflection

优化器模型不会直接读完整 epoch 的所有轨迹并自由重写技能。它先把成功和失败分开,再分成 reflection minibatch:

flowchart LR
    A["rollout batch"] --> B["failures"]
    A --> C["successes"]
    B --> D["failure minibatches"]
    C --> E["success minibatches"]
    D --> F["提出 missing/corrective rules"]
    E --> G["提出 preserve rules"]
    F --> H["候选编辑池"]
    G --> H

失败样本主要产生补充性或纠正性规则,例如“保存后重新打开 workbook 检查目标范围是否填满”。成功样本主要保护已有有效行为,避免后续编辑删除关键策略。

这种设计的优点是:优化器模型看到的不是一堆孤立失败,而是“哪些失败模式反复出现、哪些成功行为需要保留”。这比单样本反思更接近训练中的梯度估计。

Structured Edits:add/delete/replace

SkillOpt 默认采用 patch mode,也就是让优化器提出结构化编辑,而不是直接生成一个全新技能文档。编辑类型包括 append、insert、replace、delete。论文也支持 rewrite mode,但主结果使用 patch edit。

结构化编辑的价值在于可审计和可控:

自由重写结构化编辑
可能一次改动过大改动范围有限
难追踪哪条规则导致提升或退化每个编辑有 apply report
容易覆盖已有好规则可以更好保留上下文
更像 prompt rewriting更像文本参数更新

编辑会先被层级合并:先合并 failure-driven edits 和 success-driven edits,再将两者合并,优先处理失败修正,同时过滤重复、矛盾、过度特化的建议。

Textual Learning Rate:文本学习率

SkillOpt 的 learning rate 不是数值梯度步长,而是每一步最多应用多少个编辑,记作 LtL_t。例如默认设置 Lt=4L_t = 4,并使用 cosine decay,最低为 2。

这个类比非常实用:

  • 大学习率:技能变化快,但容易破坏已有能力;
  • 小学习率:变化稳,但可能学习太慢;
  • 学习率调度:早期允许较大探索,后期偏向收敛。

论文的消融显示,不同 moderate learning rate 和 schedule 下结果相对稳定,但“没有学习率约束”的表现更差。这支持一个工程判断:文本空间优化也需要步长控制。

Validation Gate:严格验证门控

候选技能生成后,会在 selection split 上评估。只有当 selection score 严格大于当前技能时才接受;平局也拒绝。

这个规则看似保守,但它解决了自我反思类方法的核心风险:LLM 很擅长生成听起来合理的失败分析,却不保证这些规则真的改善目标模型行为。Validation gate 把“语言上的合理”转化为“行为上的有效”。

flowchart TD
    A["候选技能"] --> B["selection split 运行"]
    B --> C["候选分数"]
    D["当前分数"] --> E{"候选分数是否更高"}
    C --> E
    E -->|严格更高| F["接受"]
    E -->|不更高| G["拒绝"]
    G --> H["记录失败编辑与分数下降"]
    F --> I["可能更新 best_skill.md"]

论文把这个设计视为 SkillOpt 稳定性的核心。没有验证门控,反思输出会无条件进入技能,坏编辑会不断累积。

Rejected-Edit Buffer:把失败编辑变成负反馈

被拒绝的编辑不会直接丢弃。SkillOpt 会记录它们带来的分数下降和相关失败模式,形成 epoch-local rejected buffer。后续 reflection 会看到这些负反馈,从而避免重复提出已经验证无效的改法。

这相当于在文本优化里引入“不要再沿这个方向走”的记忆。它不同于普通 memory 的地方是:它不部署给目标 Agent,只用于训练时指导优化器模型。

Epoch-Wise Slow/Meta Update

SkillOpt 还有一层跨 epoch 的长期更新。

每个 epoch 末尾,系统会用上一 epoch 的技能和当前技能在相同样本上对比,把样本分为:

  • improvements;
  • regressions;
  • persistent failures;
  • stable successes。

优化器模型据此写入一个 protected slow-update field,记录长期、稳定的领域规律。这个 slow update 仍要通过 validation gate。与此同时,optimizer-side meta skill 记录哪些编辑模式有用、哪些被拒绝、哪些失败仍然存在。meta skill 只用于训练侧,不随 best_skill.md 部署。

这个设计可以理解为两层状态分离:

状态用途是否部署给目标 Agent
best_skill.md目标 Agent 使用的技能
slow-update field技能内部长期规律是,但受保护且验证
meta skill指导优化器如何继续编辑
rejected buffer训练期负反馈

实验设置

论文在 6 个 benchmark 上评估:

Benchmark类型主要考察能力
SearchQAQAextractive question answering
SpreadsheetBench表格代码与工具使用workbook inspection、公式/静态值处理
OfficeQA工具增强文档 QA多轮工具调用、格式纪律
DocVQA文档视觉问答表格/表单/图例定位
LiveMathematicianBench数学 MCQtheorem strength、严谨选择
ALFWorldembodied decision making搜索、状态管理、长期动作规划

目标模型覆盖 GPT 系列和 Qwen 系列,执行模式包括 direct chat、Codex harness、Claude Code harness。对照方法包括 no skill、human skill、one-shot LLM skill、Trace2Skill、TextGrad、GEPA 和 harness 侧 EvoSkill。

默认超参数包括:

参数默认设置
epochs4
rollout batch size40
reflection minibatch size8
analyst workers16
textual learning rate4
schedulecosine decay,floor 2
validation gate严格提升才接受
slow update每 epoch 20 个样本
edit modepatch

对于 LiveMathematicianBench 和 ALFWorld 等训练池较小或交互模式特殊的 benchmark,论文按任务配置调整 batch size,但保留 gate、scheduler、slow/meta update 等核心机制。

方法的本质

SkillOpt 不是让模型“多反思几次”,而是把反思包进一个训练系统。它真正优化的是一个可部署文本 artifact,同时用训练侧状态维持探索、记忆和验证。这个结构使它更接近机器学习优化器,而不是一次性 prompt engineering。