Skill1:用一个奖励信号,把 Agent 的"选、用、攒"三件事一起练出来
核心摘要
做带技能库的 LLM Agent 这件事,一直有个让人头疼的工程现实——选技能、用技能、攒技能这三件事永远是分着练的。有人专心优化"用",选用现成的 retriever 选技能;有人在"攒"上玩花样,但选技能的部分干脆冻住。结果就是某一块练得再好,整条链路也跟着卡在最弱的那一环。这篇来自中科大、美团等机构的 Skill1 提出了一个挺利落的方案:让同一个策略同时负责"选、用、攒",并且所有的学习信号都来自同一个任务奖励 \(r(\tau)\)。它的关键技巧是把这个 0/1 信号拆成"低频趋势"和"高频偏离"——前者给选技能用,后者给攒技能用,中间执行的部分直接拿原始奖励。在 ALFWorld 上跑到 97.5% 平均成功率,比此前最强的 RetroAgent 高 2.6 个点,WebShop 上也是全榜第一。这是一个工程味很重、但思想干净的工作,值得做 Agent 训练的同行细看。
论文信息
- 标题:Skill1: Unified Evolution of Skill-Augmented Agents via Reinforcement Learning
- 作者:Yaorui Shi, Yuxin Chen(共同一作), Zhengxi Lu, Yuchun Miao, Shugui Liu, Qi Gu, Xunliang Cai, Xiang Wang, An Zhang(通讯)
- 机构:中国科学技术大学、美团、新加坡国立大学、浙江大学、武汉大学
- 链接:https://arxiv.org/abs/2605.06130
- 代码:https://github.com/AlphaLab-USTC/Skill1
一、先说说让我皱眉的那个老问题
去年下半年开始,圈里关于"给 LLM Agent 配一个技能库"的工作突然多了起来。Voyager 那一脉的思路其实早就有了——Agent 在做任务的过程中,把成功经验沉淀成一段段可复用的策略,下次碰到类似任务先翻翻"经验本",而不是每次都从零开始硬磕。这件事的吸引力很直白:参数化的记忆(也就是直接把策略吸进权重里)有它的极限,而显式的技能库提供了一种"可读、可查、可复用"的额外记忆容器。
但真正把这套东西做成可训练的系统,会撞上一个让人很难受的工程现实。
技能库这个东西,至少有三件事要做:
- 选:来了一个新任务,从一大堆历史技能里找出几个相关的,然后挑一个最合适的
- 用:拿着选出来的技能去做任务,技能是文本形式的策略提示,模型要会用它
- 攒:任务做完后,从 trajectory 里反思总结出一条新的、值得入库的技能
听起来很清晰对吧?问题是,现有的工作几乎没有一个能把这三件事同时用 RL 在一个目标下训出来。
我之前做过一段类似的事,大概能讲清楚卡点在哪。
- SkillRL 这一类是冻住选择模块的——retriever 用一个固定的 embedding 模型做相似度匹配,选完之后用 RL 训"用"和"攒"。问题是 retriever 选回来的东西如果本身就不靠谱,下游再怎么练也救不回来。
- RetroAgent 是反过来,"用"和"攒"都拿来训了,但选择那一步靠的是基于历史成功率的启发式打分,跟策略梯度无关——也就是说"模型怎么生成 query"这件事没法被任务结果倒过来纠错。
- EvolveR、Mem0+GRPO 这些就更直接,把库当外置数据库,把训"用"那一段当主战场,其它的丢给外部模块。
更尴尬的是,即便有人勉强同时训了两个阶段,它们用的奖励信号往往不是同一个——选技能可能用一个自评分数,攒技能可能用一个启发式匹配分,用技能用任务结果。三个信号互相之间没有内在一致性,训起来很容易出现"这边在涨那边在掉"的撕扯。
这就是 Skill1 想解决的问题。它的诉求其实可以一句话总结:
能不能用一个统一的策略、一个统一的任务奖励,把"选、用、攒"三件事真的一起训出来?
听上去像个理想主义的口号,但他们给的解法挺干净。
二、Skill1 的核心 idea:一个奖励信号,拆成两个时间尺度

