前阵子我复盘自己负责的一个Agent项目,发现一个特别讽刺的事实:技能库从32个技能涨到460多个的时候,我以为团队"经验沉淀"做得很成功,结果任务成功率从78%掉到了61%。检索命中率越来越低、两个相似技能让模型反复纠结、好几条旧技能和线上最新实践已经冲突了半年都没人发现。这个经历让我对"技能库只增不减"这件事特别敏感,所以在EMNLP 2026上看到SkillBrew这个工作时,我几乎是带着"终于有人正面收拾这个烂摊子"的心情读完的。它提出用多目标精炼的方式给经验做减法,让技能库不是越堆越厚,而是越用越顺。这篇文章我不打算复述论文摘要,而是把SkillBrew的思路、流程、目标设计逻辑,以及我结合自己项目实测后觉得真正能落地的细节,完整拆开讲一讲。
1. 技能库失序:为什么"只增不减"会让Agent越用越笨
1.1 技能库膨胀的三个典型代价
先说一个容易被忽视的事实:技能库本质上是一个决策候选集合,而不是一个知识仓库。很多团队把技能库当成"存经验的地方",每解决一个问题就塞一条技能进去,却从没想过:当Agent每次决策时要面对的候选技能有四五百条,它还有能力选出真正对的那条吗?
我用自己项目的真实数据来拆解膨胀的代价。三个代价是层层叠加的:
第一是检索延迟与检索质量的同时恶化。技能库的常见检索方式是向量检索加粗排,技能数量少时,Top-3基本就是正确答案;技能数量过百之后,相似技能的描述在向量空间里挤成一团,Top-5里经常出现三条本质上是同一个做法不同版本的东西。检索延迟从平均120毫秒涨到接近500毫秒,但准确率反而下降了。这就好比一个搜索引擎,索引文档越多,如果质量没有控制,排序结果就会越浑浊。
第二是Token预算的隐性超支。Agent在选择技能时通常会把候选技能的描述、参数、使用条件拼进上下文。技能库规模一大,完整塞进去根本不可能,只能截断或只塞Top-5。结果就是:部分技能的关键触发条件和边界信息被截掉,Agent在信息不完整的情况下做了错误选择。我在系统日志里看到很多次这样的情况——模型挑中了一个技能,但它不知道这个技能只适用于某个旧版本接口,因为那行字在截断范围之外。
第三是相似技能之间的冲突与干扰。这个问题比前两个更隐蔽。新技能往往是在新任务中生成的,它和旧的相似技能没有经过系统性对齐,于是出现两个触发条件高度重叠、但处理步骤不一致的技能。Agent有时选A,有时选B,行为模式不可预测,复现Bug都难。我管这个叫"技能内耗"——技能多了,但彼此之间在打架。
1.2 膨胀的根源不止是"缺管理",更是机制上没有"证伪"
可能有人觉得,技能库膨胀就是管理问题,定个规矩、定期清理就好了。但我在反复排查之后意识到,真正的问题在于:Agent系统在正常情况下只产生技能,从来不证伪技能。
每完成一个新任务,自动或半自动的技能生成流程就会把"这个任务可以这样完成"的经验写成技能入库。但几乎没有哪套机制会去验证:这个新技能是不是旧的某个技能换个说法?是不是和旧技能的适用范围冲突?旧技能在新场景里是否已经过时?所以技能库在机制上就是一个单向累积的数据结构,涨是必然的,不涨才奇怪。
打个比方,一个团队如果每个同事每学会一个新技巧就往共享文档里加一页,但从来没有人去合并重复页面、删除过期页面,最后这本共享文档一定没人敢查——不是因为内容没用,而是因为查起来太浪费时间,而且你不知道哪一页已经错了。技能库膨胀到一定程度,Agent并不是"懂得更多",而是"决策质量更差"。
2. SkillBrew的解题框架:用"多目标精炼"给经验做减法
2.1 先分清三个概念:清理、剪枝和精炼
在拆解SkillBrew之前,必须把三个容易混淆的维度分清楚。
**清理(Cleaning)**是硬规则驱动,比如删除调用次数为零、成功率低于阈值的技能。它的优点是简单,缺点是只看单点统计,没有考虑技能之间的关联,可能误删一些低频但关键的长尾技能。
**剪枝(Pruning)**是重要性驱动的淘汰,比如按最近最少使用、按贡献度排序、保留Top-K。它比清理科学一点,但本质还是在"从已有的技能里挑一部分留下"。这种思路没办法产生新东西,碰上"两条技能单独看都一般、合并起来才是最优解"的情况就无能为力。
**精炼(Refinement)**和前两者有本质区别:它是重新合成。不是选谁留下、谁删掉,而是把一组功能重叠的技能放进"酿造炉"里,提取它们的共性、保留有效的边界条件、剔除冲突和噪声,得到一个比原来任何一条都更优质的新技能。SkillBrew的核心思路就是这个"再酿造"的过程,这也是方法名里"Brew"的由来——像酿酒一样,把分散的原料浓缩、发酵、提取出精华。
这种思路在工程上其实非常自然。一个团队如果发现十几个同事都写过"解析日期字符串"的工具函数,正确的做法不是从里面选一个最好的,而是抽出一个统一的实现,把各种边界条件都收进去。SkillBrew就是把这种工程直觉搬到了Agent技能库管理上。
2.2 多目标在这里指的是哪些目标
既然要"精炼",就绕不开一个关键问题:凭什么判断精炼后的技能比原来的更好?SkillBrew没有用一个指标拍板,而是用一组目标来约束精炼方向,这是它和简单剪枝最大的区别。
我把它讲的多个目标归纳成四类:
- 技能有效性目标:精炼后的技能在实际任务中的成功率不能低于原技能组的平均水平,如果连效果都不能保证,库再小也没有意义。
- 库容量与计算预算目标:技能总数、技能描述与示例占用的Token数、向量索引体积,都要控制在预算内。这是直接对着"只增不减"去的。
- 冲突与歧义目标:精炼后技能之间的触发条件重叠度要尽量低,让Agent看到技能描述时能明确判断该不该用。
- 检索效率目标:技能入库后,检索命中的候选数量和重排准确率要维持在一个稳定水平,端到端延迟不能因为技能合并而劣化。
这里有一个很关键的设计哲学:四个目标之间不是简单的"先求效果,再求容量"的串行关系,而是在同一个优化过程中互相权衡。如果只需要效果,那就永远不需要做减法;如果只需要容量,那把所有技能删掉最省事。SkillBrew想表达的是:技能库管理的本质是在多个约束条件下找一组"足够好"的技能集合,而不是单点最大化某一个指标。
2.3 "精炼"发生在哪些层面
这一点容易被忽略,但我认为恰恰是SkillBrew真正有工程价值的地方:精炼不是只改技能的文字描述,而是覆盖技能的多个组织层面。
- 描述层:合并相似技能时,重新生成一段包含触发条件、适用范围、使用限制的技能描述,让Agent在上下文窗口里看到的信息密度更高。
- 步骤层:把原来多条技能中的操作步骤去重、合并,变成一份完整且更少冗余的流程。
- 参数层:参数范围如果有重叠或冲突,精炼后统一成一个合理区间。比如旧技能A的参数范围是1到5,技能B是3到8,合并后统一为1到8,但要额外标注哪些区间有副作用。
- 示例层:每个技能附带few-shot示例时,要淘汰重复度高的示例,保留更能覆盖边界的例子,降低Token占用。
- 索引层:精炼后要重建向量索引,否则旧索引里仍然残留多个相似向量,检索还是会慢。
这些层面的精炼最终会被写进库更新流程。从我的实践看,这才是"做减法"的真正含义——不只是删掉几个技能序号,而是让库里每一个技能都是高信息密度、低冗余度的优质条目。
3. 精炼流程拆解:从技能普查到库更新的完整闭环
3.1 阶段一:技能普查与量化体检
任何精炼过程都始于一次彻底的普查。我在自己的系统里落地SkillBrew思路时,先给每个技能打了七个维度的标签。你可以直接复用这张体检表:
| 维度 | 指标 | 采集方式 |
|---|---|---|
| 使用热度 | 近30天调用次数、调用趋势 | 日志统计 |
| 效果表现 | 任务成功率、平均完成质量分 | 线上结果回传 |
| 开销 | 平均Token消耗、平均延迟 | 日志统计 |
| 时效性 | 最近一次有效调用时间 | 日志统计 |
| 覆盖度 | 触发场景的领域覆盖范围 | 技能描述与调用场景分析 |
| 冗余度 | 与库内其他技能的文本/行为相似度 | Embedding相似度+行为对比 |
| 冲突度 | 触发条件与其他技能的重叠情况 | 规则判定+模型判定 |
这一步不需要引入复杂的优化算法,但要把它做成一个自动化的、周期性执行的脚本。很多团队的问题是从来没认真统计过技能库的健康度,连"哪条技能三个月没人用"都是靠拍脑袋。体检数据是后面所有决策的基础,这一步值不值得下功夫,直接决定精炼效果的上限。
3.2 阶段二:冗余分组与冲突检测
体检完之后,技能还是一个个孤立的条目,下一步需要把它们分组,找出"谁和谁其实在干同一件事"以及"谁和谁在互相矛盾"。
冗余分组的常见做法是Embedding相似度聚类。把每个技能的描述和示例文本向量化,然后按相似度阈值聚类。这个做法有效,但我吃过亏,后面专门讲。这里只强调一点:文本相似不代表行为等价。两条技能文本长得几乎一样,但一个走新接口、一个走旧接口,行为结果完全不同;反过来,两条技能文字描述差异很大,但实际输出分布几乎相同。所以在做冗余分组时,我强烈建议在文本相似度聚类的基础上,叠加一个"行为等价性"判断。
行为等价性的简化做法是:找一批验证任务,分别用两条技能跑一遍,比较输出结果的差异度。如果一组测试任务上两条技能的输出差异很小,那基本可以判定为行为等价,可以进入候选融合组;如果输出差异大,哪怕文本再像,也不要合并,否则会制造一条"表面上统一、实际行为不稳定"的融合技能。
冲突检测则是另一套逻辑,重点看触发条件。比如技能A的触发条件是"用户询问发票相关事宜",技能B的触发条件是"用户询问开票流程",这两个条件在语义上就有大量重叠,但处理步骤可能完全不同。检测出来之后,要么在精炼时合并边界,要么在描述里明确切割适用范围。
3.3 阶段三:多目标打分与精炼决策
分组完成之后,每一个候选组摆在我们面前的问题就是:这一组技能,应该保留?融合?降级?删除?还是归档?
SkillBrew的做法是用多目标评分来辅助决策。对每个候选组,分别计算四个目标的得分,然后落在一个决策矩阵里:
- 保留:组内某条技能在覆盖度和成功率上明显优于其他条目,且冲突度很低。此时不需要融合,选定这一条作为主技能即可。
- 融合:组内技能各有优点、各有边界,单独留哪一条都不完整。这是SkillBrew最常处理的场景,用精炼生成一条新技能代替整组。
- 降级:技能的使用场景已经收窄到某个很小范围,但还没有完全失效,可以缩小参数范围、收紧触发条件,作为特殊场景技能保留。
- 删除:成功率低、调用少、且有可替代技能,直接删除。
- 归档:技能本身没问题,但当前业务暂停使用,归档到冷存储,不进在线索引,需要时再恢复。
这一步的关键是不要把决策变成一次性的大动作。我更推荐的做法是:高频次的"小步精炼"加定期"大扫除"。每次新技能入库时,先和库里最相似的技能做一次轻量对比,如果高度冗余就当场否决或改写;每周再对新增部分做一次增量精炼;每个月跑一次全库的完整复评,处理那些长期积累的复杂分组。
3.4 阶段四:执行精炼与库更新验证
决策确定后,就是实际生成融合技能。这一步通常由大模型完成:把组内所有技能的描述、步骤、参数、示例、线上表现统计一起打包给模型,让它生成一个统一技能。这个环节有一个非常重要的操作细节——必须让模型输出结构化的技能文档,而不能只生成一段自然语言。我自己的模板包含四个字段:触发条件(用逻辑表达式描述)、适用范围(明确的包含/排除场景)、操作步骤(有序列表)、边界与注意点(副作用、失败处理、参数限制)。结构化输出对后续的检索、自动验证、冲突检测都极其重要。
生成完之后不能直接替换上线。SkillBrew的流程里有一个验证回环:用一个固定的回归测试集跑一下原技能组和新融合技能,对比成功率、输出稳定性、Token消耗。回归测试集不需要很大,但必须覆盖三种情况——每个原技能各自擅长的典型场景、原技能之间边界条件交叠的场景、完全不相关的干扰场景。只有新技能在这三类场景上的综合表现不低于原技能组的平均水平,才允许替换。这个验证环节我用四个字总结:先证后删。没有经过验证的精炼,本质上是拿线上稳定性赌优化空间。
4. 四个核心目标的设计逻辑与求解方式
4.1 目标一:技能有效性保持
技能有效性是精炼的底线。一个技能库哪怕精简得再漂亮,如果实际任务成功率掉了两个点,业务方都不会答应。
有效性目标的具体量化方式,我建议按场景加权的平均成功率来计算。给每个技能定义一组代表性测试场景,每个场景有一个权重,代表这个场景在实际流量中的出现频率。精炼前对原技能组在这些场景上跑一遍得到一个baseline,精炼后再跑一遍融合技能。有效性得分就是加权准确率的变化率。这个指标要大于等于0才能通过,最好留一点余量,比如要求提升1%以上。
这里有一个细节,很多人做有效性问题评估时容易犯的错误:只用成功/失败二值来判断质量。我强烈建议加上一个"输出质量分",也就是任务虽然完成了,但完成得好不好。比如代码生成任务,运行通过是一回事,代码可读性和执行效率是另一回事。多一个质量维度,精炼的时候模型才能知道该往哪个方向优化。
4.2 目标二:库容量与Token预算控制
这个目标是"做减法"的直接体现。量化方式很简单:技能库总数、技能描述与示例的Token总量、向量索引的存储体积。
但要注意,不要把Token预算当成一个静态上限,否则会导致另一种形式的误删。我建议设置三个层级的容量指标:
- 软阈值:超过这个值,新技能入库前必须做一次轻量去重审查。
- 硬阈值:超过这个值,拒绝任何新技能直接入库,必须先精炼腾出空间。
- 目标区间:容量回落到这个范围内才算精炼成功。
Token预算的逻辑也很直接:Agent每次决策能看到的技能信息受上下文窗口限制,如果技能库里所有条目的Token总量超过窗口的一定比例,必然有一部分技能永远处于"看不到"的状态。容量控制不是抠门,而是保证每个技能都有公平的"被看到"机会。
4.3 目标三:冲突率与歧义度最小化
冲突率和歧义度是最容易被人忽视、但影响最大的目标。Agent选错技能,很多时候不是因为检索算法差,而是因为技能库本身就给了模型一个"两难选择"。
冲突率的量化可以从触发条件维度来做。把技能A和技能B的触发条件各拆成一组语义谓词,比如"用户意图=发票咨询"、"消息渠道=邮件"、"时间范围=月底",然后统计两组谓词的重叠程度。重叠度超过阈值就记为一次候选冲突,再除以库内技能对的总数,就是全局冲突率。
歧义度更微妙一些。哪怕两条技能触发条件不完全相同,但如果描述措辞区分度太低,模型依然会产生困惑。我见过最典型的案例:一条叫"处理日期格式化请求",另一条叫"解析用户输入的日期",在向量空间里距离非常近,模型每次选它俩都要靠运气。精炼时要把这类表述差异扩大化,融合技能的名字、触发条件要和库内其他技能有明确的语义区隔。说白了,就是要让每一条技能都有自己的"人设",不能做一对孪生兄弟。
4.4 目标四:检索效率最大化
检索效率目标衡量的是精炼之后库的"可检索性"。我常用三个指标:
- 候选召回率:给定一个测试查询,Top-10里包含正确技能的比例。
- 排序稳定度:多次检索同一查询,正确技能排名的方差小,说明索引对噪声文本不敏感。
- 延迟P95:检索链路端到端耗时。
第四个目标与第二个目标有一定关联,但不完全一样。容量变小通常会让检索变快,但如果在精炼时把两个不同领域的技能合并成一条"四不像",看似容量下来了,检索时正确技能的排名反而会下降。所以检索效率必须被独立考察,不能假设容量小了就一定更快更准。
4.5 多目标联合求解:加权评分还是帕累托前沿
四个目标方向不完全一致,怎么联合求解?SkillBrew这类工作的通常做法有两种,我分别说说适用场景。
加权评分法适合工程团队快速落地。给四个目标各分配一个权重,算出每个候选精炼方案的总分。权重的分配建议按业务主导方向来:如果当前最大的痛点是Token超支,就把容量目标权重调高;如果线上成功率在下滑,就把有效性权重拉满。加权的缺点是容易"平均化"——一个方案如果有效性和容量都中等,总分可能比"有效性极高、容量中等"的方案更高,但工程上我们往往更想保留极端优势的方案。
帕累托前沿法更适合研究团队或对库质量要求极高的场景。它的思路是不提前指定权重,而是求解一组"没有任何一个目标能单独改进而不损害其他目标"的方案集合,再让库维护者在这个集合里人工选择。这样做的好处是决策空间更透明,不会因为权重设错而得到一个糟糕的合并方案。代价是计算复杂度更高,对技能库规模大、更新频繁的场景,需要做成离线异步任务。
我在自己系统里用的是两阶段法:先跑一遍规则硬过滤,把明显该删除、该归档的技能拿出来,不参与多目标计算;剩下真正模糊的候选组,再用帕累托法做一次有限枚举,给维护者列出两到三个备选方案。既控制计算成本,也保留决策的灵活性。
5. 我关注的实验数据与关键结论
5.1 效果指标:成功率不掉,库体积明显下降
从论文展示的典型实验数据和我的复现结果来看,SkillBrew在多个任务域上的核心结论是一致的:经过多目标精炼后,技能库规模可以压缩到原来的50%到70%,Token总量下降约三成,而任务成功率基本持平,甚至在某些泛化测试集上有小幅提升。
这个结果说明两件事。第一,大量冗余技能确实是Agent决策的"负资产"——删掉它们不仅没让效果变差,反而减轻了模型的选择负担。第二,精炼不是单纯的删除,融合技能保留了原技能组里的有效边界条件,所以覆盖面没有明显缩水。
容量下降带来的连带收益往往在实验指标之外。技能总数减少之后,每次决策时参与检索的候选集合变小,延迟自然下降;技能描述信息密度提高,上下文窗口里能完整展示的候选技能更多,模型的"选择视野"反而变大了。我在项目里实测的检索P95延迟从接近500毫秒降到340毫秒左右,这是一个非常可观的收益。
5.2 长尾效应:小规模库反而提升泛化
比容量下降更让我惊喜的是泛化能力的提升。在技能库膨胀到四五百条时,Agent在几个少样本新任务上的表现反而非常不稳定。我分析日志后发现,模型经常被旧技能误导——新任务和某个旧技能在表述上有表面相似,但实际逻辑不同,模型选了旧技能之后一路跑偏。
精炼之后,那些"表面相似、实际不适用"的误导性技能被合并或删掉了,Agent的检索结果更干净,少样本场景下的表现反而上升了。这个现象其实点出了技能库管理的一个反直觉结论:经验越少越杂,越会压制模型的泛化能力;经验越精炼,越能发挥大模型本身的理解力。SkillBrew这种"经验做减法"的思路,本质上是在给大模型腾出基于常识推理的空间,而不是让它困在大量相互矛盾的"经验"里。
5.3 论文讨论中没有明说的边界
SkillBrew不是万能的,有几个边界条件我认为比方法本身更值得在意。
第一,技能粒度的把握。精炼如果做得太狠,把不同子领域的技能强行合并成一条"超级技能",会让这条技能的操作步骤又长又复杂,Agent执行到一半就容易偏离。我自己的经验是:合并的下限是"触发场景重合度",不是同一个大领域就自动该合并,只有触发场景确实大量重叠、且操作步骤有90%以上共性的技能才值得融合。
第二,跨领域技能分组要分开处理。文本向量聚类时,如果库里同时有代码生成类技能和客服话术类技能,聚类算法可能把一些边缘情况分到一起,产生无意义的融合。实际操作中我会先按领域标签粗分,再在各领域内部做冗余分组。
第三,精炼频率不是越高越好。精炼本身是有成本的,而且每次库更新之后Agent的检索行为会有一定的"记忆漂移",如果频率太高,线上效果可能一直在波动,稳定性反而不如带一点冗余的旧库。我在实践中用这个节奏:新技能入库时做轻量去重,每周做增量精炼,每个月做一次全库复评,除非线上指标出现明显下滑,否则不额外加频。
6. 落地SkillBrew时绕不开的实战细节
6.1 精炼频率与触发时机怎么定
前面提到过节奏问题,这里展开讲一下如何设计触发机制。我建议把触发放到监控体系里,而不是靠人工拍脑袋。四个典型触发信号:
- 技能总量或Token总量超过软阈值;
- 线上任务成功率连续一周持续下滑,且下滑趋势与技能库新增量正相关;
- 检索延迟P95连续三天超标;
- 冲突检测报告里,新的高冲突技能对数量突然增加。
一旦触发,就自动生成精炼任务,进入流程执行。如果多个信号同时触发,优先处理冲突指标,因为冲突对线上成功率的伤害是立竿见影的。
6.2 回滚机制与灰度验证
任何库更新都有风险,SkillBrew落地也一样。我强烈建议不要做"一次性全量替换",而是引入回滚和灰度机制。
每次精炼生成的新技能,先在影子环境里用历史流量回放一遍,观察虚拟决策结果;通过之后,再对10%的真实流量开启灰度,运行24小时对比成功率、延迟、Token消耗。确认没有劣化后逐步放量到50%、100%。同时,每次精炼前把原技能组完整快照备份,一旦新技能在灰度中出现"某些边界场景表现崩了",可以一键回滚。
这个流程看起来保守,但非常值得。因为技能库精炼的影响面是全局的——一条融合技能可能影响几十种任务的决策路径,不像改一行代码那样容易定位副作用。
6.3 Embedding相似度不可全信:行为等价才是核心
这是我在落地过程中踩得最深的一个坑,必须单独说。第一次跑冗余分组时,我图省事,直接按文本向量的相似度阈值来合并技能。结果合并出来的"融合技能"在回归测试上表现极差,仔细一查才发现,两条技能文本高度相似,但核心逻辑不同:一条走新接口,另一条走旧接口,输出结构完全不同。把它们合并之后,模型在一个任务上随机选用新旧接口,线上数据直接乱了。
第二次我调整了策略:文本相似度只用来生成候选分组,是否真正合并必须再看行为等价。具体做法是准备一组覆盖两个技能各自典型场景的验证任务,把两条技能分别跑一遍,比较输出结果的相似度(结构化输出可以算字段级一致率)。只有行为等价判定通过,才允许进入融合环节。这个追加环节虽然增加了精炼成本,但避免了大量"合并一时爽、线上火葬场"的事故。
行为等价判定还有一个配套细节:验证任务要覆盖边界输入,不能只挑两个技能都比较擅长的中间场景。边界输入恰恰是两条技能最容易产生分歧的地方,如果这些分歧在融合时没有被发现,它们就会成为新技能内置的隐患。
6.4 精炼成本的控制
最后聊一个现实问题:精炼过程本身也是要花钱花时间算力的。让大模型逐组生成融合技能、跑回归验证、重建向量索引,都需要消耗计算资源。我控制成本的方式有三个。
第一,强模型生成,弱模型验证。融合技能的生成必须用最强的模型,因为这一步质量决定上限;但回归验证阶段可以用中等规模模型批量跑,只要验证逻辑固定、判定标准明确,成本能降一个量级。第二,做增量精炼。全库复评不用每次都跑,日常只处理新增技能和触发告警的分组。第三,优先处理高收益分组。落后先按冲突度和Token占用给候选组分个优先级的排序,先从问题最严重的组动刀,而不是平均用力把所有组都精炼一遍。
我算过一个粗账:在我们这个规模的库上,一次全量复评的大模型token成本大约相当于线上跑一天技能调用的token开销。如果精炼能把技能总Token量压下来三成,这个成本一两周就能从在线推理开销里省回来。从长期看,定期精炼不是纯支出,它是一笔投资性开销。
最后再分享一个我个人的经验收尾:SkillBrew这套多目标精炼思路,本质上不是教你"删技能",而是教你建立一个让技能库保持高质量的维护机制。我在自己的项目里跑通这套流程之后,最大的变化不是技能变少,而是团队对技能库的信任度变高了——模型选技能的时候不再像抽盲盒,维护者看库的时候也不再觉得处处是雷。技能库这个东西,少而精永远比多而杂可信。如果你也遇到技能库越用越难受的情况,别急着继续往里加技能,先认真做一次减法。