agent-skills 技能体系:让 AI coding agents 从玩具变成工具

发布时间:2026/10/28 6:41:52
agent-skills 技能体系:让 AI coding agents 从玩具变成工具

1. 从“agent-skills”说起:为什么它值得单独拎出来聊

第一次看到agent-skills这个标题,很多人会以为它只是某个仓库里随手放的一堆提示词集合。但真正在 AI coding agents 这条线上折腾过一段时间的人会明白,它其实指向一个更底层的问题:当模型能力越来越强,真正拉开差距的,不再是模型本身,而是你喂给它的“技能包”怎么组织、怎么调用、怎么复用。

agent-skills本质上是一套围绕 AI coding agents 构建的技能体系,通常以目录、清单或 CLI 可识别的方式存在,让 Claude Code、VS Code 里的编码代理、以及各种接入第三方 API 的代理工具,能够按需加载特定能力。它解决的不是“模型会不会写代码”,而是“模型在具体项目里能不能稳定地按你的规矩写代码”。适合谁看?如果你正在用 Claude Code、正在折腾 skills CLI、或者想让 test-driven-development 真正落到代理工作流里,那这篇内容就是写给你的。

我自己的感受是,很多人装完 Claude Code、配好 VS Code 插件、连上第三方 API 之后,就以为万事大吉,结果一跑真实项目就发现:代理要么乱改文件,要么跳过测试,要么把简单需求做成过度设计。问题往往不在模型,而在 skills 层没有搭好。agent-skills这个标题背后,其实是一整套“让代理从玩具变成工具”的工程化思路。

2. agent-skills 的整体设计与思路拆解

2.1 为什么不是“提示词合集”,而是“技能体系”

早期大家用 AI coding agents,习惯把一堆提示词塞进一个 system prompt 里,或者写一个超长的CLAUDE.md。这种做法在单次任务里还能凑合,一旦项目变大、任务变多,就会暴露三个问题:提示词互相冲突、上下文被无关内容占满、代理不知道什么时候该用哪条规则。

agent-skills的设计思路正好相反:它把能力拆成一个个独立技能,每个技能有自己的触发条件、执行步骤和验收标准。代理在运行时根据当前任务动态加载相关技能,而不是一次性把所有规则灌进去。这就像你带团队,不会让一个人同时记住所有 SOP,而是告诉他“遇到数据库迁移就看这份文档,遇到前端组件就看那份”。

这种拆法的好处很直接。第一,上下文利用率高,代理每次只加载当前任务需要的技能,留给代码和推理的空间更大。第二,可维护性强,某个技能过时了,改那一个文件就行,不会牵一发动全身。第三,可组合,test-driven-development 技能可以和代码审查技能叠加使用,形成流水线。

2.2 技能粒度怎么定:太粗没用,太细爆炸

这是我在实际搭建agent-skills时踩得最狠的一个坑。一开始我把技能切得非常细,比如“写单元测试”“运行单元测试”“修复失败测试”各算一个技能,结果代理在任务里频繁切换,反而变得犹豫,经常在一个步骤里反复确认。

后来我调整成按“任务阶段”划分,而不是按“具体动作”划分。一个技能应该对应一个完整的、有明确输入输出的工作单元。比如test-driven-development就是一个合格粒度的技能:它包含先写测试、再写实现、再跑测试、再重构这一整条链路,而不是拆成四个技能。

判断粒度是否合适,我常用一个标准:如果这个技能单独拿出来,能不能对一个真实任务产生可验证的改变?能,就保留;不能,就合并或删掉。太粗的技能会让代理抓不住重点,太细的技能会让它陷入决策疲劳。

2.3 与 Claude Code、skills CLI 的协作关系

agent-skills不是孤立存在的,它需要宿主环境来加载和执行。目前最常见的宿主就是 Claude Code 和各类 skills CLI。Claude Code 本身提供了代理运行框架,包括文件读写、终端命令执行、上下文管理;而agent-skills提供的是“在什么场景下做什么”的领域知识。

skills CLI 的作用则更偏工具链:它负责技能的安装、版本管理、依赖解析和本地缓存。你可以把它理解成 npm 之于 JavaScript 项目的关系。没有 CLI,你也能手动把技能目录拷来拷去,但一旦技能数量上去、多人协作、需要锁定版本,CLI 就是刚需。

