Skip to main content

Skill 上线后,怎么维护?三类失败、四类测试集、自动进化与版本追踪

· 9 min read

Skill 维护的核心是钉住 5 件事:成功标准、失败点、测试集、进化、版本。少一类,评估是空的。

  • 成功结果 / 过程 / 风格 / 效率,缺一类评估就漏
  • 失败:触发 / 环境 / 执行 3 类,每类独立观察、独立维护
  • 测试集:显式 / 隐式 / 上下文 / 副测试集,10-20 条就够
  • 进化:失败信号 → 候选补丁 → 新能力验证 → 基线回归 → 灰度
  • 版本:git 单一来源——commit / tag / push 三件套,不另起基础设施
  • 结论:Skill 进生产就是工作流资产——靠体感维护必然崩,按这 5 件事维护才能稳

真正的问题不是"会不会跑通"

Skill 上线后最常见的方式:每次改完跑一下,没报错就发。这是 盲改——你根本不知道这次是优化还是回归。

更深的漏洞在第二层:不接真实工作流,行为边界会悄悄漂移,进入生产后才暴露:

失控征兆第一次暴露时机
该触发的没触发用户第一次手动重写一遍请求
不该触发的被触发用户第一次报错"它乱动了"
触发对但绕路上线一周后看 token log
风格飘了(命名/结构)下游组件第一次接不住

你要的不是"每次跑通",是一个能在它偷偷变坏时告诉你"变坏了"的机制

第一步:拆成功标准(不能只看"任务做完没")

任务能跑通 ≠ Skill 行为可靠。任务跑通只是结果目标,还有 3 类目标会被默认忽略:

类型验证什么漏评的后果
结果任务完成、产物可用最直觉,也最容易被当成全部
过程agent 真的按预期调用了工具链绕路完成 ≠ 行为可靠
风格输出结构、命名、依赖规范单次没差,下游接不住才放大
效率是否乱跑命令、无意义 retry单次无所谓,接入生产才看得到

关键不是这 4 类文字本身,是它们要分开评估。过程目标和结果目标经常矛盾:任务完成了,但 agent 多绕了 2 步不该跑的工具调用——单次没差,长期维护成本在涨。

tip

没写出来的成功标准,等于不存在。把 4 类目标写成一行一句的评估措辞,塞进 Skill 的副文档里,比放在脑子里有效 10 倍。

第二步:定位三类会失控的点(每类单独盯)

触发假设——description 在 Skill 里同时干两件事:

  • 触发匹配:决定哪些 prompt 该加载这个 Skill
  • 角色定位:触发之后,description 是 agent 看到的开场白,决定它怎么解读后面的 instructions——同一条 instructions 里写"重搭项目",被"前端样式专家"读到是"我只动样式",被"前端工程专家"读到是"我来搭脚手架"

所以改 description 一行字,会同时改"谁该触发"和"agent 怎么看 instructions"——这两层出问题常常分不清是哪层塌的。糊法有两种典型:

  • 误触发:description 写"做前端项目",用户问"我的 npm install 失败了",Skill 也被触发,去读 package.json 然后新建了一份 demo 项目——用户只是想问个 npm 报错,根本不该进前端工作流
  • 触发对了但边界没约束:description 写"改前端样式",用户说"加个 header 样式",Skill 触发是对的;但 instructions 没强调"只改 CSS、不动结构",结果它顺手搭了一份 demo 项目——触发没问题、触发后失控

环境假设——决定它在哪种机器上能跑。Skill 不会默认自己永远在空目录里,也不会默认某个包管理器已经装好。这类失控最隐蔽,因为你本地刚好满足前提,换一台机器、换一个 CI runner 就全失效。

执行假设——决定 agent 走每一步时怎么安排顺序。每一步单独看都对、顺序错了整个执行会在某个中间状态卡死。常见:先跑了 lint/build、再装依赖,结果依赖没装好后续步骤一连串跳过。

warning

3 类独立可观察,3 类也需要独立维护。改 description 想优化触发假设,等于改了 2 个维度的契约——出问题不知道是哪一类出的。

第三步:写一份回归 prompt 测试集(10-20 条就够)

测试集类型测什么防线
显式调用直接点名改 description / 指令后基础防线不能破
隐式调用用户只描述场景触发边界质量
带上下文调用任务里混入真实业务噪声下能否识别
副测试集不该触发画边界,不是测性能

