Skill Issue 阅读笔记:如何真正优化代码仓库里的 Agent 技能

笔记日期: 2026-09-14
作者: Zhongzhu Zhou
阅读论文: Skill Issue: Lessons from Optimizing Repository SKILLs for Coding Agents
论文作者: Mykhailo Kozyrev, Andrei Kozyrev, Anton Podkopaev
arXiv: 2609.12742v1
会议/状态: 预印本,2026 年 9 月

1. 这篇论文在问什么

代码仓库里的 SKILL.md 看起来只是一个普通 Markdown 文件。它可以告诉 Agent 如何构建项目、模块之间怎样依赖、哪些测试命令最可靠、哪些局部约定容易踩坑。它能像源码一样进入版本控制、经过 PR 审核,也不需要额外向量数据库。

真正困难的问题不是「文件里能不能写有用知识」,而是:

优化器能否自动发现一组知识,让固定的代码 Agent 在未来仓库任务上稳定变好?

论文没有用漂亮文档的主观评分来回答,也没有选择已被强模型刷到接近满分的简单合成任务。作者从真实合并 PR 中挖任务,在同一个冻结版本上反向撤销修复,再把「加载候选技能」与「加载空技能」的两次轨迹逐任务配对比较。

结果很克制:

  • GEPA 的平均配对分数提高 4.9 个百分点;
  • SkillOpt 只提高 0.1 个百分点;
  • 三个仓库的测试集都太小,无法把这种幅度与 Agent 自身重跑波动区分开;
  • 但仓库维护者确实在生成文档里看到需要长期参与项目才能掌握的知识;
  • 两个真实开放 issue 上,加载技能后的成本和用时明显下降。

我认为这篇论文最重要的主题不是「哪个文本优化器更强」,而是 Agent 测量工程:任务怎么造、对照组怎么设、指标到底测了什么、样本量够不够支持结论。

图 1:仓库技能优化的整体架构;模型、工具、预算与仓库版本固定,唯一变化的是 Markdown 技能。

2. 前置知识

2.1 代码 Agent 的随机轨迹

代码 Agent 会读文件、搜索符号、执行命令、修改代码、运行测试并根据反馈恢复。给定任务 xx、模型 MM、工具 TT、限制 LL 与技能 ss,轨迹可写成:

τH(M,T,L;,x,s)\tau \sim H(M,T,L;,x,s)

即使所有可见条件完全相同,两次运行也可能走不同路径。因此「这次带技能成功、这次不带技能失败」还不是稳定的因果证据。

2.2 仓库知识与通用建议

真正有价值的仓库知识通常可验证、可定位:

  • 某个模块应该运行哪个 Gradle task;
  • Kotlin multiplatform 的 source set 允许怎样依赖;
  • 哪个 annotation 会注册工具;
  • 哪类改动必须更新哪组测试。

「先读 README」「尽量保持 diff 小」是通用卫生习惯,通常没有坏处,却会占用上下文。好技能追求的是单位 token 中可行动的局部信息,而不是文采。

2.3 反事实任务

一个已合并 PR 给出了现实中的修复。基准要构造另一个世界:修复被撤销,周围仓库仍保持当前状态,原补丁对 Agent 不可见,而测试可以验证它是否重新解决问题。

2.4 训练、选择与测试集

文本优化也会过拟合。训练集提供反思材料;选择集决定保留还是拒绝一次改写;测试集只在最后使用。一个仓库即使留下约 100 个任务,三路切分后测试集也只有 20–26 个,这正是后文统计功效不足的根源。

3. 完整系统:两个相互嵌套的循环

数据循环把仓库历史变成可评分任务:

  1. 固定一个当前 base commit;
  2. 拉取已经合并的 PR;
  3. 分开实现改动与测试改动;
  4. 在当前 base 上反向撤销实现;
  5. 对撤销前后分别跑测试;
  6. 只保留能让原本通过的测试发生孤立失败的任务;
  7. 删除 Git 历史并清理问题描述中的泄漏。