这里有个容易被忽略的点:技能和宿主之间的接口要稳定。我见过有人把技能写成强依赖某个 Claude Code 版本的内部 API,结果一升级就全挂。稳妥的做法是让技能只依赖稳定的输入输出约定,比如“读取任务描述、输出文件变更和测试结果”,而不是依赖具体函数名。

3. 核心细节解析与实操要点

3.1 技能目录结构:别小看文件夹命名

一个可维护的agent-skills目录,通常长这样:

agent-skills/ skills/ test-driven-development/ SKILL.md examples/ scripts/ code-review/ SKILL.md refactor-safely/ SKILL.md registry.json README.md

SKILL.md是核心,里面写清楚这个技能的适用场景、前置条件、执行步骤、验收标准和常见错误。examples/放正反例,代理在不确定时可以参考。scripts/放可执行脚本,比如跑测试、格式化代码。registry.json是技能清单,CLI 靠它做索引。

命名上我建议用“动词+对象”或“领域+目标”的形式,比如test-driven-development、refactor-safely。避免用utils、helpers这种模糊词,代理看到这种名字根本不知道什么时候该加载。

注意:技能目录不要嵌套太深。我试过三层以上嵌套,结果 CLI 扫描变慢,代理加载时也容易找错路径。两层足够:skills/<skill-name>/。

3.2 SKILL.md 怎么写才让代理真的照做

很多人写SKILL.md像写博客,大段描述性文字,代理读完还是不知道第一步干什么。有效的写法是结构化指令 + 明确验收。我通常按这个模板:

# Skill: test-driven-development ## When to use - 任务涉及新增功能或修复缺陷 - 项目已有测试框架 ## Steps 1. 阅读任务描述,列出需要覆盖的行为 2. 先写失败测试,运行并确认失败 3. 写最小实现让测试通过 4. 重构,保持测试通过 5. 输出变更文件和测试结果 ## Acceptance - 新增测试至少覆盖任务描述中的每个行为 - 所有测试通过 - 没有跳过或注释掉测试 ## Common mistakes - 先写实现再补测试 - 测试断言过于宽松

关键点是Steps要可执行,Acceptance要可验证。代理最怕模糊指令,比如“写出高质量代码”,它没法判断什么叫高质量。你写“所有测试通过且没有跳过”,它就能判断。

3.3 技能加载策略:按需还是全量

Claude Code 和 skills CLI 通常支持两种加载方式:全量加载和按需加载。全量加载适合技能少、任务类型单一的场景;按需加载适合技能多、任务差异大的项目。

我的经验是,技能超过 8 个就一定要按需加载。否则上下文里塞满无关技能,代理的注意力会被稀释。按需加载的实现方式通常是在任务描述里加标签,或者让代理先做一次技能匹配。比如任务描述里出现“测试”“TDD”,就加载test-driven-development;出现“重构”,就加载refactor-safely。

这里有个实操技巧:给每个技能写一句“触发短语”,放在registry.json里。代理匹配时先看触发短语,再看完整技能内容。这样匹配速度快,准确率也高。

3.4 与第三方 API 和模型接入的配合

现在很多人不只用官方模型,还会通过第三方 API 接入其他模型。这时候agent-skills的写法要更保守一些,因为不同模型对指令的遵循程度不一样。我实测下来,步骤越短、验收越明确,跨模型稳定性越好。

具体做法是:把长步骤拆成编号列表,每步不超过两句话;验收标准用布尔判断,比如“测试通过为真,否则为假”;避免依赖模型自行推断的隐含规则。如果某个技能在某个模型上表现差,不要急着改技能,先看是不是步骤太长或验收太模糊。

提示:接入第三方 API 时,注意技能里不要写死模型名称或 API 细节。技能应该只描述“做什么”,不描述“用哪个模型做”。这样换模型时技能不用改。

4. 实操过程与核心环节实现

4.1 从零搭建一个最小可用 agent-skills

假设你现在有一个项目,想让它支持test-driven-development技能。第一步是建目录:

mkdir -p agent-skills/skills/test-driven-development touch agent-skills/skills/test-driven-development/SKILL.md touch agent-skills/registry.json

然后写registry.json:

{ "skills": [ { "name": "test-driven-development", "path": "skills/test-driven-development", "triggers": ["测试", "TDD", "test", "单元测试"] } ] }