图 1:训练范式对比。这张图把这篇论文的卖点讲得很直白——之前的方法是"局部最优",Skill1 主张"全局协同"。
2.1 工作流:一个策略串起三件事
来一个任务 \(x\),Skill1 是这么走的:
- 策略 \(\pi_\theta\) 看到任务,生成一个自然语言的 检索 query \(q\)
- 用一个冻结的 encoder(all-MiniLM-L6-v2)把 query 和库里每条技能的描述算个相似度,召回 top-\(K\) 个候选(论文里 \(K=5\))
- 同一个策略 \(\pi_\theta\) 拿到这 \(K\) 个候选,生成一个 permutation(重排序),排第一的那个技能 \(z\) 就被选出来
- 策略以 \(z\) 的 strategy 作为提示,进入多轮交互执行任务,最多 \(T\) 步,拿到 0/1 的终端奖励 \(r(\tau)\)
- 策略对整段 trajectory 做反思,输出一条新技能(含 strategy 描述和适用场景描述),只有当 \(r(\tau)=1\) 时才入库
整个过程里,query、permutation、action 序列、新技能这四段都是同一个 \(\pi_\theta\) 生成的,所以理论上都可以一起拿策略梯度更新。这就是"统一"两个字的来源。
技能库容量上限 5000 条,满了之后用一个简单的启发式做淘汰:\(U(s) \cdot \log(n(s))\),其中 \(U(s)\) 是技能的历史 utility 分,\(n(s)\) 是被选中的次数。两个都小的优先淘汰——既没人用、用了也没效果的,先走。
这一套工作流其实并不算"创新"。Voyager、ExpeL、RetroAgent 都有类似形态。Skill1 真正值钱的地方在后面那个 reward 拆解。
2.2 关键 trick:把任务奖励拆成低频趋势 + 高频偏离
这是我读到的时候第一次"嗯,这个想法挺漂亮"的地方。
问题摆在那:你只有一个 0/1 的任务结果 \(r(\tau)\),怎么把它合理地分配给"选、用、攒"三个完全不同时间尺度的能力?
- "用" 关心的是当前这个 episode 做没做成——尺度就是单次
- "选" 关心的是这个技能"长期来看"靠不靠谱——尺度是跨 episode 的统计
- "攒" 关心的是这条新攒出来的技能"相对于库里已有的"是不是真有增量——尺度是和库的整体分布比较
作者的思路是:
把 \(r(\tau)\) 看成一个信号序列,做一个低通和高通滤波。低频部分(趋势)给"选",高频部分(偏离)给"攒","用"直接用原始信号。
具体怎么做?
选技能的奖励:对每条被检索回的技能 \(s\),维护一个 EMA(指数移动平均)的 utility 分:
这个 EMA 就是任务奖励的低频分量——它把"这个技能跨多个 episode 平均效果如何"这件事提取出来。然后用它作为重排序的 ground truth,让策略给出的 permutation \(\sigma_i\) 尽量和 utility 排序对齐,奖励就是 NDCG:
注意一个小细节:EMA 更新时不只更新被选中的那条技能,而是更新所有被召回的 top-\(K\) 都更新。作者的理由是——同一批被召回,说明它们都和当前任务相关,可以一起拿当前的任务结果作为信号。这个工程决定我挺认可,单纯只更新被选中那条会让没被选的技能永远拿不到反馈。
攒技能的奖励:用当前任务结果减去"库里已有的最强技能的 utility":
这就是高频分量——它衡量的是"这次结果相对于库的现状是惊喜还是平庸"。如果一个新攒出来的技能能让任务结果超过库里最好的那条,那这条新技能就值得入库,给正奖励;反过来如果还不如现有的,给负奖励,劝退冗余蒸馏。
用技能的奖励:直接用原始任务结果 \(R^{\text{util}}_i = r(\tau_i)\),配合 GRPO 的 group-relative advantage 做策略梯度。
三个目标加权求和:
论文里 \(\lambda_1 = \lambda_2 = 0.3\)。