优化循环把 Agent 轨迹变成候选技能:

  1. 选择技能候选与任务小批次;
  2. 运行固定代码 Agent;
  3. 与同任务的空技能轨迹比较;
  4. 让反思模型阅读轨迹与反馈;
  5. 重写整份文档或执行受限编辑;
  6. 按 GEPA 或 SkillOpt 的规则保留候选;
  7. 最后在未见测试集上评估。

图 2:单一冻结版本上的反向 PR 数据流;每一层都是任务有效性闸门。

干预量可以写为:

Δ(x,s)=Q(τx,s,τx,)\Delta(x,s) = Q(\tau_{x,s},\tau_{x,\varnothing})

这里 QQ 比较候选技能轨迹与空技能轨迹。模型、harness、工具、回合上限、容器和 base commit 都保持不变。

3.1 为什么必须用同一个冻结版本

最直接的替代方案是正向构造:回到每个 PR 的 parent commit,应用测试补丁,让 Agent 重做实现。这能得到更多任务,但每个任务属于不同历史时刻。

如果优化器同时看到数月历史,它会把不同版本的路径、API 与模块布局写进同一技能。论文早期实验甚至生成了「先判断当前仓库属于两种形态中的哪一种」这类建议;实际上只是同一个仓库的不同时期。

冻结 base 用任务数量换时间一致性。它适合仍能映射到当前树的历史改动;遇到全局重命名、模块迁移或架构重写就会大量丢任务。Tracy 仓库 203 个 PR 最终只保留 5 个。

3.2 空技能基线意味着什么

空技能只有标题,没有建议。它回答「自动发现的全部文本比没有文本多贡献多少」。生产中更现实的对照可能是已有 AGENTS.md 或维护者手写指南;因此论文估计的是总效应,不是相对成熟文档的边际效应。

4. 算法一:反向 PR 任务挖掘

合并 PR 不能直接当任务。方法必须撤销修复,同时保证当前仓库仍可构建、失败测试确实对应这个改动。

编号伪代码:反向 PR 挖掘

  1. 把仓库冻结在 base commit bb,运行完整测试。
  2. 记录在 bb 上通过的测试集合 PbP_b
  3. 对每个合并 PR rr,按路径拆分实现补丁 IrI_r 与测试补丁 UrU_r
  4. 首先尝试精确反向应用 IrI_r
  5. 若失败,按文件结构撤销新增与删除文件。
  6. 对剩余且尺寸未超阈值的修改文件,让 LLM 根据当前源码与正向 diff 重建旧源码。
  7. 从重建后的工作树重新导出真实 Git patch,不直接信任模型生成的补丁文本。
  8. 静态检查缺失 import 与「留下答案实现但删掉调用点」问题。
  9. 在撤销后的树上运行测试。
  10. 定义隐藏目标 Fr=PbPrF_r=P_b\setminus P_r
  11. 如果 FrF_r 为空、目标测试原本已失败、失败扩散到无关区域、或 gold patch 不能恢复,则拒绝。
  12. PbP_b 抽取最多 30 个回归保护测试。
  13. 删除历史、清理 PR 链接;没有 issue 时生成并检查不泄漏答案的问题描述。
  14. 输出任务 (b,Ir,Fr,Gr,dr)(b,I_r,F_r,G_r,d_r)

核心集合差来自一个简单条件:评分测试必须在撤销前通过、撤销后失败。

Fr={t:tPb}{t:tPr}F_r = \{t:t\in P_b\} \setminus \{t:t\in P_r\}

如果 Fr=F_r=\varnothing,这个改动可能未被测试覆盖,或撤销后没有可观测影响。无论技能是什么,任务都无法提供区分信号。

4.1 三层撤销策略

第一层:精确反向 patch。 最便宜、最可信,但只能容忍很少代码漂移。

第二层:文件级结构撤销。 删除 PR 新增文件、恢复被删文件,可以处理结构性变更,却无法重建已经漂移的文件内部语义。

第三层:LLM 重建。 模型读取当前文件与正向 diff,推断修复前源码。它贡献了大部分产量:koog 的 119 个评分任务中只有 25 个能干净反向应用;kotest 是 56/100,ktor 是 65/131。

为什么不用普通三方 merge?因为周围代码大幅变化后,机械 merge 没有足够上下文恢复意图。为什么不直接采用 LLM 的 patch?因为自由文本会夹带语法错误或无关修改;从真实工作树重新导出 diff 更可审计。