副测试集是最容易忽略的一类,也是最危险的失控点。它测的不是"会不会触发",是"该不该触发"。你本来只想做增量改动,它把整个架子重搭——这种失控进生产,修复成本数倍于日常维护。

tip

一条带元数据的用例比十条裸用例有用。每条用例要带 5 字段:类别 + prompt + 期望触发 + 期望产出 + 失败模式标签。没有元数据,3 个月后你自己都不知道这条用例在测什么。

第四步:自动进化(出现失败信号怎么改)

维护的第 4 步是让 Skill 能从失败里自动进化——但前提是前三步(成功标准 / 失败点 / 测试集)已经稳了,否则自动进化只是在加速腐烂。

[信号采集] → [候选补丁] → [新能力验证] → [基线回归] → [灰度发布] → [CHANGELOG]
↑ ↓
└────────────────────[ 复盘 → 下个版本 ]─────────────────────────┘

信号采集——失败信号从 4 个入口来:用户反馈("它又乱动了")、产物检查(输出目录里出现未预期的子目录)、效率异常(跑一个简单任务调了 30 个工具调用)、副测试集失败(最容易自动化的一类)。

候选补丁生成——先反推信号属于 4 类失败中的哪一类,再写最小补丁:

  • 触发假设漂了 → 改 description
  • 环境假设漂了 → 改 instructions 的 environment 段落
  • 执行假设漂了 → 改 instructions 里的步骤顺序
  • 不要跨维度同时改
danger

永远不要让 LLM 直接写 SKILL.md。永远以补丁建议产出,落盘前必须人 review。Skill 一旦自动化改自己,回归把所有用例都破了都没人发现——上一版本的测试集白维护了。

新能力验证——新能力相关测试集 100% 通过;

基线回归——老 baseline 必须全部不破;这一步没做就上线,等于上版本的测试集白维护了。

灰度发布——5% → 25% → 100% 流量逐步扩,每阶段看副用例失败数是否变多。副用例是版本升级的金丝雀:副用例失败说明触发边界扩了,得回滚。

tip

自动进化的最小目标不是"Skill 自动变好",是把"修了这次指令就没人管"变成"每次改动都有失败信号回灌"。失败信号流建成了,比 Skill 是否真"智能"重要。

第五步:版本追踪

Skill 版本管理最省力的方式是直接交给 git——不需要单独的 version.txt / package.json,不需要手写 CHANGELOG。commit 是变更记录,tag 是版本号,push tag 是分发,三件套全部复用现成 git 设施。

三步自动化

  1. 每次修改自动 commit——粒度精细到一次改动一条 commit,AI 自动生成 commit message(人类不再手写 subject)。回退走 git revert <sha> / git reset <sha>,比卸载再装一个旧版本简单一档
  2. 人类 review + approve——commit message 就是 changelog 草稿,git log v0.9.0..v1.0.0 直接当发布说明扫一遍
  3. 打 tag + push——approve 通过后给这一组 commit 打 vX.Y.Z,然后 push tag 到远端。后续 fetch / clone / submodule 都基于 tag,不引用 branch

这一套走通后,版本即 git tag、变更即 commit、changelog 即 git log——Skill 的版本维护跟代码库完全走同一套机制,没有额外基础设施。

warning

依赖 Skill 的项目用 git tag pin,比如 submodule 锁 <v1.2.0>、clone 时 -b v1.2.0 --depth 1不要写 latest、不要写 branch 引用——tag 是不可变、跨机器一致的版本锚点,branch 名会动。

Take Away

  1. Skill 不是 prompt——是带契约的工作流资产,维护不是可选项
  2. description 同时干两件事:触发匹配 + 角色定位。改一行字 = 同时动两个维度,回归出问题分不清是哪层塌的
  3. 副测试集不是测性能——是给 Skill 画边界("该不该触发" 比"会不会触发" 重要)
  4. 加新 + 不破老 才叫升级——新能力验证 + 基线回归两步都得做,缺一就是 regression
  5. 版本追踪完全交给 git——commit 是变更、review 是质量门、tag 是版本、push tag 是分发,零额外基础设施

References

  1. 面试官问:Skill 上线后,你怎么持续维护? —— Agent开发实战, 哔哩哔哩, 2026-07-14