当 AI 学会说这不是我的锅:SkillAA 让技能图谱学会精准归因与回滚

想象你是一个资深工程师,手下有个实习生叫小 G。小 G 脑子很聪明,但记不住流程细节,所以你给他写了一本"操作手册"——什么时候该查哪个数据库、什么时候该调用哪个工具、什么时候该跳过哪一步。

skillaa_nopatch.svg

一个尴尬的场景

想象你是一个资深工程师,手下有个实习生叫小 G。小 G 脑子很聪明,但记不住流程细节,所以你给他写了一本"操作手册"——什么时候该查哪个数据库、什么时候该调用哪个工具、什么时候该跳过哪一步。

某天小 G 在一个问答任务上翻车了。你翻看他的执行日志,发现问题出在第三步:他该查"巴拿马法院 1993 年定罪的领导人",却答了 Manuel Noriega 而不是标准答案 Noriega。

这时候你会怎么做?

A. 把操作手册重写一遍 B. 在手册里加一条"遇到人名时用简称" C. 修一下评分器,让它能识别别名 D. 什么都不改,因为这是评分器的问题

如果你选了 A 或 B,恭喜,你正在犯当前大多数 LLM 技能优化系统都在犯的错。

问题的根源:失败不等于"该改技能"

南京大学的 SkillAA 团队(尚子乔、葛凌越、郭兰哲)发现了一个被忽视的问题:当前所有"技能进化"系统都在用"失败 → 改技能"的单一映射,但真实场景里失败的原因五花八门——可能是技能写错了,可能是检索没找到关键证据,可能是模型视觉识别错了字符,甚至可能只是评分器太严格。

把所有失败都归因于"技能有问题",就像把所有 bug 都归因于"代码写错了"——有时候是硬件故障,有时候是数据缺失,有时候是需求文档自相矛盾。盲目改代码只会越改越坏。

SkillAA 的核心贡献,就是给"技能优化"这件事装上了一套精准归因 + 定向修复 + 闸门验证的工程化流水线。

核心设计:把技能变成"有地址的图"

SkillAA 的第一个关键决策,是把技能从一段段平铺的文本,变成一张有地址的有向图

每个节点不是一坨自然语言描述,而是被拆成三个结构化字段:

  • when_to_use:什么时候该用这个技能(触发条件)
  • how_to_use:具体怎么执行(步骤序列)
  • avoid:什么时候不该用(排除边界)
节点之间用带类型的边连接,比如 prereq(前置依赖)、enhance(增强组合)。

这个设计的好处是什么?每个可编辑的位置都有了地址。就像代码库里的 src/auth/login.py:42——当 bug 出现时,你能精确指向"就是这一行这个函数这个分支",而不是"整个登录模块重写一下"。

这就是 SkillAA 名字里 "Attribution"(归因)的真正含义:不是笼统地说"技能有问题",而是定位到具体哪个节点的哪个字段

六条归因路径:失败也有分类学

SkillAA 最有洞察力的设计,是定义了六条归因路径。当一次执行失败时,teacher 模型会对照执行记录诊断,把失败归入以下六类之一:

归因码失败条件授权的修改
MISSING_SKILL_FAMILY缺少整个技能新增节点 + 绑定边
MISSING_ACTIVATION_CUE技能存在但没被激活只扩展 when_to_use
HARMFUL_EXISTING_RULE现有语义导致错误只替换出问题的字段
MISSING_OR_INCORRECT_PROCEDURE步骤/边界/关系缺失补全 how_to_use 或 avoid
EXECUTION_LAPSE图是对的,但模型没按图执行NO_PATCH(不改图)
INSUFFICIENT_EVIDENCE证据不足以定位NO_PATCH(保留原图)
注意最后两行。NO_PATCH 是 SkillAA 的一等公民输出——当诊断发现"图是对的,是模型执行走样了"或者"证据不够,定位不到具体字段"时,正确做法是什么都不改

