1. 从"agent-skills"这个标题能读出什么
第一次看到agent-skills这个仓库名,我的直觉是:这大概率不是一个应用,而是一套"能力包"。事实也确实如此——它本质上是一个围绕 AI coding agent 构建的技能集合,核心是把"怎么让 AI 编程助手真正按你的意图干活"这件事,从玄学变成可复用的工程实践。
很多人用 AI 编程工具的方式还停留在"打开对话框,把需求丢进去,然后祈祷它别乱改"。这种用法在简单脚本上勉强能用,一旦项目上了规模、有了测试、有了代码规范,AI 就会开始自由发挥:改坏无关文件、跳过测试、写出风格完全不一致的代码。agent-skills想解决的正是这个问题——它把"如何约束和引导 AI agent"沉淀成一套结构化的技能定义,让 agent 在明确的规则下工作。
这篇文章适合三类人看:一是已经在用 Claude Code 这类终端 AI 编程工具、但总觉得"它不太听话"的开发者;二是想给自己的团队建立 AI 编码规范、却不知道从哪下手的技术负责人;三是纯粹好奇"skills CLI 到底是个什么东西"的探索者。我会从这套技能包的设计逻辑讲起,一路拆到怎么落地、怎么避坑,尽量把每个"为什么"都说清楚。
需要先说明一点:agent-skills本身是一个偏"方法论 + 工具链"的项目,它不绑定某一个具体模型,而是通过 skills CLI 这套机制,把技能定义注入到 agent 的工作流里。理解这一点,后面的内容才不会跑偏。
2. skills CLI 到底在解决什么核心问题
2.1 裸用 AI agent 的三个典型翻车场景
在讲 skills CLI 之前,得先讲清楚它要治的病。我自己踩过的坑,基本可以归成三类。
第一类是上下文漂移。你让 agent 改一个函数,它改着改着顺手把旁边的工具函数也"优化"了,理由是"这样更优雅"。结果你 review 的时候发现,它动的那块代码是另一个同事特意写成那样的,背后有历史原因。AI 不知道这些,它只看到"这段代码可以更好"。
第二类是流程缺失。你希望它先写测试再写实现,但它上来就改实现,测试最后补一个"能过就行"的。test-driven-development 这套东西,靠嘴说没用,得靠机制强制。
第三类是知识不落地。团队里有一套代码规范、一套提交信息格式、一套目录约定,但每次开新会话,agent 都是白纸一张,你得重新交代一遍。交代得不全,它就按自己的理解来。
这三个问题的共同点是:它们都不是模型能力问题,而是工作流问题。模型足够聪明,但它不知道你的规矩。skills CLI 的价值,就是把这些"规矩"变成 agent 能读取、能执行的结构化定义。
2.2 技能(skill)的本质是一份可执行的约定
很多人第一次接触 skill 这个概念会懵:它和 prompt 有什么区别?我的理解是,prompt 是"这一次你要做什么",skill 是"你以后遇到这类事都该怎么做"。
一份 skill 通常包含几个部分:触发条件(什么时候用这个技能)、操作步骤(具体怎么做)、约束条件(不能做什么)、验证方式(怎么确认做对了)。它更像是一份 SOP(标准作业程序),而不是一句指令。
举个例子,一个"写测试"的 skill 可能会这样定义:当用户要求新增功能时,先分析需求边界,列出测试用例清单,写失败测试,再写实现让测试通过,最后重构。整个过程有明确的顺序,agent 不能跳步。这就是为什么它能和 test-driven-development 天然契合——TDD 本身就是一套强顺序的流程,正好适合用 skill 固化下来。
2.3 skills CLI 的定位:技能的分发与管理层
skills CLI 是这套体系里的"包管理器"角色。你可以把它理解成 npm 之于 JavaScript、pip 之于 Python——它负责把技能定义安装到你的工作环境里,让 agent 在运行时能加载到。
它要处理的问题包括:技能从哪来(本地文件还是远程仓库)、装到哪去(agent 的配置目录)、怎么生效(agent 启动时如何加载)、怎么更新(技能迭代后如何同步)。这些看起来是琐碎的工程问题,但恰恰是"让 AI 听话"能否规模化的关键。
提示:不要把 skills CLI 当成一个必须用的工具。它的价值在于当你有多套技能、多个项目、多个团队成员时,手动管理会失控。如果只是个人玩一玩,直接放几个技能文件也能跑。
3. 技能包的设计哲学:为什么是"技能"而不是"配置"
3.1 配置是死的,技能是活的
传统的做法是写一个配置文件,比如.ai-rules或者CLAUDE.md,把规范一股脑塞进去。这种做法的问题在于:它是静态的、扁平的、无条件的。不管你在做什么任务,agent 读到的都是同一坨规则。
技能不一样。技能是按需加载的。当你在做数据库迁移时,加载的是迁移相关的技能;当你在写前端组件时,加载的是组件规范技能。这种"上下文相关"的特性,让 agent 在每一步都能拿到最相关的指引,而不是被无关规则干扰。
这背后的逻辑其实很朴素:人的注意力有限,模型的上下文窗口也有限。把最相关的东西放在最前面,效果永远好过把所有东西都堆上去。
3.2 技能的可组合性
agent-skills这套设计里,我特别喜欢的一点是技能可以组合。一个"代码审查"技能可以调用"安全检查"技能和"风格检查"技能,形成一个审查流水线。这种组合能力让技能从"单点规则"升级成"工作流编排"。
组合带来的直接好处是复用。你不需要在每个技能里重复写"检查是否有硬编码密钥",只需要在需要的地方引用安全检查技能。这和软件工程里的函数复用是一个道理,只不过复用的对象从代码变成了"行为规范"。
3.3 为什么强调 test-driven-development
在关键词里,test-driven-development 被单独拎出来,这不是偶然。TDD 是 AI 编程里最能体现"技能价值"的场景之一。
原因在于:AI 写代码太快了,快到人类来不及验证。如果没有测试作为锚点,你根本不知道它改的东西对不对。而 TDD 强制"先写测试",等于给 AI 的每一步都设了一个可验证的目标。测试通过,说明这一步做对了;测试失败,说明还得改。
把 TDD 做成技能,意味着 agent 每次接到任务,都会自动走"分析需求 → 写测试 → 写实现 → 重构"这个流程。它不会偷懒跳过测试,因为技能定义里写死了这个顺序。这就是机制的力量——不依赖模型的自觉,而依赖流程的约束。
4. 把 agent-skills 跑起来:环境准备与安装路径
4.1 先确认你的 agent 环境
在装 skills CLI 之前,得先有一个能跑 skill 的 agent 环境。目前主流的选择是 Claude Code 这类终端 AI 编程工具。它的特点是直接在命令行里工作,能读写文件、执行命令、跑测试,这正是 skill 能发挥作用的前提。
如果你还没装 Claude Code,大致流程是先确认 Node.js 环境(建议 18 以上),然后通过官方渠道获取安装方式。安装完成后,在项目目录里运行一次,确认它能正常读取文件、执行命令。这一步别跳过,因为后面 skills CLI 装的东西,最终是要被这个 agent 加载的。
注意:不同平台的安装细节差异不小。Mac 和 Ubuntu 下的路径、权限处理方式不一样,Windows 下建议用 WSL。装完之后一定要验证 agent 能正常执行终端命令,否则 skill 里的"跑测试"这类步骤会直接失败。
4.2 skills CLI 的安装与初始化
skills CLI 的安装通常走包管理器。假设它是通过 npm 分发的,流程大致是全局安装,然后在项目里初始化。
# 全局安装 skills CLI(示意,具体包名以官方为准) npm install -g skills-cli # 在项目根目录初始化技能配置 skills init初始化会生成一个技能配置目录,通常叫.skills或者类似的名字。这个目录就是技能的家。里面会有默认的技能定义文件,以及一个清单文件,记录当前启用了哪些技能。
初始化完成后,建议先跑一次skills list看看默认装了哪些技能。这一步能帮你建立"技能清单"的概念——你随时知道 agent 现在被哪些规则约束着。
4.3 技能目录的结构长什么样
一个典型的技能目录结构大致是这样:
.skills/ ├── manifest.json # 技能清单,记录启用状态 ├── tdd/ # 测试驱动开发技能 │ ├── skill.md # 技能定义 │ └── examples/ # 示例 ├── code-review/ # 代码审查技能 │ └── skill.md └── security/ # 安全检查技能 └── skill.md每个技能一个文件夹,里面至少有一个定义文件。定义文件用 Markdown 写,因为 Markdown 对模型友好,结构清晰,还能塞代码示例。
manifest.json 是关键,它决定了哪些技能会被加载。你可以按项目启用不同组合——后端项目启用 API 设计技能,前端项目启用组件规范技能。
4.4 验证技能是否生效
装完之后怎么确认技能真的起作用了?我的做法是做一个"反向测试":故意让 agent 做一个违反技能规则的操作,看它会不会拒绝或者提醒。
比如你装了 TDD 技能,就让它"直接实现一个函数,不用写测试"。如果技能生效,它应该会提醒你"按照 TDD 流程,我需要先写测试"。如果它二话不说直接写了实现,说明技能没加载成功。
这个验证步骤很多人会跳过,结果用了半天发现技能根本没生效,白折腾。花五分钟验证,能省几小时排查。
5. 自己写一个技能:从需求到可执行定义
5.1 先想清楚"这个技能要约束什么行为"
写技能的第一步不是打开编辑器,而是想清楚:我要约束的是什么行为?这个行为现在出了什么问题?理想状态是什么样?
拿"提交信息规范"举例。问题是:agent 提交代码时,commit message 写得随心所欲,有的用中文有的用英文,有的写"fix bug"有的写"修复了一个问题"。理想状态是:统一格式,包含类型、范围、描述。
想清楚这个,技能定义就有了骨架:触发条件是"当 agent 准备提交代码时",操作步骤是"按约定格式生成 message",约束是"不允许空泛描述",验证方式是"检查 message 是否符合正则"。
5.2 技能定义文件的写法
技能定义用 Markdown 写,结构上建议包含这几块:
# 技能名称:提交信息规范 ## 触发条件 当 agent 执行 git commit 操作时自动应用。 ## 操作步骤 1. 分析本次改动的类型(feat/fix/refactor/docs/test/chore) 2. 确定影响范围(模块名) 3. 用一句话描述改动,不超过 50 字 4. 按 `type(scope): description` 格式生成 message ## 约束条件 - 描述必须具体,禁止使用"优化""调整"等空泛词 - 一次提交只做一件事,混合改动需拆分 ## 验证方式 生成的 message 需匹配正则:`^(feat|fix|refactor|docs|test|chore)\(.+\): .+$`这个结构的好处是:模型读起来没有歧义。触发条件告诉它"什么时候用",操作步骤告诉它"怎么做",约束条件告诉它"红线在哪",验证方式告诉它"怎么自查"。
5.3 把技能写"窄"而不是写"宽"
新手写技能最容易犯的错是贪大求全。一个技能里塞进十条规则,覆盖五个场景,结果模型记不住,执行时顾此失彼。
我的经验是:一个技能只解决一类问题。提交信息规范就只管提交信息,别顺手把代码风格也塞进去。代码风格单独开一个技能。这样每个技能都短小精悍,模型执行起来准确率高。
技能多了之后,用 manifest 组合。比如"提交前检查"这个场景,可以组合"提交信息规范"+"代码风格检查"+"测试通过检查"三个技能。组合是 manifest 层的事,不是单个技能的事。
5.4 给技能配示例,比写规则更有效
模型对示例的敏感度远高于对抽象规则的敏感度。与其写"描述要具体",不如直接给两个正反例:
好的例子:feat(auth): 增加手机号登录接口 坏的例子:fix: 修复了一些问题示例能让模型快速对齐你的预期。我写技能时,示例部分往往比规则部分还长,但效果确实好。
6. 技能与 TDD 的化学反应:让 AI 不敢跳过测试
6.1 为什么 AI 天然想跳过测试
从模型的角度看,写测试是"额外工作"。它的目标是"完成任务",而任务描述里通常只说"实现某功能",没说"先写测试"。所以它会选择最短路径:直接写实现。
这不是模型偷懒,而是它缺少流程约束。TDD 技能的作用,就是把"先写测试"变成任务定义的一部分,让模型认为"不写测试就不算完成任务"。
6.2 TDD 技能的具体流程设计
一个可落地的 TDD 技能,流程应该包含这几步:
- 需求拆解:把用户需求拆成可测试的行为点。比如"用户能登录"拆成"正确密码能登录""错误密码报错""空密码报错"。
- 写失败测试:为每个行为点写测试,此时测试必然失败,因为实现还不存在。
- 写最小实现:只写让测试通过的最少代码,不多写。
- 重构:测试通过后,优化代码结构,保持测试绿色。
- 循环:回到第一步,处理下一个行为点。
这个流程的关键是"最小实现"和"重构"两步。很多 AI 会跳过重构,直接进入下一个功能,导致代码越写越乱。技能定义里要明确要求它停下来重构。
6.3 怎么验证 TDD 技能真的在起作用
验证方法很直接:看 git 历史。如果 TDD 技能生效,提交历史里应该能看到"测试文件先于实现文件出现"的模式。或者更简单,在 agent 工作时观察它的输出——它应该先创建测试文件,运行测试看到失败,然后才写实现。
如果它一上来就写实现,说明技能没生效,或者技能定义里的流程不够强制。这时候要回去检查技能定义,把"必须先写测试"这条约束写得更硬。
6.4 一个容易忽略的细节:测试的粒度
TDD 技能里要明确测试粒度。太粗的测试(比如"整个系统能跑")没有指导意义,太细的测试(比如"这个 getter 返回正确值")又浪费时间。
我的建议是:按行为测试,不按方法测试。测试"用户用正确密码能登录",而不是测试"validatePassword 方法返回 true"。前者是行为,后者是实现细节。行为测试更稳定,实现改了测试不用改。
这个原则要写进技能定义里,否则 AI 会按方法粒度写测试,导致测试和实现耦合太紧,重构时一改就红。
7. 多模型接入下的技能适配问题
7.1 技能定义要不要针对模型定制
现在很多人会在不同模型之间切换,比如用 Claude 做主力,偶尔切到其他模型做对比。这就带来一个问题:同一套技能定义,在不同模型上效果一样吗?
答案是:不完全一样。不同模型对指令的遵循程度、对 Markdown 结构的敏感度、对示例的依赖程度都有差异。一个在 Claude 上跑得很好的技能,换到另一个模型上可能就"理解偏了"。
但这不意味着你要为每个模型写一套技能。更实际的做法是:技能定义保持模型无关,把模型特定的适配放在配置层。比如某些模型需要更明确的步骤编号,你可以在加载时做一层转换。
7.2 切换模型时最容易丢的是什么
切换模型时,最容易丢的是"隐式约定"。Claude 可能从你的技能定义里读出了"要先写测试"这层意思,但另一个模型可能只读到了字面意思。这时候技能定义里的"显式程度"就很重要。
我的经验是:技能定义要写得足够显式,显式到"傻瓜都能执行"的程度。不要依赖模型的推理能力去补全你的意图。每一步都写清楚,每个约束都写明白。这样不管换哪个模型,执行结果都不会差太多。
7.3 用技能做模型对比的基准
反过来想,技能还能当模型对比的"标尺"。同一套技能定义,让不同模型执行同一个任务,看谁执行得更准确、更少偏离。这比单纯比"谁生成的代码好看"要有意义得多,因为它测的是"谁更能按规矩办事"。
我做过一次小对比:同一个 TDD 技能,让两个模型实现同一个功能。一个严格走了"测试先行"流程,另一个直接写实现然后补测试。这个差异在技能约束下暴露得很明显,比看代码质量更直观。
8. 实战踩坑:技能不生效的排查链路
8.1 第一步:确认技能文件被加载了
技能不生效,先别怀疑技能写得不好,先确认它有没有被加载。检查 manifest.json 里这个技能是不是 enabled 状态,检查技能目录路径对不对,检查 agent 启动时有没有报加载错误。
我遇到过一次,技能文件写得好好的,但 manifest 里路径写错了一个字母,agent 静默跳过了。这种问题不报错,最难查。
8.2 第二步:确认技能触发了
技能加载了,不代表触发了。触发条件写得太窄,可能永远不触发;写得太宽,可能在不该触发的时候触发。
排查方法是:在技能定义里临时加一条日志输出,看 agent 执行到相关操作时有没有打印。如果没有,说明触发条件没匹配上,回去改触发条件。
8.3 第三步:确认技能被遵循了
触发了,但 agent 没按技能说的做。这种情况通常是技能定义有歧义,或者约束不够硬。
排查方法是:把技能定义读一遍,问自己"如果我是模型,我会怎么理解这句话"。如果存在多种理解,就改写得唯一。如果约束是"建议"语气,就改成"必须"语气。
8.4 第四步:确认没有技能冲突
多个技能同时生效时,可能互相冲突。比如一个技能说"提交前必须跑测试",另一个技能说"提交要快,别跑测试"。这种冲突会让 agent 无所适从。
排查方法是:把技能一个个禁用,看问题是否消失。找到冲突的两个技能后,要么合并,要么明确优先级。
8.5 一个真实的排查案例
我有一次装了"代码审查"技能,但 agent 审查时总是漏掉安全检查。查了半天发现,安全检查是单独一个技能,但 manifest 里没启用。启用之后,审查技能里引用的安全检查才真正生效。
这个坑的教训是:技能之间的引用关系要显式声明。不要假设"装了 A 技能,A 引用的 B 技能就自动生效"。manifest 里该启用的都要启用。
9. 把技能纳入团队工作流
9.1 技能应该进版本控制
技能定义是团队资产,应该和代码一起进 git。这样每个人拉下代码,技能就是一致的。新人入职,不用口头交代规范,技能文件就是规范。
建议把.skills目录放在项目根目录,和.gitignore、README.md平级。技能变更走 code review,和代码变更一样对待。
9.2 技能的所有权和维护
技能不能没人管。建议指定一个"技能维护者"角色,负责审核技能变更、解决技能冲突、定期清理过时技能。
技能过时是个大问题。项目重构了,原来的技能可能不再适用,但没人删,就会一直误导 agent。定期 review 技能清单,该删的删,该改的改。
9.3 用技能做新人 onboarding
新人入职最头疼的是"不知道团队的规矩"。技能文件恰好就是规矩的集合。让新人读一遍技能目录,比读一堆文档快得多,而且更准确——因为技能是 agent 实际执行的规则,不是写在文档里没人看的摆设。
我甚至建议把技能文件作为 onboarding 材料的一部分,让新人第一周就熟悉这些规则。
9.4 技能与 CI 的配合
技能约束的是 agent 的行为,但 agent 可能绕过技能。比如它可能不跑测试就提交。这时候 CI 就是最后一道防线。
理想的状态是:技能让 agent 在本地就做对,CI 做兜底检查。两者配合,既不浪费 CI 资源,又不放过漏网之鱼。
10. 一些关于技能设计的个人体会
写了这么多技能之后,我最大的体会是:技能设计是门"约束的艺术"。约束太松,agent 自由发挥,结果不可控;约束太紧,agent 寸步难行,效率还不如自己写。
找到那个平衡点,靠的是迭代。第一版技能往往不是太松就是太紧,用一段时间,看哪里出问题,再调。调个三五轮,基本就顺了。
另一个体会是:技能要写给人看,不只是写给模型看。一份好的技能定义,人读了也知道该怎么做。这样技能就不只是"约束 AI 的工具",还是"团队知识的载体"。新人读技能,老人改技能,技能在团队里流动起来,价值就放大了。
最后一个反直觉的点:不是所有事都值得做成技能。有些一次性任务,直接对话解决就行,做成技能反而增加维护负担。判断标准是:这件事会不会重复发生?重复发生的事才值得固化。一次性的,放过它。
这套东西说到底,核心就一句话:把"你希望 AI 怎么做"从脑子里、从口头交代里,搬到可执行、可版本化、可复用的文件里。搬完之后,你会发现 AI 编程从"碰运气"变成了"可预期"。这个转变,值得花时间折腾。