图 2:完整流程图,把上面三步用图说清楚。注意 EMA-utility \(U(s)\) 这个东西是非参数化更新的,它本身不参与梯度,但它派生出来的 NDCG 和 variation 信号要回传梯度。
说到这,我想多聊一句——这种"用 EMA 提取长期趋势,用偏离提取短期变化"的思路其实在传统强化学习里有先例,比如 dueling network 把 V 值和 advantage 拆开、PPO 的 GAE 做时序差分。但把这套思想搬到"技能库管理"这个看似不相关的场景,让一个完全相同的任务奖励信号承担三种角色,这个 translation 是漂亮的。
2.3 工程上的几个细节
有几个点值得专门提一下,做过类似事情的同行会有感:
(a) Re-ranking 为什么用 REINFORCE 而不是 GRPO?
GRPO 是用同一个任务下的 \(G\) 个 rollout 做 group-relative advantage 标准化。但 Skill1 里每个 rollout 生成的 query 不一样,召回回来的 \(\mathcal{B}_K^i\) 也不一样,候选集都不同,做 group 比较就没意义了。所以 re-rank 部分退回到原始的 REINFORCE,单条独立优化。这个细节看上去不起眼,但其实是被实验逼出来的——如果直接套 GRPO,rerank 信号会被均值方差归一化扭曲。
(b) Distill 的 advantage 单独归一化。
虽然 distill 和 util 都用 GRPO 框架,但它们的 advantage 分别独立标准化。原因也很自然:util 衡量"任务做没做成",distill 衡量"和库比有没有惊喜",两者均值方差完全不同,混在一起算 group 统计量会互相干扰。
(c) 技能淘汰策略。
\(U(s) \cdot \log(n(s))\) 这个分数。乘 log 是为了保护"虽然效用高但还没被广泛验证"的新技能不被秒杀,同时也避免"虽然用得多但效果不好"的老技能赖着不走。挺工程的一个细节。
三、实验结果:好看,但要看清"和谁比"
3.1 主实验:97.5% 的 ALFWorld 平均成功率
| ALFWorld 任务类型 | Pick | Look | Clean | Heat | Cool | Pick2 | Avg | WebShop Score | WebShop Succ |
|---|---|---|---|---|---|---|---|---|---|
| ReAct | 48.5 | 35.4 | 34.3 | 13.2 | 18.2 | 17.6 | 31.2 | 46.2 | 19.5 |
| Reflexion | 62.0 | 41.6 | 44.9 | 30.9 | 36.3 | 23.8 | 42.7 | 58.1 | 28.8 |
| ExpeL | 21.0 | 67.0 | 55.0 | 52.0 | 71.0 | 6.0 | 46.3 | 30.9 | 11.2 |
| PPO | 92.3 | 64.0 | 92.5 | 89.5 | 80.3 | 68.8 | 80.4 | 81.4 | 68.7 |
| GRPO | 90.8 | 66.1 | 89.3 | 74.7 | 72.5 | 64.7 | 77.6 | 79.3 | 66.1 |
| GiGPO | 97.7 | 82.7 | 98.8 | 83.7 | 89.3 | 79.2 | 90.8 | 84.4 | 72.8 |
| SkillRL | 97.9 | 71.4 | 90.0 | 90.0 | 95.5 | 87.5 | 89.9 | 85.2 | 72.7 |
| RetroAgent | 97.9 | 90.9 | 99.2 | 92.9 | 85.3 | 91.0 | 94.9 | 88.9 | 82.3 |
| Skill1 | 100.0 | 98.6 | 97.3 | 99.2 | 96.1 | 96.0 | 97.5 | 89.7 | 82.9 |
几个观察。
和最强 RL-only 方法 GiGPO 比,Skill1 高了 6.7 个点。 这个差距体现的是"显式技能库"相对于"参数内隐式记忆"的额外价值。最有意思的是涨幅最大的两类任务——Look(+15.9 点)和 Pick2(+16.8 点)——恰好是需要组合多个子流程的任务类型。这一点和直觉吻合:参数化记忆擅长把一个完整流程"固化",但要在新任务里"重组合"已学过的子流程,显式技能库的可读、可检索特性就有优势了。
和最强带技能库的方法 RetroAgent 比,Skill1 高 2.6 个点。 RetroAgent 的"选"是启发式的(基于历史成功率),"用"和"攒"都用了 RL 但奖励信号是分开的。Skill1 把三件事统一在一个信号下,赚回这 2.6 个点。但说实话——
这里我必须给一个不太热情的评论。 Skill1 主表中的"Clean"任务上比 RetroAgent 低了 1.9 个点,作者在附录 D 里强调这个差距 \(p=0.147\) 不显著。但反过来 Skill1 比 RetroAgent 高的那些 task,确实 \(p\) 值很小(Heat \(p=0.004\),Cool \(p=0.005\))。这个 statistical analysis 是论文最让我信服的部分之一——他们没有躲,明确给了 3 seed 的方差和 t-test。这种坦诚比那种把方差藏起来只给 mean 的做法好得多。
3.2 消融:拆掉哪一块都不行
| 配置 | Pick | Look | Clean | Heat | Cool | Pick2 | Avg |
|---|---|---|---|---|---|---|---|
| Skill1 完整版 | 100.0 | 98.6 | 97.3 | 99.2 | 96.1 | 96.0 | 97.5 |
| w/o Select.(去掉选择阶段) | 96.9 | 90.3 | 98.0 | 90.4 | 86.5 | 85.3 | 91.8 |
| w/o Distill.(去掉蒸馏阶段) | 97.4 | 88.5 | 98.1 | 96.1 | 87.6 | 89.5 | 92.4 |
| w/o Library(完全不要库) | 96.7 | 71.5 | 94.9 | 70.7 | 71.5 | 65.5 | 80.9 |
| \(\lambda_1=0\)(去掉重排序奖励) | 99.5 | 80.5 | 98.8 | 100.0 | 90.6 | 84.9 | 94.0 |
| \(\lambda_2=0\)(去掉蒸馏奖励) | 100.0 | 85.4 | 95.5 | 96.4 | 91.0 | 96.2 | 94.9 |
| \(\lambda_1=\lambda_2=0\) | 98.1 | 74.9 | 95.6 | 95.6 | 79.5 | 87.2 | 90.2 |
我看完这张表第一反应是:"w/o Library 才掉到 80.9%,比我想象的还顽强。" 然后又仔细看了一眼——掉得最狠的是 Heat(-28.5 点)和 Pick2(-30.5 点),这两个都是多步组合任务。说明库的价值真的高度集中在"需要复用历史子流程"的场景,而对单步任务(如 Pick)影响不大。
更值得琢磨的是 \(\lambda_1\) 和 \(\lambda_2\) 同时为 0 的那一行——掉到 90.2%,比单独去掉任何一个 stage("用、攒"二选一)还低。作者的解读是:这两个辅助信号不仅对它们自己的目标有用,对"用"也有帮助。你想想看,当 selection 和 distillation 同时缺少信号的时候,policy 退化成了一个有库但不会管理库的状态,这个状态比"完全没有库"还糟糕——因为库里塞满了不靠谱的东西,反而干扰了 utilization。
3.3 训练动力学:三个能力是怎么一起涨起来的