接着写SKILL.md,内容参考上一节的模板。写完用 skills CLI 注册:

skills register ./agent-skills skills list

如果skills list能看到test-driven-development,说明注册成功。然后在 Claude Code 里跑一个简单任务,比如“给这个函数加一个边界条件测试”,观察代理是否按 TDD 步骤执行。

4.2 在 Claude Code 里验证技能是否生效

验证技能生效,不能只看代理说“我用了 TDD”,要看它的实际行为。我通常检查三点:第一,它有没有先写测试再写实现;第二,它有没有运行测试并报告结果;第三,它有没有在测试失败时停下来修,而不是直接改实现。

如果代理跳过测试直接写实现,说明技能触发没生效,或者SKILL.md里的步骤不够强制。这时候可以在Steps里加一句“在写任何实现代码之前,必须先创建并运行失败测试”。语气要明确,不要用“建议”“可以”这种软词。

如果代理写了测试但没运行,检查scripts/里有没有提供测试命令,或者SKILL.md里有没有写清楚运行方式。代理不会自己猜你的测试框架,你得告诉它。

4.3 参数与配置:测试命令、超时、重试

在SKILL.md里,测试命令要写具体。比如:

npm test -- --runInBand

不要只写npm test,因为不同项目配置不一样。超时和重试也要考虑。我一般设置单次测试超时 120 秒,失败重试 1 次。重试太多会掩盖真实问题,重试太少又容易被偶发失败干扰。

如果项目测试很慢,可以给技能加一个“快速测试”和“完整测试”两档。代理在开发过程中跑快速测试,提交前跑完整测试。这样既保证反馈速度,又不牺牲质量。

4.4 技能组合:TDD + 代码审查 + 安全重构

单个技能能解决单点问题,组合起来才能覆盖完整工作流。我常用的组合是:test-driven-development负责新增和修复,code-review负责检查变更,refactor-safely负责在测试保护下重构。

组合方式有两种:一种是在任务描述里同时触发多个技能,代理按顺序执行;另一种是写一个“复合技能”,把多个技能的步骤串起来。前者灵活,后者稳定。我建议先用前者,等流程稳定了再考虑后者。

组合时要注意技能之间的顺序。TDD 必须在重构之前,代码审查必须在测试通过之后。如果顺序错了,代理可能在不稳定的代码上做审查,得出错误结论。

5. 常见问题与排查技巧实录

5.1 技能不触发:先查触发短语,再查加载顺序

技能不触发是最常见的问题。排查顺序是:第一,看registry.json里的触发短语是否覆盖了任务描述里的关键词;第二,看 CLI 是否真的加载了技能;第三,看代理的上下文里有没有技能内容。

我遇到过一种情况:触发短语写的是英文,任务描述是中文,结果匹配不上。后来我把触发短语做成中英双语,问题就解决了。还有一种情况是技能加载顺序不对,后面的技能覆盖了前面的。这时候要检查 CLI 的加载配置,确保没有重复或冲突。

5.2 代理跳过步骤:用验收标准兜底

代理跳过步骤,通常是因为步骤不够强制,或者验收标准太宽松。解决办法是在Acceptance里加硬性条件,比如“必须提供测试运行输出”“必须列出变更文件”。代理为了满足验收,就会补上步骤。

如果加了验收还是跳过,可能是模型能力问题。这时候可以换一个遵循指令更好的模型,或者把步骤拆得更细。我实测下来,步骤从 5 步拆到 8 步,跳过率会明显下降,但也不能无限拆,否则代理会陷入细节。

5.3 测试不稳定:区分偶发失败和真实失败

测试不稳定会严重影响代理判断。代理看到测试失败,可能去改实现,结果改错了。我的做法是:在技能里加一条“如果测试失败,先重跑一次;如果仍然失败,再视为真实失败”。这样能过滤掉大部分偶发失败。

同时,要检查测试本身是否有共享状态、时间依赖、网络依赖。这些是偶发失败的常见来源。如果测试确实不稳定,先修测试,再让代理用 TDD。否则代理会在不稳定的基础上做决策,越做越乱。

5.4 常见问题速查表