4.2 动态验证看不见的缺陷

只要撤销使测试失败,动态闸门就可能误判。模型删掉仍被使用的 import,会让编译失败,看起来像「目标测试被破坏」;也可能删除调用点,却留下包含答案的 private helper。

在 koog 一个 280 任务中间池上,静态检查剔除 56 个:36 个缺 import,26 个遗留修复,6 个两者兼有;其中 36 个此前已经通过动态验证。这个数字说明:验证器只能验证它明确测量的属性。

5. 算法二:配对轨迹评分

绝对通过率主要反映任务容易程度。如果空技能已经能做对,候选技能即使毫无作用也拿到同样分数。论文改为逐任务比较候选与基线。

编号伪代码:配对评分

  1. 读取任务 xx 已保存的空技能轨迹 zxz_x
  2. 在完全相同 harness 中加载候选技能 ss,得到轨迹 ax,sa_{x,s}
  3. 如果只有一方修改测试,或声称成功但自己的测试日志否定它,则该方输。
  4. 否则,如果只有一方通过所有 FAIL_TO_PASS 与回归保护测试,则该方赢。
  5. 如果正确性仍不能区分,再计算通过比例、陈述诚实度、diff 尺寸、工具调用数。
  6. 把次级特征限制在小范围,保证便宜但错误的 patch 不能超过正确 patch。
  7. 候选赢返回 11,输返回 00,完全相同返回 0.50.5
  8. 对切分中所有任务取平均。

单任务分数是:

