1. 从"agent-skills"这个标题能读出什么
第一次看到agent-skills这个仓库名,我的直觉是:这不是又一个"提示词合集",而是一套给 AI coding agent 用的能力包。它要解决的问题很具体——当你把 Claude Code 这类命令行 AI 编程助手接进项目之后,会发现它默认只会"聊天式改代码",缺少一套可复用、可版本管理、可被 agent 自动加载的工程化技能。agent-skills干的就是把"怎么让 agent 按测试驱动开发(TDD)的节奏干活""怎么让 agent 遵守项目规范""怎么让 agent 自己跑测试再改代码"这些经验,沉淀成结构化的 skill 文件,让 agent 在需要的时候自动读取并执行。
关键词里出现的skills CLI、test-driven-development、AI coding agents、Claude Code基本勾勒出了它的全貌:这是一个围绕 AI 编程代理的技能编排层。它不训练模型,也不改模型权重,而是通过一套约定好的目录结构和元数据,把"人类工程师的最佳实践"翻译成 agent 能理解的指令集。你可以把它理解成给 agent 装的"插件系统"——只不过插件的内容不是代码,而是工作流。
适合谁看?三类人最该关注。第一类是把 Claude Code 当日常主力工具、但总觉得它"不够听话"的开发者;第二类是团队里想把 AI 编码规范统一起来的 tech lead;第三类是想自己写 skill、扩展 agent 能力边界的折腾党。如果你只是偶尔用 AI 补全几行代码,这篇可能有点重;但只要你开始让 agent 独立完成一个 feature、跑一轮测试、提交一次 PR,agent-skills这套思路就值得认真拆一遍。
下面我会从它的核心机制、目录结构、TDD skill 的落地方式、CLI 的用法、以及我自己踩过的坑几个角度,把这块东西讲透。
2. agent-skills 到底解决了什么痛点
2.1 裸用 Claude Code 的三个典型翻车现场
先说清楚没有 skills 的时候会发生什么,你才能理解这套东西的价值。
翻车一:agent 改完代码不跑测试。你让它实现一个函数,它噼里啪啦写完,然后说"完成"。你一看,边界条件没处理,导入路径写错,测试根本跑不过。它不会主动去跑pytest或npm test,因为默认行为里没有"验证"这一步。
翻车二:每次都要重复交代规范。你的项目用 4 空格缩进、用ruff做 lint、commit message 遵循 conventional commits。这些你每次开新会话都得重新说一遍,说漏一条它就自由发挥。上下文一长,它还会忘。
翻车三:agent 不知道"什么时候该做什么"。面对"加一个用户登录接口"这种任务,人类工程师知道要先写测试、再写实现、再重构。agent 不知道,它会直接冲去写实现,测试留到最后甚至不写。
agent-skills的核心洞察就是:这些不是模型能力问题,是流程编排问题。模型足够聪明,缺的是"在正确的时机被喂正确的指令"。skill 就是那个"时机触发器"。
2.2 skill 和 prompt、和 CLAUDE.md 的区别
很多人第一反应是:"这不就是写个 prompt 吗?我放 CLAUDE.md 里不就行了?"
区别在于加载时机和粒度。CLAUDE.md 是全局常驻的,每次会话都塞进上下文,写多了会稀释注意力,而且它是"静态规则",不区分场景。skill 是按需加载的:agent 判断当前任务需要"测试驱动开发"这个技能时,才去读对应的 skill 文件,读完执行完就释放。
打个比方:CLAUDE.md 像是贴在工位上的员工手册,天天看;skill 像是抽屉里的操作手册,做特定工序时才翻出来。前者适合放"永远成立"的约束(比如"禁止提交密钥"),后者适合放"特定任务才用"的流程(比如"如何写一个符合 TDD 的 feature")。
这个区分非常关键,因为它直接决定了你的上下文预算怎么花。上下文是稀缺资源,常驻内容越少,agent 在关键时刻的"脑容量"越充足。
2.3 一个 skill 的最小构成
一个标准的 skill 通常包含三部分:
- 元数据(frontmatter):name、description、触发条件。agent 靠 description 判断"这个 skill 跟当前任务相不相关"。
- 指令正文:具体的工作流步骤,用自然语言写,但要求足够具体、可执行。
- 辅助资源:可选的脚本、模板、参考文件,skill 正文里可以引用它们。
元数据里的 description 是最容易被写砸的地方。写得太泛("帮助写代码"),agent 永远匹配不上;写得太窄("当用户要求用 pytest 写一个带 mock 的异步测试时使用"),又几乎触发不了。好的 description 是"任务类型 + 关键动作"的组合,比如"实现新功能时,按测试先行的顺序推进"。
3. 目录结构与 skill 的加载逻辑
3.1 典型目录长什么样
虽然agent-skills的具体文件我没法逐行给你,但这类项目的目录约定高度一致,我按通用实践给你还原一个可用的结构:
agent-skills/ ├── skills/ │ ├── test-driven-development/ │ │ ├── SKILL.md │ │ └── references/ │ │ └── tdd-checklist.md │ ├── code-review/ │ │ └── SKILL.md │ └── commit-convention/ │ └── SKILL.md ├── cli/ │ └── index.js └── README.md每个 skill 一个目录,目录名就是 skill 的标识。核心文件是SKILL.md,里面用 YAML frontmatter 声明元数据,正文写指令。references/放那些"正文太长、按需引用"的补充材料。
提示:目录名和 frontmatter 里的 name 保持一致,能省掉很多调试时的困惑。我见过有人目录叫
tdd、name 写test-driven-development,结果 CLI 按目录名索引、agent 按 name 匹配,两边对不上,skill 死活不触发。
3.2 agent 是怎么"发现"skill 的
加载逻辑分两步。第一步是索引:agent 启动时扫描 skills 目录,只读每个 SKILL.md 的 frontmatter,把 name 和 description 装进一个轻量清单。这一步不读正文,所以开销很小。第二步是匹配与加载:当 agent 接到任务,它拿任务描述去跟清单里的 description 做语义匹配,命中哪个就把哪个的正文读进上下文。
这个设计的好处是可扩展性。你装 50 个 skill,启动时也只加载 50 条 description,不会撑爆上下文。真正占空间的正文只在需要时进来。
但这也带来一个坑:description 的质量直接决定 skill 的命中率。我建议你写完 description 后,拿几个真实任务描述去"人肉匹配"一遍,看看能不能对上。对不上就改,别指望 agent 比你聪明。
3.3 优先级与冲突处理
多个 skill 同时命中怎么办?常见做法是给 skill 加priority字段,或者靠 description 的 specificity 排序。更稳妥的做法是让 skill 之间职责不重叠。比如"写测试"和"TDD 流程"这两个 skill 就容易打架——前者只管写测试,后者管整个"测试-实现-重构"循环。我的经验是:把细粒度的 skill 作为粗粒度 skill 的子步骤引用,而不是让它们平级竞争。
4. TDD skill:把工程纪律塞进 agent 的脑子里
4.1 为什么 TDD 是 agent 最该学的第一课
在所有 skill 里,test-driven-development是最值得先做的,原因很实在:TDD 天然适合 agent。
人类做 TDD 的痛苦在于"忍住不先写实现"很反人性,但 agent 没有这个心理负担,它只是执行指令。而且 TDD 的循环(红-绿-重构)是高度结构化的,正好是 agent 擅长的"按步骤执行"。更妙的是,测试本身就是可验证的反馈信号——agent 写完测试跑一遍,红了;写实现再跑,绿了。这个反馈闭环让 agent 能自我纠错,而不是写完就拍屁股走人。
4.2 一个可落地的 TDD skill 正文该怎么写
指令正文最忌讳写成"你要遵循 TDD 原则"这种空话。agent 需要的是可执行的动作序列。我推荐按这个骨架写:
- 先确认测试框架和运行命令。让 agent 读 package.json / pyproject.toml,找到测试命令,别猜。
- 写一个失败的测试。明确要求:只写一个测试用例,覆盖当前要实现的最小行为。
- 运行测试,确认它失败。这一步不能省。如果测试直接通过,说明要么测试写错了,要么功能已存在,都要停下来报告。
- 写最小实现让测试通过。强调"最小",禁止顺手实现其他功能。
- 再跑测试,确认变绿。
- 重构。在测试保护下清理代码,重构后必须再跑一次测试。
- 循环。回到第 2 步,处理下一个行为。
每一步都要写清楚"运行什么命令""看到什么结果才算通过""不通过怎么办"。比如第 3 步可以写:"运行测试命令。如果测试通过而非失败,停止当前循环,向用户报告:测试未按预期失败,可能功能已实现或测试断言有误。"
4.3 让 agent 真的去跑命令,而不是假装跑
这是 TDD skill 能不能生效的生死线。很多 agent 会"脑补"测试结果——它写完测试,不去执行,直接说"测试通过"。你必须用强指令堵死这条路。
有效的写法是明确要求 agent展示命令输出。比如:"每次运行测试后,把完整的命令和输出粘贴到回复里。没有真实输出的'测试通过'一律视为未完成。" 这句话看着啰嗦,但实测能显著降低 agent 偷懒的概率。
另外,如果你的 agent 环境支持工具调用(比如 Claude Code 的 Bash 工具),要在 skill 里明确"使用终端工具执行测试命令",而不是让它在脑子里模拟。工具调用是硬约束,脑补是软约束,能上硬的就别用软的。
4.4 测试粒度:agent 最容易失控的地方
agent 写测试有个通病:一次写一大堆。你让它实现一个计算器,它一口气写 20 个测试用例,然后开始逐个实现,循环节奏全乱了。
skill 里必须限制粒度。我的做法是加一条硬规则:"每个循环只允许新增一个测试用例。新增第二个测试前,必须确认前一个已经变绿。" 这条规则把 agent 拉回小步快跑的节奏,也让每次失败的范围可控——出问题时你知道是哪个行为没实现,而不是面对一片红。
5. skills CLI:安装、管理与调试
5.1 CLI 存在的意义
有人会问:skill 不就是几个 markdown 文件吗,我手动拷进项目不就行了,要 CLI 干嘛?
CLI 解决的是分发和版本管理。手动拷贝的问题在于:skill 更新了你怎么同步?多个项目怎么共享?团队里怎么保证大家用的是同一版?CLI 把这些变成一条命令的事。典型用法是skills install <name>把某个 skill 装进当前项目的 skills 目录,skills list看装了哪些,skills update拉最新版。
5.2 安装与初始化
按通用实践,流程大概是这样:
# 全局安装 CLI npm install -g agent-skills-cli # 在项目里初始化 skills 目录 skills init # 安装 TDD skill skills install test-driven-development # 查看已安装 skills listskills init通常会创建skills/目录并生成一个配置文件,记录 skill 的来源和版本。这个配置文件要提交到 git,这样团队成员 clone 之后跑一次skills sync就能对齐。
注意:CLI 的包名和命令名在不同项目里可能不一样,装之前先看 README 的 Quick Start,别照着记忆里的命令硬敲。我踩过一次,把
skills敲成了另一个同名工具,装了一堆不相干的东西。
5.3 调试 skill 不生效的问题
skill 装了但 agent 不用,是最常见的求助。排查顺序我总结成一张表:
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| agent 完全不提 skill | description 匹配不上 | 拿任务描述手动比对 description |
| agent 提了但没执行 | 正文指令太抽象 | 检查是否有可执行命令和验证步骤 |
| 执行了但中途跑偏 | 缺少边界约束 | 补充"禁止做什么"的负面指令 |
| 时灵时不灵 | 上下文被挤占 | 精简 CLAUDE.md,给 skill 留空间 |
我遇到最多的是第一类。description 写得太"文学",比如"帮助开发者写出优雅的代码",agent 根本不知道什么时候该用。改成"实现新功能时,按测试先行的顺序推进,每个循环只加一个测试"之后,命中率立刻上来了。
5.4 多 skill 协同的编排思路
当你有 TDD、code-review、commit-convention 三个 skill 时,理想状态是它们能串成一条流水线:TDD 负责实现,code-review 负责检查,commit-convention 负责提交。但 agent 不会自动串,你得在 skill 里写"交接指令"。
比如 TDD skill 的最后一步可以写:"所有测试通过后,提示用户或自动触发 code-review skill 进行代码审查。" 这样 skill 之间就有了调用关系。不过要注意别搞成无限套娃,交接链超过三层,agent 就容易迷失。
6. 我踩过的坑和几条实操心得
6.1 坑一:skill 写成了"教科书"
我第一版 TDD skill 写了满满一页 TDD 的历史、原则、好处,结果 agent 读完该干嘛还是干嘛。后来我把它砍到只剩动作步骤,效果立竿见影。skill 是操作手册,不是科普文章。每一句话都要能对应到一个动作或一个判断,否则就是噪音。
6.2 坑二:忽略了"失败路径"
新手写 skill 只写"顺利情况":写测试、跑测试、写实现、跑测试、通过。但真实开发里,测试跑不起来(环境问题)、测试一直红(实现有 bug)、测试意外绿了(断言写错)都是常态。skill 里必须为这些分支写清楚"停下来报告什么"。agent 遇到没写过的分支,默认行为往往是"硬着头皮往下走",结果越走越偏。
6.3 坑三:把 skill 当成了万能药
skill 能规范流程,但不能提升模型本身的代码能力。如果模型写不出正确的实现,再好的 TDD skill 也只是让它更快地写出错误的代码。skill 的定位是"放大已有的能力",不是"补足缺失的能力"。想清楚这一点,你就不会对 skill 抱不切实际的期待。
6.4 心得:从小处开始,用真实任务验证
别一上来就写十个 skill。先写一个 TDD skill,拿一个真实的小任务(比如"给现有函数加参数校验")跑一遍,观察 agent 在哪一步卡壳、哪一步偷懒,然后针对性改 skill。改完再跑,反复几轮,skill 才真正可用。这个过程没有捷径,但每一轮都能让你更懂 agent 的行为模式。
6.5 心得:给 skill 加"自检清单"
在 skill 正文末尾加一个 checklist,让 agent 在结束前逐条自查。比如 TDD skill 的清单可以是:
- 每个测试用例是否都真实运行过并展示了输出?
- 是否每个循环只新增了一个测试?
- 重构后是否重新运行了全部测试?
- 是否有未处理的失败测试?
这个清单相当于给 agent 一个"交卷前检查"的动作,能拦下不少低级失误。实测下来,加了清单之后 agent 的"假装完成"明显减少。
7. 把 agent-skills 用出长期价值
agent-skills这类项目的真正价值,不在于它自带几个 skill,而在于它提供了一套把团队工程经验沉淀成 agent 可执行资产的范式。你今天写的 TDD skill,明天可以扩展成"数据库迁移 skill""API 设计 skill""发布流程 skill"。每沉淀一个,agent 在你项目里的"专业度"就高一截。
我自己的做法是:每次在 code review 里发现 agent 犯的重复性错误,就想想"这个能不能写成一条 skill 规则"。能写就写,写完验证。几个月下来,agent 在我项目里的表现跟刚接入时完全是两个水平。这不是模型变强了,是我把该教的都教给它了。
如果你刚开始折腾,我的建议是:先别管 CLI 和目录规范,就手写一个SKILL.md,塞进项目,让 agent 读,跑一个真实任务,感受一下"按需加载的指令"和"常驻的 CLAUDE.md"到底差在哪。感受过那个差异,后面的一切就顺理成章了。