问题可能原因排查方法解决方式
技能不触发触发短语不匹配检查 registry.json补充中英双语触发词
代理跳过测试步骤不强制查看 SKILL.md加硬性验收条件
测试偶发失败共享状态/时间依赖重跑测试先修测试再启用技能
技能冲突加载顺序错误查看 CLI 日志调整加载顺序或合并技能
跨模型表现差步骤太长对比不同模型拆短步骤,明确验收

5.5 我踩过的三个坑

第一个坑是技能写得太抽象。早期我写“写出优雅的代码”,代理完全不知道怎么做。后来改成“函数不超过 30 行,参数不超过 4 个”,代理立刻能执行。抽象指令对代理无效,具体约束才有效。

第二个坑是忽略技能版本管理。有一次我改了一个技能,结果另一个项目也在用,行为变了导致测试失败。后来我给技能加版本号,项目锁定版本,问题才解决。

第三个坑是过度依赖技能。有段时间我把所有规则都塞进技能,结果代理变得死板,遇到技能没覆盖的情况就卡住。后来我保留了一部分“自由发挥”空间,让代理在技能之外也能做合理判断。技能是护栏,不是牢笼。

6. 技能体系的扩展与长期维护

6.1 从个人技能到团队技能库

个人用agent-skills,怎么舒服怎么来。一旦团队用,就要考虑标准化。我们团队的做法是:技能库放在独立仓库,走代码审查流程;每个技能必须有负责人;技能变更要通知使用方。

团队技能库还要解决“技能发现”问题。新人不知道有哪些技能可用,所以我们写了一个索引页,按任务类型分类,比如“测试相关”“重构相关”“部署相关”。每个技能一句话说明用途,点进去看详情。

6.2 技能质量评估:用数据说话

技能好不好,不能靠感觉。我们统计了几个指标:技能触发率、任务完成率、代理跳过步骤的比例、测试通过率。触发率低说明触发短语有问题,完成率低说明步骤或验收有问题,跳过率高说明约束不够。

这些数据不需要很复杂,手动记录几十次任务就能看出趋势。我建议每两周回顾一次,把表现差的技能挑出来优化或下线。技能库不是越多越好,而是越精越好。

6.3 与 test-driven-development 的深度绑定

test-driven-development是我所有技能里用得最频繁的一个,也是收益最明显的。它让代理从“写完再说”变成“先想清楚再写”。但 TDD 技能要生效,前提是项目有可运行的测试框架,而且测试速度不能太慢。

如果项目没有测试,我建议先补最小测试集,再启用 TDD 技能。否则代理会陷入“想写测试但没框架”的尴尬。补测试不需要覆盖所有代码,先覆盖核心路径就行。有了基础,TDD 技能才能跑起来。

6.4 后续扩展方向

agent-skills的扩展空间很大。往深了做,可以加“技能依赖管理”,让技能之间声明依赖关系,CLI 自动解析。往宽了做,可以加“技能市场”,团队之间共享技能。往细了做,可以给每个技能加“适用模型”标签,不同模型加载不同技能。

我目前在做的是“技能效果回放”:把代理执行技能的过程录下来,事后分析哪一步卡住、哪一步跳过。这个对优化技能很有帮助,但实现成本不低。如果你刚开始,先把基础技能跑通,再考虑这些高级功能。

提示:技能库要定期清理。我每季度会下线一批使用率低的技能,避免维护负担。技能不是资产,是工具,不用了就删。

7. 一些实操心得与建议

如果你刚开始接触agent-skills,我的建议是从一个小技能开始,不要一上来就搭大框架。先写一个test-driven-development,在真实任务里跑通,感受代理的行为变化。跑通之后再考虑加第二个、第三个技能。

技能写完后,一定要在真实项目里验证,不要只在玩具项目里试。真实项目有历史代码、有依赖、有边界条件,这些才是检验技能的地方。玩具项目里表现好,不代表真实项目里能用。

另外,不要迷信技能数量。我见过有人收集了几百个技能,结果代理加载慢、冲突多、效果差。十个精心维护的技能,比一百个随便写的技能有用得多。技能的价值在于被使用,不在于被收藏。

最后分享一个我常用的小技巧:给每个技能写一句“失败模式”,放在SKILL.md末尾。比如“如果代理在测试失败时直接改实现,说明 TDD 技能未生效”。这样排查问题时,一眼就能定位。这个习惯帮我省了很多时间,也让我对技能的理解越来越深。