图 3:训练动力学。最值得看的是左图——selection precision 在 step 20 左右就先冲到 0.95,然后 step 60 时 utilization 和 distillation 才跟着冲到 0.8。这个"先选后用"的次序很自然——只有先有靠谱的检索,下游才有得练。
这张图是我觉得整篇论文最有说服力的一张。它直接展示了三个能力在训练过程中的相互推动——选择先收敛,提供高质量的技能供给;然后利用和蒸馏跟上,因为它们手里拿到的素材变好了;最后这两者的提升又反过来让库的整体质量上升,selection 的信号也跟着变更可靠。这是一个真实的正反馈循环。
如果你把绿色或浅色曲线放在一起看,会发现去掉选择信号之后,所有三条曲线都被拖慢了——不仅是 selection 自己,连 utilization 都跟着掉。这就是 co-evolution 的核心论据:每一个 stage 的信号都不只服务于自己,它通过改变下游 stage 的输入分布间接影响整条链。
3.4 技能库的多样性:值得单独说

图 6:技能库的多样性对比。这张图给的洞察很直观——Skill1 的高频技能像撒胡椒粉一样分散在策略空间,而消融版本的高频技能挤在角落里抱团。
这是一个我没预期到但很喜欢的发现。当你只看主表的成功率数字时,你看不出技能库内部发生了什么——是高度集中在几条"明星技能"上反复用,还是真的形成了一个多样化的能力集合?
Figure 6 给出的答案是后者。Skill1 训出来的库里,被高频使用的技能(前 10%)数量几乎是消融版本的两倍,而且这些高频技能在 t-SNE 空间里铺得很开。作者的解释是:variation 信号(也就是 \(R^{\text{distill}} = r - \hat{U}\))会主动惩罚"和现有技能高度相似但效果不见得更好"的新蒸馏,所以策略被迫去探索那些没被现有技能覆盖的角落。
这点对工程很有启发——如果你做技能库管理,单纯的"成功才入库"这种过滤是不够的,你需要一个"和现有库的差异性"的额外信号来避免技能塌缩。
3.5 计算开销:1.3 - 1.7 倍于 GRPO
| 方法 | Step 20 (s) | Step 60 (s) | Step 100 (s) | 库大小 @ Step 100 |
|---|---|---|---|---|
| GRPO(无库) | 301 | 274 | 297 | — |
| SkillRL | 368 | 319 | 327 | 83 |
| Skill1 | 387 | 444 | 494 | 5000 |
| w/o Distill. | 509 | 750 | 738 | 5000(提前满) |
Skill1 比纯 GRPO 慢 1.3 - 1.7 倍,开销主要来自库变大之后 selection 时上下文变长。但说实话,对于一个能涨 17 点的方法(GRPO 77.6 → Skill1 97.5),这点开销在我看来挺值的。
更有意思的对比是 w/o Distill.——去掉蒸馏之后,库会被原始 trajectory 塞爆(5000 上限快速打满),导致 selection 上下文极长,反而慢了 69%。这说明蒸馏不仅是为了质量,也是为了把经验压缩成短的、可检索的形态,控制库的"信息熵"在一个合理范围。
四、几个让我皱眉的地方
读完之后我必须承认这是一篇做得相当扎实的工作。但有几个地方我会想多问一句。
(1) 任务奖励都是 0/1,信号过粗的问题怎么办?
ALFWorld 和 WebShop 的 success rate 是二值的(成功/失败),整个 EMA-utility 也就在 [0,1] 之间。这种情况下,"低频趋势"和"高频偏离"的拆分确实清爽。但如果任务奖励本身是稠密的(比如 process reward 或者多维评分),这套拆解还能不能 work?作者没回答这个问题。我直觉上这套机制在稀疏 0/1 信号下最干净,一旦换成稠密信号,"低频"和"高频"的边界会变模糊。
(2) Encoder 冻结,但 query 是学出来的,这个 mismatch 怎么处理?
retriever 用的 all-MiniLM-L6-v2 是预训练好的句嵌入模型,它对 query 和 skill description 的语义匹配方式是固定的。但 Skill1 同时在训"生成什么样的 query 才能召回好技能"——其实是让 policy 去学一个 encoder 的隐式 prior。如果 encoder 本身的语义空间和任务空间不对齐,policy 就要学一种"奇怪的"措辞方式来骗 retriever。这种"为 encoder 量身定制 query"的策略可能不会泛化。
(3) 库容量 5000 是不是太小?
ALFWorld 训练数据规模有限,5000 条够用。但论文自己也在 Limitation 里承认了——任务多样性一上来,这个 fixed-size 库就会成为瓶颈。我自己更想看到的是 hierarchical skill organization 或者基于 retrieval frequency 的分层淘汰机制,而不是简单的 EMA-based eviction。
(4) 和同期工业界方案的关系。
论文里对比的 baseline 主要是学界工作(RetroAgent、SkillRL、Mem0),但同期工业界其实有一些类似的"经验沉淀 + 检索复用"的 production 系统在跑。这套学术框架真的能直接照搬到工业部署吗?我持保留态度——production 里的技能往往不是 free-form 文本,而是结构化的工具调用模板、有版本号、有 ownership。Skill1 的 strategy 字段是自由文本,自然语言泛化好但工程可维护性差。
五、对工程的启发:哪些可以拿来用
抛开论文本身的研究价值,对做 Agent 系统的工程同行,我觉得有几个 takeaway 是可以直接吸收的。
(a) "选、用、攒"必须联合训练,不能分块。 这是最大的工程启发。如果你的 Agent 系统已经有了一个固定 retriever + 训过的 policy,那升级路径不是各练各的,而是想办法让 policy 也参与"生成 query"这件事,让 query 也能拿到 task feedback 的梯度。
(b) 用 EMA 跟踪每条技能的长期 utility。 这个开销极小,但能给你一个"哪些技能值得保留、哪些该淘汰"的可量化指标。即便不做 RL 训练,这个 utility 也可以作为重排序的特征喂给一个轻量的 ranker。
(c) 不要只用"任务成功"作为入库门槛。 Skill1 的 variation 信号给了一个很好的工程范式——"超过库的最强水平"才入库。这个比简单的"成功即入库"门槛高,能避免库快速膨胀和质量稀释。
(d) Distillation 不只是为了质量,也是为了压缩。 这个 insight 容易被忽略。Skill1 的 ablation 里去掉 distillation 的版本反而比完整版慢 50%+,因为库被原始 trajectory 撑爆了。压缩本身就是一种性能优化。
(e) 用 t-SNE 看你的库长什么样。 这是一个非常便宜的诊断工具。如果你的高频技能在嵌入空间里抱团,说明你的库已经塌缩到几个套路上了,需要从机制层面加压力让它探索新策略空间。
六、一个我没太想明白的开放问题
最后聊一个我自己还没完全想通的事情,作者也没解决——
当 Agent 主要靠技能库做事的时候,base policy 的能力上限在哪里?
Skill1 用的是 Qwen2.5-7B-Instruct。这个模型本身的 reasoning 能力其实有上限。当技能库变得越来越丰富,base policy 越来越依赖"检索 + 套用"模式时,会不会出现一个现象——policy 变成了一个"高级模板拼接器",而失去了从头思考的能力?
这不是危言耸听。Case Study 1 里那个例子,Skill1 之所以知道"stove burner 烧不了 plate,要用微波炉",是因为库里恰好有一条 utility=0.951 的技能明确写了这一点。如果碰到一个库里没有的新约束,policy 还能不能像 zero-shot 那样从环境观测里推理出来?还是说它已经被训练得"先查库再说",忘了怎么 zero-shot 推理?
这其实是参数化记忆和外部记忆之争的一个老问题,Skill1 没有给出答案,但它提供了一个很好的 testbed 来研究这个问题。
总的来说,这是一篇我会推荐给做 Agent 训练同行细读的论文。它不是那种"突破性的新算法"——说到底还是 GRPO 的拓展。但它在"如何用一个干净的奖励拆解机制把多个能力一起练"这件事上做得很漂亮,并且 ablation 和 statistical analysis 都给得相当扎实。这种"思想干净 + 实验严谨"的组合,在当下 Agent 领域已经不算多见了。
觉得有启发的话,欢迎点赞、在看、转发。跟进最新 AI 前沿,关注我