AI Agent Skill 上线后,如何持续维护
Skill 上线不是终点,而是它第一次接触真实任务的开始。真正难的工作不是把
SKILL.md写出来,而是持续回答三个问题:它有没有被正确触发、有没有按预期执行、改完之后有没有伤到旧场景。本文是「AI Agent 技能(Skill)实战解析」的后续。上一篇讲怎么设计和编写 Skill,这一篇只谈上线之后:如何收集反馈、定位失败、建立评测、管理版本,以及在必要时安全地下线一个 Skill。
本文脉络: |
一、为什么 Skill 上线后一定会变
刚写完的 Skill 往往看起来很可靠。示例任务能跑通,规则也没有明显冲突,目录结构干净得像刚装修完的房子。
真实用户一进来,问题就开始了。
有人只说一句「帮我整理一下」,你以为他要写文档,他其实想整理 Excel;有人把一个 200 页 PDF 和一句模糊要求一起丢进来;还有人会在同一次任务里同时触发三个 Skill,让它们争夺工作流的控制权。
这不是模型“不听话”,而是上线前的样本太少。Skill 的行为至少受四类变量影响:
| 变量 | 典型变化 |
|---|---|
| 用户表达 | 同一个意图有几十种说法,甚至没有明确关键词 |
| 输入材料 | 文件格式、大小、质量和缺失字段都不可控 |
| 运行环境 | 工具权限、依赖版本、目录结构和网络状态会变化 |
| 模型能力 | 模型升级后,触发判断和指令遵循可能发生漂移 |
所以我更愿意把 Skill 看成一种行为接口。它虽然不是传统 API,却一样有输入、输出、依赖和兼容性问题。既然是接口,就不能靠“作者感觉应该没问题”来维护。
上线后的目标也不是让它永远不出错。更现实的目标是:
发现失败的速度,比失败扩散的速度快; |
二、先把失败分对类
维护 Skill 最容易踩的坑,是看到一次失败就往 SKILL.md 里补一句规则。补了十几次之后,主文件变成一份充满例外条款的免责声明,Agent 反而抓不住重点。
动手改之前,先判断失败发生在哪一层。
1. 触发失败
该触发时没有触发,或者不该触发时抢了别人的任务。
例如一个技术写作 Skill 只在用户说“博客文章”时触发,但用户说“把这段数据库笔记整理成可发布的长文”时没有触发。这通常是 description 覆盖的表达太窄。
反过来,如果用户只是让 Agent 修改一段 README,它也强行进入完整写作流程,那就是触发范围写得太宽。
这类问题应该改元数据,重点检查:
- 有没有写清楚“做什么”;
- 有没有覆盖用户真实使用的措辞;
- 有没有明确不适用的边界;
- 是否与其它 Skill 的描述高度重叠。
2. 路由失败
Skill 已经触发,但选错了内部路径。
比如技术写作 Skill 同时支持博客和公众号,用户明确说“发公众号”,Agent 却生成了 Hexo front-matter。这不是触发问题,而是模式判断出了错。
路由失败通常需要改决策条件,而不是增加更多写作规则。
如果目标载体已经明确,直接进入对应模式。 |
3. 执行失败
路径选对了,但步骤漏了、顺序错了,或者输出不符合要求。
例如文档生成 Skill 已经选中 .docx 流程,却没有做渲染检查;部署 Skill 修改了配置,却忘了运行构建。这类问题适合增加检查点、脚本或明确的完成条件。
4. 环境失败
网络、权限、依赖、文件路径或外部服务不可用。
环境问题很容易被误诊成指令问题。代理端口没启动时,继续优化“重试规则”没有意义;缺少数据库权限时,往 Skill 里加一句“务必写入数据库”只会让报错更执着。
维护记录里要把这类失败单独标记,因为它们通常需要修工具、配置或部署环境。
5. 预期本身不合理
还有一类失败最隐蔽:Skill 忠实地执行了规则,但规则本身已经过时。
例如最初要求所有任务都生成详细计划,后来发现简单改字也要先列五步计划,成本远大于收益。这时应该删规则,而不是教模型“在简单任务里把计划写短一点”。
一句经验:能删掉一条错误规则,就不要再补三条例外。
三、建立最小可用的反馈闭环
不需要一上来就做复杂的可观测平台。一个 Skill 刚上线时,维护者真正需要的只有少量高质量信号。
1. 每次失败至少记录什么
建议保留以下字段:
| 字段 | 用途 |
|---|---|
| 用户原始请求 | 判断触发和路由是否合理 |
| 被触发的 Skill 与版本 | 确认问题来自哪一版 |
| 选择的内部路径 | 区分触发失败和路由失败 |
| 最终结果 | 查看实际偏差,而不是只看报错 |
| 用户修正 | 用户改了什么,往往比“满意/不满意”更有价值 |
| 失败分类 | 触发、路由、执行、环境或规则问题 |
| 是否可复现 | 决定能否加入回归评测 |
注意隐私边界。日志里可能包含代码、客户数据、文档内容和账号信息。能记录结构化摘要,就不要默认保存完整输入;必须保存时,要明确访问权限和保留期限。
2. 别只收集差评
只看失败案例会把 Skill 越改越保守。维护者还需要知道它在哪些场景表现稳定,否则很容易为了修一个边缘问题,把主流程改坏。
我通常会同时保留三类样本:
黄金样本:必须一直做对的核心任务 |
黄金样本保证“基本盘”不退化,事故样本保证同一个坑别踩两次,边界样本则专门测试那些看起来不像正常用户、但偏偏每天都会出现的输入。
3. 用户修正是最值钱的反馈
“结果不好”信息量很低。“不要改原文结构,只修复术语错误”就具体得多。
如果同一种修正反复出现,不要急着把用户的话原样追加到 Skill。先问:
- 这是通用规则,还是某个项目的偏好?
- 应该放在
SKILL.md,还是项目级指令? - 能不能变成一个自动检查,而不是自然语言提醒?
- 它是否会与现有规则冲突?
Skill 不是所有反馈的垃圾桶。
四、用评测集守住质量底线
没有评测集的 Skill,维护方式通常是“改完跑一个示例,感觉好多了”。这种感觉非常不可靠。
最小评测集不需要几百条。先选 15~30 个有代表性的任务,就能拦住大量回归。
1. 评测什么
Skill 的评测至少分四层:
| 层级 | 评测问题 | 示例指标 |
|---|---|---|
| 触发 | 该用时用了,不该用时没用吗 | 触发准确率、误触发率 |
| 路由 | 是否选择了正确模式和参考资料 | 路由准确率 |
| 过程 | 是否执行关键步骤 | 检查点通过率 |
| 结果 | 最终产物是否可用 | 构建成功、格式正确、人工评分 |
只评最终文本容易掩盖过程问题。一次构建成功,可能只是模型碰巧生成了正确配置;如果它没按要求检查仓库状态,下次就可能覆盖用户改动。
2. 把模糊要求变成可判定条件
“文章写得专业”很难自动评测,但可以拆成:
- front-matter 是否包含必需字段;
- 是否有
<!-- more -->; - 主章节是否使用中文编号;
- 是否引用了不存在的内部链接;
- 构建是否通过;
- 是否出现禁用的套路化表达。
能用脚本判定的,不要全交给另一个模型打分。模型评审适合判断表达质量、事实一致性等开放问题;文件存在、字段完整、命令成功这些事情,确定性检查更便宜也更可信。
3. 每次线上事故都要变成回归样本
一次故障只有进入评测集,才算真正修完。
建议给案例一个稳定编号:
id: TW-017 |
以后无论改 description、工作流还是参考资料,都重新跑这条。否则三个月后很可能有人“优化结构”时把旧问题重新放回来。
五、版本管理:什么改动算破坏性变更
Skill 也应该有版本号。不是为了看起来专业,而是为了回答一个实际问题:线上失败到底发生在哪一版?
可以沿用语义化版本的思路:
PATCH:修正文案、补充示例,不改变既有流程 |
下面这些改动,我会按破坏性变更处理:
- 原来默认生成草稿,现在默认直接写文件;
- 原来允许自主发布,现在必须等待用户确认;
- 修改输出文件名或目录;
- 删除一个已公开的模式;
- 更换必须安装的工具;
- 改变与其它 Skill 的职责边界。
1. 保留变更记录
不必写成大型项目的发布公告,但至少说明:
## 1.3.0 - 2026-07-27 |
变更记录最重要的不是“改了什么文件”,而是“用户能观察到的行为发生了什么变化”。
2. 不要悄悄改变输出契约
如果下游脚本依赖 Skill 生成的文件名、字段或目录结构,一个看似无害的重命名也可能让整条工作流断掉。
维护时应把稳定部分明确成契约,例如:
输入契约:接受 Markdown、Word、PDF |
契约之外的措辞和内部步骤可以灵活优化;契约变更则需要升大版本、迁移说明或兼容期。
六、发布策略:从本地验证到灰度上线
直接修改所有用户正在使用的 Skill,然后观察有没有人报错,是最省事也最昂贵的发布方式。
更稳妥的流程是:
修改草案 |
1. 静态检查
先检查那些不需要模型运行的问题:
- frontmatter 是否合法;
name是否与目录一致;- 引用的文件和脚本是否存在;
- 相对路径是否正确;
- 是否出现互相冲突的指令;
- 主文件是否膨胀到难以阅读;
- 示例中是否残留密钥和真实用户数据。
2. 影子运行
影子运行的意思是:新版 Skill 读取真实任务并生成结果,但不把结果交给用户,也不执行写操作。维护者只比较新旧版本的决策和产物。
它尤其适合验证触发逻辑。因为“新版会不会抢走别的 Skill 的任务”,靠离线构造几个例子很难看全。
3. 灰度与回滚
如果运行平台支持版本选择,先让少量用户或内部任务使用新版。观察指标没有明显恶化,再逐步扩大。
每次发布都应保留一个能快速切回的稳定版本。回滚条件要提前写清楚,例如:
核心任务成功率下降超过 5% |
别等事故发生后再开会讨论“这算不算严重”。
七、依赖、兼容性与安全维护
Skill 自身可能只是一组 Markdown,但它依赖的世界一直在变。
1. 建一张依赖清单
至少记录:
| 依赖类型 | 例子 | 维护动作 |
|---|---|---|
| 模型 | 默认模型、上下文长度 | 模型升级后跑完整评测 |
| 工具 | 浏览器、Shell、文档渲染器 | 跟踪接口和权限变化 |
| 外部服务 | GitHub、Slack、Cloudflare | 检查认证、限流和 API 版本 |
| 项目约定 | 目录、构建命令、模板 | 仓库变更时同步 Skill |
| 参考资料 | 官方文档、规范 | 定期检查链接和版本 |
最常见的维护事故不是 Skill 主文件写错,而是它引用的脚本改了参数,或者项目已经换了构建命令。
2. 模型升级必须重跑评测
新模型通常更强,但“更强”不等于“行为完全兼容”。
它可能更主动地调用工具,也可能更少询问用户;过去必须写得很细的步骤,新模型已经能自己推断;过去一句话就能约束住的边界,新模型反而会做更远的扩展。
所以模型升级应当被当成一次依赖升级,而不是免费性能提升。
3. 定期做安全审查
重点检查:
- 是否可能泄露环境变量、凭证或用户文件;
- 外部内容能否通过提示注入改变工作流;
- 写操作是否有清晰授权边界;
- 删除、覆盖、发布等动作是否可恢复;
- 日志是否记录了不必要的个人或业务数据;
- 引用的脚本和依赖是否来自可信来源。
尤其要警惕“为了减少确认步骤”而不断放宽权限。流畅和失控之间,有时只差一句“默认直接执行”。
八、什么时候应该拆分、合并或退役
不是所有维护都应该继续往原 Skill 里加内容。
1. 该拆分的信号
- 主文件越来越长,大量章节只服务于特定场景;
- 触发描述需要列出互不相关的任务;
- 不同模式使用完全不同的工具和产物;
- 修改一个模式时,经常让另一个模式回归;
- 用户只想用其中一部分,却每次加载整套规则。
先考虑把细节拆到 references/。如果连触发条件、流程和产物都不同,再拆成独立 Skill。
2. 该合并的信号
- 两个 Skill 总是一起触发;
- 职责边界需要反复向模型解释;
- 输入输出几乎相同,只差少量参数;
- 用户根本分不清应该点哪个。
Skill 不是越多越好。数量多到需要另一个 Skill 来解释“该用哪个”,通常说明分类出了问题。
3. 该退役的信号
- 平台已经原生提供同等能力;
- 长期没有真实调用;
- 维护成本明显高于带来的收益;
- 依赖已停止维护或存在安全风险;
- 新 Skill 已完整覆盖旧能力。
退役不要直接删除。先标记 deprecated,给出替代方案和迁移时间;观察没有剩余调用后,再停止分发。涉及输出格式变化时,还要保留读取旧格式的兼容窗口。
九、一套可执行的维护节奏
维护最怕“有空再看”。下面这套节奏不重,但足以让一个中小规模 Skill 保持健康。
每周
- 查看新增失败和用户修正;
- 给失败分类,合并重复问题;
- 把可复现事故加入回归集;
- 修复高频且影响核心流程的问题。
每次发布
- 更新版本号和变更记录;
- 跑静态检查与完整回归;
- 检查输出契约是否变化;
- 记录依赖版本;
- 确认回滚版本可用;
- 观察发布后的错误率与人工反馈。
每月
- 清理重复、冲突和已经失效的规则;
- 检查外部链接、脚本和工具接口;
- 复盘误触发率和任务成功率;
- 审查日志字段与权限;
- 评估是否需要拆分、合并或退役。
可以把这份清单直接放进 Skill 仓库:
## Release Checklist |
真正成熟的 Skill,不是规则最多,而是每条规则都能解释自己为什么存在。
十、常见问题
| 问题 | 回答要点 |
|---|---|
| Skill 多久更新一次合适? | 不要按日历强行发版。高影响故障立即修,普通改进攒成小版本;即使没有发版,也应定期检查依赖和反馈。 |
| 用户说“不好用”,应该立刻改吗? | 先拿到原始请求、实际结果和用户修正,确认失败类型。单个偏好不一定适合上升为全局规则。 |
| 评测集需要多少案例? | 先从 15~30 个高价值案例开始,覆盖核心、事故和边界场景。数量不是目标,能拦住真实回归才是。 |
| 可以只靠另一个模型评审吗? | 不建议。格式、文件、命令和构建结果优先用确定性检查;模型评审留给表达质量和语义一致性。 |
SKILL.md 越写越长怎么办? |
通用流程留在主文件,场景细节拆到 references/;如果触发条件和产物也不同,再拆成多个 Skill。 |
| 模型升级后需要改 Skill 吗? | 不一定要改,但必须重跑评测。先用结果证明兼容,再决定删规则还是补约束。 |
| 如何判断维护是否有效? | 看核心任务成功率、误触发率、人工修正率、平均修复时间和回归数量,而不是看新增了多少规则。 |
| 旧 Skill 可以直接删除吗? | 不要。先标记废弃、提供替代方案和迁移期,确认没有剩余调用后再下线。 |