
1. 从写死的技能到会生长的技能为什么这个话题值得单独聊如果你最近在折腾 Agent 相关的东西大概率会遇到一个很尴尬的阶段Demo 跑得挺漂亮工具调得也挺顺但一旦把 Agent 放到真实场景里跑上几天你就会发现它的技能是死的。今天你给它写了三个 skill它就只会这三件事明天业务多了一个新需求你得手动再写一个 skill 塞进去后天发现某个 skill 的参数老是不对你又得回去改 prompt、改 schema、改示例。改到最后整个 skill 库变成了一堆没人敢动的祖传代码。这个问题的本质是技能的生产方式还停留在人工手写阶段。而 Agent Skills 这个系列想聊的核心就是怎么让技能从知识和经验里自动生成并且在使用过程中持续演化。这不是一个纯学术问题它直接决定了你的 Agent 能不能从一次性工具变成越用越顺手的助手。我先把这篇要讲的东西摊开说清楚SkillGen讲的是技能怎么从知识里被生成出来Anything2Skill讲的是任意形态的输入文档、对话、操作记录怎么转成可执行技能Trace2Skill讲的是从执行轨迹里反向提炼技能。这三条路径合起来构成了技能从知识和经验两个源头生长的完整链路。而持续演化则是这条链路的后半段——技能生成出来不是终点它得能被验证、被修正、被合并、被淘汰。适合读这篇的人有三类一是正在做 Agent 平台、需要设计 skill 管理机制的工程师二是被skill 越写越多、越写越乱折磨过的开发者三是对 Agent 架构感兴趣、想搞清楚 skill 这一层到底该怎么设计的技术负责人。不管你现在用的是哪套框架这套思路都是通用的因为它解决的是机制问题不是某个 SDK 的 API 问题。下面我会按知识怎么变技能经验怎么变技能技能怎么演化演化过程中会踩哪些坑这条主线往下讲中间会穿插具体的结构设计、参数取舍和实操心得。有些地方我会给出伪代码和数据结构你可以直接拿去改。2. SkillGen把静态知识拆成可执行技能的三层结构2.1 为什么知识直接塞进 prompt是条死路很多人做 skill 的第一反应是把一段知识文档直接塞进 system prompt然后告诉模型你要按照这个来。这个做法在知识量小的时候能跑但一旦知识超过几千字问题就全出来了模型会漏读、会串行、会把不同章节的规则混在一起用。更麻烦的是你没法知道它到底用了哪条知识出了问题也没法定位。SkillGen 的核心思路是把知识先拆成结构化的技能单元再让模型按需调用。这里的技能单元不是一段文字而是一个有明确边界的结构体。我一般把它设计成三层触发层Trigger什么情况下该用这个技能。包括意图描述、关键词、前置条件。执行层Execution具体怎么做。包括步骤序列、工具调用、参数约束。校验层Validation做完之后怎么判断对不对。包括输出格式、成功条件、失败回退。这三层分开设计的好处是每一层都可以独立演化。触发层不准就调触发层执行层老出错就改执行层校验层太松就收紧校验。而不是像 prompt 那样改一个字整个行为都变了。2.2 从文档到技能切分粒度怎么定知识来源最常见的就是文档。把文档变成技能第一个要决策的就是切分粒度。切太粗一个技能管一大片模型执行时还是要自己判断细节切太细技能数量爆炸检索和编排成本飙升。我的经验是按一个技能对应一个可独立完成的任务来切。判断标准很简单如果这个任务做完之后有一个明确的、可验证的结果那它就是一个技能。比如从合同里提取甲方乙方和金额是一个技能审核合同就不是——它太宽了应该拆成提取、比对、生成意见三个技能。具体操作上我会走这么几步先做任务清单把文档里所有需要 Agent 做的事列出来用动词开头一句话一个。合并同类项把动词相同、对象不同的合并成一个技能用参数区分。比如提取合同金额和提取发票金额可以合并成提取金额用文档类型做参数。标注依赖哪些技能必须在另一些技能之后执行形成有向图。补全校验每个技能写清楚什么算成功。这套流程走下来一份 50 页的文档通常能拆出 15 到 30 个技能。如果拆出来超过 50 个说明粒度太细了要往回合并。2.3 技能描述怎么写才能被模型稳定选中技能生成出来之后最大的挑战不是执行而是被正确选中。模型面对几十个技能经常选错或者选了个不该选的。这里的关键在触发层的描述质量。我踩过的坑是一开始把技能描述写得很专业用了很多领域术语结果模型反而选不准。后来改成用大白话描述什么时候用命中率明显上来了。比如不要写执行实体关系抽取而要写当用户给了一段文字想让你找出里面的人名、公司名和它们之间的关系时用这个。另外几个实操要点负向描述很重要明确写这个技能不适用于什么情况能大幅减少误选。比如提取金额技能里要写如果文档是图片且没有 OCR 结果不要用这个技能。给 2 到 3 个正例不用多两三个典型例子就够多了反而稀释重点。触发关键词要覆盖同义表达用户说多少钱金额总价费用都得能命中。下面是一个技能结构体的示例可以直接参考{ skill_id: extract_amount_v2, trigger: { intent: 从文本中提取金额信息, keywords: [金额, 总价, 费用, 多少钱, 报价], negative: [图片无OCR, 纯语音输入], examples: [ 这份合同的总金额是多少, 帮我看看发票上的费用 ] }, execution: { steps: [定位金额相关段落, 识别币种和数值, 归一化格式], tools: [text_search, regex_extract], params: {currency_default: CNY} }, validation: { output_schema: {amount: number, currency: string}, success_condition: amount 非空且大于 0, fallback: 返回未找到并说明原因 } }这个结构看起来简单但它把什么时候用怎么用怎么算对三件事彻底分开了后面演化的时候就能精准定位问题。3. Anything2Skill任意输入转技能的通用管道3.1 输入形态决定了转换策略Anything2Skill 这个名字听起来很泛但落到实操上核心是根据输入形态选择不同的转换策略。常见的输入有这么几类每类的处理方式差别很大输入形态典型来源转换重点主要难点结构化文档手册、规范、SOP抽取步骤和条件隐含前提的补全半结构化会议纪要、聊天记录识别任务和责任人口语到指令的转译操作轨迹点击流、API 调用日志还原意图和参数噪声步骤的过滤自然语言口述用户直接描述澄清和补全歧义消解代码/脚本已有自动化脚本抽象成技能接口硬编码参数的泛化我做过一个比较典型的项目是把客服团队的历史工单转成技能。工单是半结构化的有标题、描述、处理步骤、结果。直接扔给模型让它总结成技能出来的东西全是废话。后来改成分字段处理标题用来生成触发意图处理步骤用来生成执行序列结果用来生成校验条件。这样每个字段各司其职生成质量立刻上来了。3.2 从操作轨迹里去噪是成败关键Trace2Skill 和 Anything2Skill 在处理轨迹类输入时是重叠的这里重点讲去噪。操作轨迹最大的问题是噪声极多用户点了无关的按钮、来回切换页面、重复操作、误操作后撤销。如果不去噪生成的技能里会混进一堆无用步骤。我的去噪策略分三步合并连续同类操作比如连续五次滚动合并成一次滚动到目标位置。剔除无状态变更的操作只读操作、纯导航操作如果对最终结果没影响就删掉。识别并保留纠错模式有些操作看起来是误操作但其实是发现错了然后改对的固定模式这种要保留因为它反映了真实场景里的异常处理。去噪之后还要做意图还原。轨迹本身只记录了做了什么没记录为什么做。这一步需要结合上下文推断。比如用户先搜索退款政策再点申请退款意图就是按政策发起退款而不是两个独立动作。3.3 参数泛化别让技能只会处理那一个例子从单个例子里生成的技能最大的毛病是参数写死。比如从一次给张三发邮件的轨迹里生成的技能可能是给张三发邮件而不是给指定收件人发邮件。这就是参数没泛化。泛化的做法是识别变量槽位。具体来说把轨迹里所有具体值标出来判断它是常量还是变量如果这个值在不同例子里都一样它是常量保留。如果这个值会变它是变量抽成参数。如果拿不准先抽成参数给它一个默认值。我一般会要求至少用三个不同例子来生成同一个技能这样变量槽位自然就暴露出来了。单个例子生成的技能只能当草稿不能直接上线。def generalize_params(traces): # traces: 同一意图下的多条执行轨迹 slots {} for step in align_steps(traces): values [t.get(step) for t in traces] if len(set(values)) 1: slots[step] {type: const, value: values[0]} else: slots[step] {type: var, samples: values} return slots这段逻辑不复杂但效果很实在。对齐步骤是难点需要按操作类型和对象做匹配不能简单按顺序对。4. Trace2Skill从执行轨迹反向提炼技能的完整链路4.1 轨迹采集要采哪些字段Trace2Skill 的前提是有轨迹可采。很多团队采集轨迹时只记了调用了什么工具、传了什么参数这不够。要支撑技能生成至少得采这些字段时间戳用来判断操作顺序和间隔间隔过长可能是中断。输入上下文用户当时说了什么、看到了什么。动作类型是查询、是写入、还是确认。动作对象操作的是哪个实体。结果状态成功、失败、还是部分成功。后续反应用户是继续、重试、还是放弃。其中后续反应最容易被忽略但它信息量最大。用户重试说明上一步有问题用户放弃说明这条路走不通。这些信号是判断技能质量的重要依据。4.2 从轨迹到技能的抽象层级轨迹是具体的技能是抽象的中间要跨过好几层。我一般分四层来做原始轨迹层一条条记录不做处理。会话层把同一目标的连续操作聚成一个会话。模式层把多个相似会话归纳成一个模式。技能层把模式转成带参数和校验的技能。跨层的关键是相似度判断。两个会话算不算同一个模式要看目标是否一致、步骤序列是否相似、涉及的工具是否相同。我用的相似度是加权组合目标权重最高步骤序列次之工具再次之。阈值一般设在 0.75 左右太低会把不同模式混在一起太高又归纳不出东西。4.3 一个真实案例的拆解过程说个具体例子。有个团队做的是数据报表 Agent用户经常要拉某个时间段某个维度的数据然后生成图表。他们一开始是手工写技能写了十几个还是覆盖不全。后来改成从轨迹生成。采集了两周的轨迹后发现高频模式是这样的先选时间范围再选维度再选指标然后生成图表最后导出。但不同用户的顺序不一样有人先选指标再选时间。这时候如果按固定顺序生成技能就会漏掉变体。他们的处理方式是把顺序无关的步骤标记为可并行/可乱序只对真正有依赖的步骤比如必须先选完维度才能选指标保留顺序约束。这样生成的技能既覆盖了所有变体又不会因为顺序不同而误判为不同技能。这个案例给我的启发是技能生成不是越严格越好而是要区分必须和可以。把约束放松到刚好能保证正确性的程度技能的适用范围才够广。5. 技能演化生成只是起点迭代才是常态5.1 演化触发条件什么时候该更新技能技能生成出来之后不能就放着不管。得有机制判断这个技能该更新了。我总结了几类触发条件失败率上升某个技能最近调用失败率超过阈值说明它可能过时了。参数越界频繁模型老传一些 schema 里没有的参数说明 schema 该扩了。触发误选本该用 A 技能的请求被 B 技能接走了说明触发描述有歧义。人工反馈集中用户或运营集中反馈某个技能不好用。上游知识变更技能依赖的文档更新了技能得跟着改。这几类条件里失败率和误选率是最客观的应该做成自动监控。人工反馈虽然主观但往往能发现自动指标发现不了的问题不能省。5.2 版本管理技能也要有灰度和回滚技能演化最怕的是改坏了没法退。所以技能必须版本化而且要有灰度机制。我的做法是每个技能有skill_id和version调用时记录用了哪个版本。新版本先小流量跑对比成功率和耗时。指标不达标自动回滚到上一版。保留最近 N 个版本方便追溯。这里有个细节技能的版本要和它的依赖一起管。如果技能 A 依赖技能 BB 升级了A 可能也得跟着调。所以版本管理不能只看单个技能要看依赖图。5.3 技能合并与淘汰别让技能库无限膨胀技能库膨胀是个慢性病。一开始几十个半年后几百个一年后上千个然后没人搞得清楚哪个是哪个。要控制膨胀得定期做合并和淘汰。合并的判断标准是两个技能的触发条件高度重叠、执行步骤高度相似、只是参数不同。这种就该合并成一个带参数的技能。淘汰的标准是连续 N 天零调用、或者调用后成功率极低且没有修复价值。我一般每个季度做一次技能库体检输出一份报告新增了哪些、合并了哪些、淘汰了哪些、哪些是僵尸技能。这份报告比任何文档都更能反映 Agent 的真实能力边界。6. 演化路上的坑我踩过的和见过的6.1 过度生成技能不是越多越好最常见的坑是过度生成。有了自动生成能力之后团队容易上头恨不得把每个操作都生成一个技能。结果技能库爆炸检索变慢模型选择变难整体效果反而下降。我的经验是技能数量要控制在模型能稳定选择的范围内。实测下来单个 Agent 的技能数在 30 到 80 之间比较舒服超过 150 就开始明显退化。如果业务确实需要更多技能就得分层先选大类再选具体技能。6.2 演化失控改了 A 崩了 B第二个坑是演化失控。技能之间有依赖改一个可能影响一片。我见过最惨的一次是有人优化了一个基础技能的参数格式结果所有依赖它的上层技能全挂了。避免这个坑的办法是依赖影响分析。每次改技能之前先跑一遍依赖图看看会影响哪些下游技能然后对这些技能做回归测试。这个测试不用很重跑一遍典型用例就行但必须有。6.3 校验缺失技能看起来对但实际错第三个坑是校验太弱。很多技能只校验了输出格式没校验输出内容。结果模型返回了一个格式正确但内容完全错误的结果系统还以为成功了。校验要分两层格式校验和语义校验。格式校验好做schema 一卡就行。语义校验难做但更重要。我的做法是给每个技能配一个最小可信检查比如金额技能检查金额是否在合理区间日期技能检查日期是否在有效范围。这些检查不追求完备但能挡住大部分低级错误。6.4 冷启动没有轨迹时怎么生成技能最后一个坑是冷启动。Trace2Skill 依赖轨迹但新场景一开始没有轨迹。这时候只能靠知识生成也就是 SkillGen 那条路。等积累了一些轨迹之后再用 Trace2Skill 去修正和补充。我的建议是冷启动阶段不要追求技能完备先覆盖最高频的几个场景让 Agent 能跑起来然后在真实使用中收集轨迹逐步演化。想一步到位把技能库建全基本不可能也没必要。7. 一套可落地的技能演化流水线把前面讲的串起来一条完整的流水线大概是这样知识侧文档进来走 SkillGen拆成技能草稿。经验侧轨迹进来走 Trace2Skill提炼成技能候选。合并草稿和候选做去重和合并形成技能库。上线技能带版本上线小流量灰度。监控采集调用数据算成功率、误选率、耗时。演化根据监控和反馈触发更新、合并或淘汰。回归每次变更跑依赖影响分析和回归测试。这条流水线不需要一次建全可以先做 1、4、5 三步跑起来之后再补 2、3、6、7。关键是先让技能能演化起来哪怕演化得很粗糙也比完全静态强。我在实际项目里的体会是技能演化的价值不在于自动化本身而在于它让团队对 Agent 的能力有了可观测、可干预的抓手。以前 Agent 出错你只能猜现在你能看到是哪个技能、哪个版本、哪一步出的问题然后精准修。这个从猜到看的转变才是这套机制真正的意义。最后分享一个小技巧给每个技能加一个last_evolved_at字段记录它上次被更新的时间。定期扫一遍那些半年没动过但还在被调用的技能往往就是下一个该优化的对象。