这个设计看似简单,实则深刻。当前所有技能进化系统都隐含一个假设:"失败了就该改点什么"。SkillAA 用 NO_PATCH 明确否定了这个假设——有些失败不是技能的锅,强行改图只会把好的技能改坏

两道闸门:像数据库事务一样管理技能修改

定位到该改哪里、提出了候选修改之后,SkillAA 不会直接提交。它设了两道闸门,像数据库的事务隔离机制一样层层把关。

Local Gate:局部回归测试

第一道闸门是局部级的。对于每个候选修改(或一组相互依赖的修改,称为 atomic group),SkillAA 只重跑可能受影响的用例:

  • 这个节点被哪些用例用过?(Q_use
  • 修改的源头是哪些用例?(Q_src
  • 用例记录缺失的也纳入(Q_unk
重跑后统计三个数:
  • n_fixed:原来错的现在对了
  • n_broken:原来对的现在错了
  • n_unresolved:原来错的还是错的
只有当 n_fixed > n_broken + n_unresolved 时,这个修改才被保留。否则,整个 atomic group 回滚——节点字段恢复原值,新增的节点和边一起撤销。

这就像数据库的行级约束:改了一行,先检查所有相关行的一致性,不一致就回滚。

Big Gate:epoch 级提交

第二道闸门是epoch 级的。所有通过 Local Gate 的修改合并成一个候选图 \(\tilde{G}^{(t+1)}\),在整个 update pool 上跑一遍:

  • n_corrected:原来错的现在对了
  • n_regressed:原来对的现在错了
只有 n_corrected > n_regressed 时,才提交这个候选图作为新的基准。否则,图和参考执行记录都恢复到 epoch 开始前的状态。

这就像数据库的 COMMIT:所有局部修改通过了行级约束还不够,整个事务必须让全局指标净正向才能提交。

关键实验:不是所有失败都是"图能修的"

SkillAA 在三个 benchmark 上验证:SearchQA(问答)、LiveMath(数学)、DocVQA(文档视觉问答)。用 gpt-5.6-sol 作为 student 和 teacher,三个 epoch 后:

  • SearchQA:81.5%
  • LiveMath:66.7%
  • DocVQA:91.2%
在九个 model-benchmark 组合上,SkillAA 都取得了最高点估计值。但更有意思的不是这些数字,而是两个"负面"结果。

负面结果一:ALFWorld 上改图反而变差

在 ALFWorld(一个交互式家庭任务环境)上,所有方法在 100 步内都能 100% 完成。但在 50 步的紧预算下,初始技能反而是最好的——SkillAA 改了图之后,成功率反而从 95.5% 掉到 92.5%。

这是一个反直觉但极其重要的发现:当初始技能已经足够支撑任务,剩余失败来自探索或执行时,改图不仅没用,还会帮倒忙

这就像一个已经写对的函数,你硬要"优化"它,结果引入了 bug。知道什么时候不改,和知道改什么一样重要。

负面结果二:残差错误审计

团队手动审计了六个 held-out 上的错误,发现它们需要四种完全不同的修复:

1. 评分器问题:模型答 Manuel Noriega,标准答案 Noriega——该修评分器,不是改技能 2. 证据缺失:检索没找到"第一任国务卿"的"第一"——该改检索,不是改技能 3. 定理识别错误:数学定理选了相关但非等价的——该加领域知识库,不是改技能 4. 视觉识别错误:手写日期 7/18 看成 11/18——该加 OCR 交叉验证,不是改技能

六个错误里只有一个是真正的技能缺陷(role selection),而且因为只出现一次,连这个都不够格做持久化修改——需要同类错误反复出现才能确认是系统性技能缺陷

这个残差审计是整篇论文最有工程价值的部分。它告诉我们:"答错了"不等于"技能错了"。把所有错误都塞给技能系统,就像把所有系统故障都塞给应用层——数据库慢了改应用代码,网络抖了改应用代码,硬件坏了改应用代码。

工程洞察:三件事比"改技能"更重要

综合 SkillAA 的设计和实验,有三个工程洞察值得所有做 agent 系统的人记住。

洞察一:把技能变成"有地址的空间"

从"一段技能文本"到"一张有节点字段和类型边的图",不只是表示形式的升级,而是把技能从"可读文档"变成了"可寻址的代码库"

没有地址,你只能说"这个技能有问题"。有地址,你可以说"节点 #7 的 when_to_use 字段缺了第 3 个触发条件"。前者无法做定向修复,后者可以。

这和软件工程的演进一模一样:从"改这个文件"到"改这个函数的这一行"到"改这个分支的这一个 commit"。粒度越细,修复越精确,回滚越干净。

洞察二:NO_PATCH 是一等公民

当前所有技能进化系统都在追求"改得更多、改得更好"。SkillAA 反其道而行,把"不改"提升到和"改"同等重要的地位。

这不是保守主义,而是对失败原因多样性的尊重。当失败可能来自检索、感知、推理、执行、评分器中的任何一个环节时,把所有失败都塞给技能系统,就像把所有疾病都开抗生素——不仅治不好病毒感染,还会制造超级细菌。

SkillAA 的 NO_PATCH 路径,相当于给技能系统装了一个"分诊台":先判断这个失败是不是技能能修的,不是就转诊到其他组件。

洞察三:两道闸门 = 事务化技能管理

Local Gate + Big Gate 的设计,本质上是把数据库事务管理的思路搬到了技能优化上:

  • Local Gate = 行级约束(修改不能破坏局部一致性)
  • Big Gate = 事务提交(整个 epoch 的修改必须让全局指标净正向)
这个设计解决了一个长期被忽视的问题:技能修改的副作用。改了一个技能,可能修好了 A 任务但搞坏了 B 任务——以前没人检查这个。SkillAA 的 Local Gate 专门抓这种回归。

一个更深的洞察:什么时候该改图,什么时候该换模型

论文最后提出了一个我非常喜欢的框架:graph-addressable vs capability-limited failures

  • Graph-addressable failure:技能图里某个字段或边有明确缺陷,改了就能修好
  • Capability-limited failure:技能图是对的,但模型本身能力不够(推理、感知、执行)
当 epoch 级别的修改开始反复被 Big Gate 拒绝时,这是一个停止信号——不是模型能力到顶了,而是"图能修的都修完了,剩下的得靠改模型"。

未来的系统应该交替进行:改图修 graph-addressable 的失败,改模型修 capability-limited 的失败,两者迭代推进。这就像软件迭代:先优化算法(改图),再升级硬件(改模型),循环往复。

对步子哥们的启示

如果你在做 agent 系统、在用 skill 或 prompt 管理任务流程,SkillAA 给了三个直接可用的思路:

1. 给你的 skill 加地址:不要把 skill 写成一坨 markdown,拆成 when_to_use / how_to_use / avoid 三个字段,用图结构管理依赖关系。这样失败时你能定位到具体字段,而不是"重写整个 skill"。

2. 设两道闸门:改 skill 之前先问"这个修改会影响哪些已通过的 case",改完之后跑一遍回归测试。全局指标净正向才提交,否则回滚。这比"改了就上线"靠谱十倍。

3. 学会说 NO_PATCH:不是所有失败都该改 skill。先诊断失败原因——是触发条件没命中?步骤错了?还是模型本身能力不够?前两者改图,后者改模型(或换更大的模型)。把"不改"作为合法输出,能避免大量无效修改。

开源代码

论文配套代码已开源:https://github.com/Ziqiao-Shang/SkillAA

仓库包含图优化器、Gate 实现、benchmark 数据准备脚本、以及完整的 per-example 预测记录。用 gpt-5.6-sol 作为 student/teacher,三个 epoch 就能复现主表结果。终端图(SearchQA 30 节点 8 边、LiveMath 37 节点 40 边、DocVQA 20 节点 19 边)也已发布,可以直接用来做 inference-only 的消融实验。

论文信息

  • 标题:SkillAA: Attribution-Guided Skill-Graph Updating with Targeted Validation and Rollback
  • 作者:Ziqiao Shang, Lingyue Ge, Lan-Zhe Guo(南京大学)
  • arXiv:2609.20455
  • 代码:https://github.com/Ziqiao-Shang/SkillAA

个人思考:SkillAA 最让我欣赏的不是它的数字,而是它对"失败"的尊重。当前 AI 圈的技能进化系统都在追求"改得更多更快",但真正成熟的工程系统知道——知道什么时候不改,比知道改什么更难也更重要。这和软件工程里"不要为了修 bug 而引入 bug"是同一个道理。

NO_PATCH 作为一等公民输出,这个设计哲学值得所有做 agent 自进化的团队借鉴。不是所有失败都是技能的锅,承认这一点,技能系统才能真正可靠。

暂无表态

想参与讨论或点赞?登录后使用完整功能

讨论回复(1)

Q

这篇把「分诊」这个点子讲透了,是我这两天读到最舒服的一篇 agent 工程解读。但有两处被顺手讲顺了:一处是「六个错误里只有一个是技能缺陷」的读法,一处是两道闸门的成色。

六个归因抽屉,两个写着不动

一、技能图的账我替你数了一遍,你对上了

仓库里每个 benchmark 都放了两版 best_graph.json(初始 initial_skill 与终态 graphopt),我把 stable_rule_graph 的 nodes / edges 逐个 parse 出来:

Benchmark初始图终态图增量
SearchQA25 节点 / 3 边30 / 8+5 / +5
LiveMath21 / 2337 / 40+16 / +17
DocVQA11 / 1020 / 19+9 / +9
你写的「终端图」三个数字,一个一个都对得上,可以放心引。

但你没给初始值,而初始值才是这套方法值不值钱的关键:三个环境里图都接近翻倍,DocVQA 从 11 个节点长到 20(+82%),LiveMath 从 21 长到 37(+76%)。「改得准」和「改得多」的分界就在这条增量上——如果最终分数是靠一张两倍大的技能表换来的,那它和「让模型多想几轮」的区别就没那么大了。

二、「六个里只有一个」这种读法,论文自己划了线

你在残差审计那段说「六个错误里只有一个是真正的技能缺陷」。这句话读起来像频率统计,但论文附录 G.3 的原话是:这六例(每基准 2 例)是挑出来区分失败机制的,不是用来估计它们出现频次的("selected to separate failure mechanisms, not to estimate their frequency")。

也就是说,「六分之一」这个比例站不住——它是六个手挑的样本,不是六十个里的六个。你后面补的那句「需要同类错误反复出现才能确认是系统性技能缺陷」论文里也没有,是你的推论,方向我同意,但得跟原话分开摆。

顺便把六例补全:SearchQA 是「Noriega 判成错」(评分器)+「第一任国务卿检索缺序数证据」;LiveMath 是「相关定理当成等价定理」+「必要条件当成可实现性」;DocVQA 是「手写日期 7/18 读成 11/18」(你说的那个是第二个:签名栏对了、角色答错)。四例需要改的是检索、评分器、领域知识库和 OCR,不是技能图。

三、两道闸门,论文给的边界比你写的窄

你把 Local + Big Gate 讲成了通用的工程最佳实践。论文自己的两句话更小心:

  • 「Big Gate 应当被理解为一条 epoch 级提交规则,它保证的是 update pool 上的净增益,而不是一个能普遍提升留出集精度的组件」。
  • 具体数字:它对 gpt-5.6-sol 是 +1.5 / +4.6 / +1.2 pp;把它整个拿掉,gpt-5.4-mini 反而 +1.1 / +2.0 / +0.9 pp。
提交史也能看:SearchQA 与 LiveMath 的最佳图在第 2 轮就被接受、第 3 轮的候选被否;DocVQA 相反,否掉第 2 轮、第 3 轮接受了另一组修复。三个环境里两个的最后一轮白跑——你说的「停止信号」不是一个设想,它已经发生过两次。(附录里还有一句挺硬:拒绝的提案不改变任何可执行状态,留出集分数不参与闸门判定。)

四、那个 ALFWorld 反例,比原文写得更狠,但也更站不住

表 9 的原始数据(50 步预算):无技能 94.8 ±0.4、初始技能 95.5 ±0.4、SkillOpt-markdown 89.6 ±1.1、SkillAA 92.5 ±3.4

你说「初始技能最好」——对。但还有一句你没说:SkillAA 的 92.5 也低于「什么都不装」的 94.8。在这个环境里,装一套技能图不如不装。

不过我得替作者说句话:SkillAA 的半幅是 ±3.4pp,四行里最大,换算成区间大约 89.1~95.9——它把另外几个数全罩住了。所以准确的说法不是「SkillAA 更差」,而是「这个对照的样本量分不出胜负」。你在这一段的结论比数据跑得快了一点,这是我全文最想改的一处。

五、两条比数字更值钱的限定

1. 对比不是算力对齐的。 论文 4.3 自陈这些是"descriptive source-protocol comparisons","should not be interpreted as a compute-matched superiority claim";而且那张渐进式对比表"does not by itself isolate the contribution of each mechanism"。所以 81.5 / 66.7 / 91.2 只能当点估计看,这也是你自己用的词,很稳。 2. 只跑了 3 个随机种子(42 / 43 / 44),论文自陈的局限是三条:graph scale、task scope、few repeated runs。

还有一条你完全没提、但我觉得最实用的:教师不必是自己。 4.4 节的教师迁移测试里,换成更弱的 gpt-5.4-mini 当教师,对更强的 gpt-5.6-sol 学生仍然带来实质增益。也就是说你不需要再找一个更强的模型来给 agent 改流程——一条比论文主表更接地气的性质。

六、仓库实测

github.com/Ziqiao-Shang/SkillAA 确实存在:2026-09-17 创建、同日推送,0 star、0 fork、无 description、无 LICENSE(只有一个 219 字节的 NOTICE.md)。代码本体不薄:evolution/engine.py 151 KB、case_analyzer.py 104 KB、evaluation/edit_gate.py 18.9 KB,三个 benchmark 的初始图与终图 JSON 都在。

所以说「已开源」我同意,但严格讲,没有许可证的仓库在法律意义上还不算「可用的开源」。要拿它做工程选型,先跟作者要一句授权,比读十篇解读都省事。

判断

这篇的价值不在 81.5 / 66.7 / 91.2,而在于它把「不改」写成了一等公民输出。你文末那句「知道什么时候不改,比知道改什么更难也更重要」,我完全同意,而且这篇论文真正新的是它给「不改」配了一个可执行的判定条件——两个归因码 + 一道净增益闸门。在此之前,「不改」只是工程直觉。

钉子

第一根:那批被闸门拦下来的修改去哪了? DocVQA 的图从 11 个节点长到 20 个,这 9 个节点里有多少是「提了 — 被 Local Gate 否 — 改一版再来」的产物?论文没给这个重试率,而它直接决定这套流水线的 token 账单。

第二根:换第 4、第 5 个种子,92.5 会回弹吗? ±3.4 的半幅太宽了,多跑两个种子只要几十分钟,能把这篇文章里最有争议的那个数字钉死。

第三根短一点:论文说「未来系统应该交替改图与改模型」,但交替的切换点怎么定它没给。目前只有一条「后续修改连续被 Big Gate 否掉」的启发式——这更像是一个值得单独做实验的问题。

#Agent工程 #技能图谱 #回归测试

暂无表态
合作

智谱 GLM-5 已上线

在智谱开放平台 BigModel.cn 打造 AI 应用。新一代旗舰模型 GLM-5 在推理、代码、智能体综合能力达到开源模型 SOTA。

领取 2000万 Tokens