qx(s)={1,ax,szx,12,ax,szx,0,ax,szx.q_x(s) = \begin{cases} 1, & a_{x,s}\succ z_x,\\ \tfrac{1}{2}, & a_{x,s}\equiv z_x,\\ 0, & a_{x,s}\prec z_x. \end{cases}

nn 个任务的总分:

S(s)=1ni=1nqxi(s)S(s) = \frac{1}{n} \sum_{i=1}^{n} q_{x_i}(s)

空技能与自身比较必然为 0.50.5。中心化效应可展开为:

Δ^(s)=S(s)0.5=WL2n\widehat{\Delta}(s) = S(s)-0.5 = \frac{W-L}{2n}

其中 WWLL 分别是候选赢和输的次数,平局抵消。这也解释了为什么 0.550.55 不是「55% 绝对成功率」,而只是相对 0.5 的五个百分点优势。

5.1 为什么要按字典序比较

正确性必须压倒省钱与 diff 小。若直接用加权和:

R=αCβDγKR = \alpha C - \beta D - \gamma K

权重一旦标定不当,一个极小、极便宜但错误的 patch 可能超过昂贵的正确 patch。字典序先处理作弊与正确性,仅在无法区分时考虑效率。

替代方案是 LLM judge。但看不到技能的 judge 只在评价补丁,不在评价技能贡献;看到技能的 judge 又可能奖励漂亮文档,即使 Agent 行为没改善。

5.2 配对减少了什么方差

配对控制任务难度,因为两次运行面对同一个 xx。它没有控制轨迹随机性。真正想估计的是:

Δx=E[Yx,s]E[Yx,]\Delta_x = \mathbb{E}[Y\mid x,s] - \mathbb{E}[Y\mid x,\varnothing]

实验却只从两个条件各抽一个样本。重复配对或共同随机数可以降低不确定性,但会线性增加昂贵的 Agent rollout。

6. 算法三与四:GEPA 和 SkillOpt 怎样改文档

6.1 GEPA:整份重写与 Pareto 候选池

编号伪代码:GEPA

  1. 用空技能 s0s_0 初始化候选池。
  2. 在选择集行为上维护 Pareto 前沿。
  3. 从前沿抽取父候选 sps_p
  4. 抽取训练小批次 BB
  5. 让目标 Agent 带 sps_p 运行 BB 中每个任务。
  6. 把分数、轨迹与文本反馈交给反思模型。
  7. 让反思模型完整重写技能,得到 ss'
  8. BB 上重新测 ss'
  9. 若相对父候选改善,则加入池,并在更大选择集上评估。
  10. 更新 Pareto 前沿,直到耗尽尝试预算。
  11. 返回最终选择候选。

整份重写可以重新组织冲突建议,跳出局部编辑限制;代价是可能删除好内容、引入泛化建议。选择集一旦噪声大,错误重写也可能幸存。

6.2 SkillOpt:有限编辑、严格闸门与拒绝记忆

编号伪代码:SkillOpt

  1. 初始化当前技能 s0s_0、编辑预算 e0e_0 与空拒绝缓冲区。
  2. 在训练批次运行 sts_t,拆分成功与失败轨迹。
  3. 让优化器提出 add/delete/replace 编辑。
  4. 去掉与本 epoch 已拒绝编辑相似的建议。
  5. 按预期效用排序。
  6. 最多应用 ete_t 个编辑,得到 ss'
  7. 在独立选择集评估 ss'
  8. 仅当 Ssel(s)>Ssel(st)S_{sel}(s')>S_{sel}(s_t) 时接受,否则保留旧文档并记录被拒编辑。
  9. 按计划衰减 ete_t
  10. 每个 epoch 结束,把稳定经验写入受保护的慢速/meta 区域。
  11. 三个 epoch 后返回最终技能。

编辑预算像文本空间的学习率:早期大步探索,后期小步稳定。拒绝缓冲类似 tabu search,慢速区域类似动量。

但严格改善闸门在小样本离散分数上很脆弱。选择集只有 mm 个任务时,分数常以 1/(2m)1/(2m)1/m1/m 跳变。一个真实有益编辑可能因为一次随机失败而被拒绝。

6.3 为什么本实验里 GEPA 更占优势

GEPA 可以保留多个行为不同的候选;SkillOpt 只有一条演化链,并要求每一步立刻测得改善。在高噪声、稀疏奖励下,候选多样性更有价值。

但不能据此推出「GEPA 普遍优于 SkillOpt」。这里只有三个仓库、每配置一次最终运行,两者预算、选择方式和成本也不同。可以说 GEPA 在本协议上赢了,不能把差异归因于某一个算法机制。

7. 数据集到底有多难挖

研究对象是 JetBrains/koog、kotest/kotest 与 ktorio/ktor。它们是 Kotlin/JVM 项目,不在 SWE-smith 的 Python AST 与 pytest 假设范围内。

仓库检查的合并 PR最终评分任务大致保留率
koog66011918.0%
ktor45213129.0%
kotest最终封顶 100100不可直接比较

一个新仓库要同时满足:

  • 历史 diff 涉及的文件在当前版本仍存在;
  • base 测试是绿色的;
  • 撤销一个改动会让至少一个原通过测试失败;
  • 失败只对应这个改动;
  • gold patch 能恢复;
  • 最终还剩足够任务做三路切分。

http4k 的例子特别有启发:700 个 PR 中 150 个可以反向应用,但行为验证后不足 100。历史多不等于信号多。

图 3(论文 §4.1):复现真实 PR 任务的修改规模、单文件比例与空技能基线通过率。

7.1 与合成 mutation 的区别

相关工作使用的 SWE-smith 公开任务中,修改行数中位数只有 4 或 7,98–100% 限于单文件。论文任务明显更大:

仓库修改行中位数文件数中位数单文件占比空技能解决率
koog54323%40%
ktor27250%66%
kotest16173%51%

空技能汇总解决率是 53%,终于给改进留出空间。若强 Agent 已把基准做到 95–100%,二元通过率几乎没有分辨率。

明显替代方案是换小模型或削弱 harness。它能制造 headroom,却会让技能针对代理 Agent 优化,而不是针对真正要上线的 Agent。作者选择保持生产级 harness,提升任务难度。

边界也很清楚:能存活的反向 PR 偏向路径稳定、测试充分的改动。大规模架构迁移、文档任务、依赖升级、跨服务变更往往被过滤,而这些可能恰好最需要仓库说明。

7.2 问题描述与答案泄漏

PR 描述写于实现之后,常直接暴露解决方案。没有关联 issue 时,作者用一次 LLM 调用把 PR 描述改写成 issue 风格,再与 gold patch 比对泄漏;容器里删除 .git、清理回链、重建单提交。

这些措施阻止直接复制历史,却无法消除语义提示。例如问题描述仍可能准确点名模块。未来应比较真实 issue、合成 issue 与极简描述三个条件。

8. 主实验结果怎么读

论文表 1 给出未见测试集的配对分数:

仓库GEPASkillOptGEPA 完全解决数变化SkillOpt 完全解决数变化
koog0.5250.546+1+2
kotest0.5540.519+3+1
ktor0.5670.437+4-2

GEPA 在三个仓库都高于 0.5;SkillOpt 两个提高、一个退化。按论文汇总,GEPA 平均 +4.9 个百分点,SkillOpt +0.1。

图 4(论文表 1):复现 GEPA 与 SkillOpt 的测试集配对分数;虚线为空技能自身比较的 0.5。

配对分数包含平局与受限次级指标,而「解决数变化」只数完全通过。因此候选可能没多解决几个任务,却在若干平局里更诚实、更省工具;也可能多解决一个任务,同时在其他任务上产生回退。两种视角必须一起报告。

8.1 钱与时间才是优化瓶颈

六次优化合计 API 花费 $2,013.98,墙钟时间 69.2 小时:

仓库GEPA 花费 / 时间SkillOpt 花费 / 时间
koog$368.82 / 4.7 h$401.44 / 8.14 h
kotest$182.48 / 4.9 h$263.56 / 13.3 h
ktor$312.87 / 13.0 h$484.81 / 25.2 h

图 5(论文表 1):复现各仓库优化 API 花费与墙钟时间。

单个候选在单个任务上的评分就是一次完整代码 Agent rollout,平均约 $0.84。生成 Markdown 很便宜,证明 Markdown 改变行为才昂贵。

所以「多跑一些样本」不是免费建议。更多测试样本、每任务重复次数、优化器探索宽度争夺同一预算。更好的实验设计应该把 rollout 自适应分给最不确定的候选。

8.2 维护者与真实 issue 证据

koog 维护者肯定了 multiplatform source set 边界、模块依赖方向等局部知识,也指出文档夹杂通用建议,并漏掉关键 @Tool annotation。

两个开放 issue 的结果:

Issue配置成本API 时间墙钟时间
#1275无技能$6.068m21s14m59s
#1275GEPA$2.483m35s5m32s
#1275SkillOpt$2.443m43s5m30s
#1354无技能$4.857m21s20m29s
#1354GEPA$3.104m52s7m38s
#1354SkillOpt$4.205m33s8m24s

图 6(论文表 2):复现两个真实 koog issue 上的 API 成本与墙钟时间。

只有六次运行,不能做普遍因果结论。但它揭示了二元通过率看不到的可能收益:技能先减少搜索与恢复成本,最终成功率才可能随后变化。

9. 统计功效:为什么不能把涨点当结论

只考虑候选与基线结果不同的任务。零假设下,若技能无效,两次轨迹可交换,候选赢的概率为 0.50.5。令 D=W+LD=W+L 为非平局数:

WBinomial(D,0.5)W \sim \operatorname{Binomial}(D,0.5)

单侧精确符号检验为:

p=Pr(XWD,0.5)=k=WD(Dk)2Dp = \Pr(X\ge W\mid D,0.5) = \sum_{k=W}^{D} {D\choose k} 2^{-D}

所有运行都没有达到 p<0.05p<0.05,最好也只有 p=0.29p=0.29

9.1 手算一个 20 任务例子

若恰好有 D=20D=20 个非平局任务,要让单侧概率低于 5%,至少需要 W=15W=15

Pr(X15)=(2015)+(2016)++(2020)2200.0207\Pr(X\ge15) = \frac{ {20\choose15} + {20\choose16} + \cdots + {20\choose20} }{ 2^{20} } \approx 0.0207

也就是候选要赢 75% 的分歧任务。55:45 这种小优势在此规模上完全看不见。论文概括:单仓库 20–26 个测试任务时,大约要赢四分之三到五分之四;汇总 69 个任务也要接近三分之二。

图 7:精确符号检验所需胜率随非平局样本数变化;阴影是论文单仓库测试集范围。

9.2 最小可检测效应的近似

用正态近似,只考虑显著性、不考虑 80% 检验功效时,检测胜率 pp 偏离 0.50.5 所需数量约为:

nz1α/220.25(p0.5)2n \approx \frac{ z_{1-\alpha/2}^{2} \cdot0.25 }{ (p-0.5)^2 }

α=0.05\alpha=0.05z0.975=1.96z_{0.975}=1.96,检测 p=0.60p=0.60

n1.9620.250.10296n \approx \frac{ 1.96^2\cdot0.25 }{ 0.10^2 } \approx 96

加入目标功效、平局、仓库异质性与轨迹随机性后还要更多。因此 20–26 个测试任务不可能可靠检出几个百分点的效果。

9.3 把三个仓库合并也不是免费扩样

合并到 69 个任务隐含两个假设:仓库效果相同、任务相互独立。但多个 PR 共享模块、测试和规范,每个仓库也只对应一份最终文档。更合理的层级模型是:

ΔrN(μ,τ2)\Delta_r \sim \mathcal{N}(\mu,\tau^2)

只有三个仓库时,仓库间方差 τ2\tau^2 本身也估不准。

正确表述不是「技能没有作用」,而是「实验无法识别这么小的平均作用」。维护者评价和开放 issue 仍有价值,只是它们回答的是文档质量和操作效率,而非总体通过率因果效应。

10. 关键设计选择:原因、替代与边界

10.1 真实 PR 对合成缺陷

为什么有效: 合并改动代表完整开发工作,经常跨文件,强 Agent 不容易饱和。

明显替代: 自动修改函数或断言,便宜且可无限生成。

边界: PR 任务受存活偏差影响;合成任务可精确控制能力维度。最理想的是混合基准。

10.2 反向构造对正向历史构造

为什么有效: 每个任务与技能事实都属于同一个可部署版本。

明显替代: 使用每个 PR 的 parent commit,获得最大 patch 适用率。

边界: 反向构造在代码漂移后损失任务;若技能能按 commit 检索,正向方法仍合理。

10.3 生产 Agent 对廉价代理模型

为什么有效: 不假设技能能从小模型迁移到真正消费者。

明显替代: 小模型筛候选,大模型最后验证。

边界: 直接优化成本高。只有先测出代理与生产模型的候选排序相关性,多保真搜索才可靠。

10.4 测试对 gold patch 或 judge

为什么有效: 测试可执行、相对确定,也能从未新增测试的 PR 中恢复评分目标。

明显替代: 计算与原补丁相似度,或让 LLM 判补丁。

边界: 测试看不到可维护性、架构、安全和潜在回归;gold 相似度惩罚等价解;judge 有校准偏差。

10.5 单 Markdown 对检索式记忆

为什么有效: 文件可审核、可版本化、可移植,不需要在线服务。

明显替代: 对历史轨迹做向量检索或持续更新记忆库。

边界: 单文档受上下文预算限制,也会过时。大型 monorepo 更适合带路由的层级技能。

10.6 严格接受对概率接受

为什么有效: SkillOpt 闸门可阻止测得退化,演化路径清晰。

明显替代: 保留不确定候选或维护候选群体。

边界: 小选择集上,一次随机波动就会冻结有益编辑。Bayesian racing 或序贯检验可只对边界候选加跑。

11. 复现清单

11.1 数据侧

  1. 固定仓库 URL、base SHA、PR 截止时间与分页顺序。
  2. 保存原始 PR 元数据和实现/测试分类。
  3. 记录每个文件采用哪层撤销。
  4. 保存重建树与 Git 重新导出的 patch。
  5. 记录每个闸门的剔除原因。
  6. 版本化静态检查器。
  7. 保存合成 issue 与泄漏审计结果。
  8. 私下保存 FAIL_TO_PASS 与回归保护集。
  9. 公开汇总流失率,不泄漏答案。

11.2 Agent 与优化器侧

  • 固定模型快照、harness、系统提示、工具、超时和回合上限;
  • 统一容器镜像、CPU/内存与网络策略;
  • 记录温度及解码控制;
  • 捕获工具调用、diff、测试日志、成本与延迟;
  • 在分层子集上重复空技能,估计自身波动;
  • GEPA 与 SkillOpt 使用相同切分和可比 rollout 预算;
  • 保存每一版候选及其 hash;
  • 维护者评价时隐藏优化器身份。

11.3 大规模花钱前的 sanity check

第一,gold patch 必须满分。第二,空技能与自身比较必须严格等于 0.5。第三,故意写错路径的有害技能应该输。第四,在少量任务上重复空技能,必须能看到噪声量级。第五,加入一个唯一且相关的仓库事实,应能在目标任务轨迹中观察到 Agent 使用它。

否则,平坦曲线可能有至少四种解释:优化器不行、指标没分辨率、Agent 根本没读技能、任务本身无效。

每次尝试建议记录:

字段用途
仓库 / base SHA状态身份
task / PR id数据来源
skill hash干预身份
baseline rollout hash配对身份
隐藏测试结果首要正确性
篡改与诚实标记安全闸门
diff 大小 / 工具数次级证据
成本 / 延迟运维结果

12. 我从论文中提炼的工程原则

12.1 优化信息,不优化文档观感

附录里有长文档占满 14 回合预算、最终没产出 patch 的例子。事实丰富不等于行动有效。真正目标是 Agent 在任务上的下游表现。

12.2 Headroom 不等于 power

把空技能解决率从接近满分降到 53%,只是让指标范围能移动;它并没有自动带来足够样本量。前者是天花板问题,后者是方差与效应识别问题。

12.3 稳定不变量比任务答案更值得写

维护者最认可 source-set 边界和模块依赖方向。这些规则跨任务存在。技能生成器应区分稳定约束与某个训练 PR 的事实,并给每条声明附作用域、证据路径、最后验证 commit 与置信度。

12.4 效率可能先于成功率改善

开放 issue 上,技能首先减少了探索、重试和墙钟时间。可以构造分层终点:正确性与回归安全作为硬闸门,然后比较首次有效测试时间、总成本、工具数和补丁复杂度。

13. 作者明确承认的局限

反向 PR 流程不会自动产生足量数据。至少约 100 个任务只是方便三路切分的操作下限,不是统计充分性的证明。

路径快速变化的仓库会在反向应用阶段失败;测试薄弱、flaky 或 base 已红的仓库会在行为验证阶段失败;没有孤立可执行效应的改动会消失。因此不能假设方法可迁移到任意仓库。

自动技能可能用权威口吻陈述过时或过度泛化的事实。它必须像代码 PR 一样经过人工审核;配对分数既不认证内容正确,也不认证安全。

维护者研究只有一个仓库的一位维护者,真实 issue 只有两个,不能当总体效果估计。

14. 批判性分析

14.1 论文本身的具体弱点

W1:研究重跑方差,却只保存一次空技能基线。 配对控制了任务身份,没有消除基线抽样误差。至少应对分层子集重复运行空技能,量化「基线运气」占多少不确定性。

W2:优化器比较被协议与预算混杂。 GEPA 和 SkillOpt 同时在编辑粒度、候选群体、接受规则、尝试数、花费和墙钟时间上不同。结果能说明谁在本协议上赢,不能说明哪一个机制导致差距。

W3:headline 没有充分拆开配对分数。 0.554 混合完全成功、平局和次级 tie-break。每仓库应公开「双方都过、仅技能过、仅基线过、双方都失败、篡改、仅靠 tie-break 获胜」列联表。

W4:任务流失改变了目标总体。 大重构和弱测试改动被系统性过滤。论文报告了数量,却没有对保留/剔除任务做语义类别比较。最终技能可能只适合稳定、测试密集的叶子改动。

W5:人工评价既不盲也没有重复。 一位 koog 维护者评价两份可能辨认来源的文档,没有多人一致性,也没有与维护者手写技能对照。

14.2 作者低估或遗漏的局限

U1:没有直接测上下文挤占。 技能占 token 与注意力。失败可能来自错误建议,也可能只是任务上下文被长文档挤掉,两者工程修复完全不同。

U2:删除 Git 历史不能消除模型记忆污染。 前沿模型可能在训练中见过公开仓库、API 或已合并改动。容器隔离阻止现场复制,却不清除参数记忆。

U3:任务相关性降低有效样本量。 多个 PR 共享模块、测试和规范。普通符号检验把任务当独立样本,实际统计功效可能更低。

U4:跨模型耐久性未知。 针对 Sonnet 4.6 优化的文本,在新模型或新 harness 上可能冗余、误导或被不同理解。仓库资产是否稳定,必须看跨模型迁移。

U5:安全问题需要专门协议。 仓库文本会影响可执行工具。自动优化可能保留 prompt injection、危险命令或面向测试的捷径,不能只靠行为分数管理。

14.3 可执行改进建议

I1:自适应重复配对。 所有候选先跑一次,只对置信区间重叠的候选追加 rollout。序贯概率比检验或 Bayesian racing 能把预算花在选择边界。

I2:发布分解结果与层级区间。 同时报告非平局胜负、完全解决变化、tie-break 贡献、仓库聚类 bootstrap,以及去掉各次级指标后的敏感性。

I3:构造混合任务套件。 合并反向 PR、正向历史任务、受控合成 mutation、架构问答与真实 issue,并按文件数、子系统、变更类型、测试强度标注。

I4:加入强人工基线。 在同等上下文与 rollout 预算下比较空技能、README/CONTRIBUTING、维护者技能、检索记忆、GEPA 与 SkillOpt。

I5:让技能声明带类型与证据。 每条局部事实附作用域、证据文件、最后验证 commit 与置信度;当路径或命令消失时由 CI 自动失效。

I6:改成约束优化。 正确性与安全放在硬约束内,在不降低通过概率的前提下最小化成本:

s=argminsE[C(s)]subject toPr(corrects)Pr(correct)ϵs^* = \arg\min_s \mathbb{E}[C(s)] \quad \text{subject to} \quad \Pr(\text{correct}\mid s) \ge \Pr(\text{correct}\mid\varnothing)-\epsilon

它能吸收真实 issue 的成本收益,又不会让便宜的错误方案赢。

I7:做模型与 harness 交叉迁移。 至少两种模型乘两种 Agent harness。跨配置都有效更像仓库知识;只在一个 harness 上有效更像 prompt 耦合。

14.4 我的总体判断

论文最强的是认识论纪律:它没有把 4.9 个百分点包装成显著改善,而是追问一个仓库为什么很难提供足够独立任务,并让维护者从指标之外检查文档。

最弱的是优化器比较没有评估框架本身那么有说服力。但这不削弱论文价值:在 Agent 系统里,建立有效干预与测量工具,往往比再提出一个优化循环更难。

15. 团队落地建议

如果团队准备引入仓库技能,我不会从全自动优化开始:

  1. 先请维护者写稳定不变量与常见陷阱。
  2. 每句话都要证明值得占上下文。
  3. 为命令、路径与模块规则附可执行证据。
  4. 在同一当前版本上回放真实历史改动。
  5. 同时对比空技能与已有文档。
  6. 除通过率外记录成本、时间和工具调用。
  7. 合并前必须由代码 owner 审核。
  8. 结构改动后自动重验。
  9. 技能版本与基准结果一起归档。
  10. 模型升级视为分布变化,重新评估。

只有当团队已经有可信任务生成器、足够多未饱和任务、并有预算重复 rollout 时,自动优化才值得投入。否则优化器只会放大基准缺陷。

16. 总结

Skill Issue 提出了正确的反事实问题:同一个代码 Agent 面对同一个仓库任务,加载这份文档后是否真的更好?

在单一冻结 base 上反向挖 PR,得到更难且时间一致的任务;逐任务配对评分削弱任务难度偏差。GEPA 平均移动 +4.9 个百分点,SkillOpt 几乎不变。但小测试集与随机轨迹使这些变化无法和偶然波动分开。

最可行动的发现来自定性与运维证据:维护者认可生成文件里的局部知识;两个真实 issue 在带技能时明显更便宜、更快。这意味着仓库技能可能先改善搜索效率与执行成本,之后才可能提高二元成功率。

因此我的结论是:版本化仓库知识很有前景,但优化它需要可靠任务、因果对照、统计功效与人工审核。文档写得像真的,不是证据;通过率动了几分,也未必是证据。论文真正的贡献,是让这些区别可以被讨论和测量。