1. agent-skills 到底在解决什么问题
第一次看到agent-skills这个词,很多人会以为是某个新出的 AI 模型或者又一个套壳工具。实际上它要解决的是一个非常具体、非常痛的问题:AI coding agent 每次开新会话都像失忆一样,你得反复告诉它项目规范、测试怎么写、提交信息怎么格式化。
我最早用 Claude Code 的时候,每次让它写代码都要在 prompt 里重复一遍"用 pytest 写测试""函数命名用 snake_case""不要直接改 main 分支"。写三五次还行,写到第十次的时候我就想,这东西难道不能记住吗?
agent-skills就是干这个的。它本质上是一套可复用的技能定义文件,放在项目目录里,AI coding agent 启动时自动读取,相当于给 agent 装了一本"项目员工手册"。你写一次,之后每次会话它都自动遵守。
这个项目适合谁?三类人:
- 已经在用 Claude Code、Cursor、Windsurf 这类 AI coding agent 的开发者,想让 agent 输出更稳定
- 团队里多人共用 AI 辅助编码,需要统一代码风格和流程
- 想把自己的工作流沉淀成可复用资产,而不是每次靠记忆和复制粘贴
关键词里提到的test-driven-development、skills CLI、AI coding agents其实指向同一个核心:把开发规范从"人口头交代"变成"文件系统里的结构化定义"。
我实测下来最大的感受是,这东西的价值不在于让 AI 变聪明,而在于让 AI 变一致。同一个项目里,今天写的代码和下周写的代码,风格、测试覆盖、提交习惯能保持统一,这才是工程上真正值钱的地方。
2. agent-skills 的文件结构与加载机制
2.1 一个 skill 文件里到底写了什么
agent-skills的核心单位是 skill 文件,通常放在项目根目录的.agent/skills/或者.claude/skills/下面(不同 agent 工具路径略有差异,但逻辑一致)。每个 skill 是一个 Markdown 文件,带 YAML frontmatter。
我拿一个实际在用的 TDD skill 举例:
--- name: test-driven-development description: 强制在实现功能前先写失败测试 trigger: 当用户要求新增功能或修复 bug 时 --- ## 规则 1. 收到功能需求后,先写一个会失败的测试 2. 运行测试,确认它确实失败(红) 3. 写最小实现让测试通过(绿) 4. 重构,保持测试通过 5. 不允许在没有测试的情况下提交实现代码 ## 测试文件命名约定 - 单元测试:`test_<module>.py` - 集成测试:`test_<module>_integration.py` - 测试函数名必须描述行为,如 `test_returns_empty_list_when_no_match`这个文件的关键在于trigger字段。它不是每次都加载,而是 agent 判断当前任务匹配 trigger 时才激活。这就避免了把所有规则一股脑塞进 context 导致 token 浪费。
2.2 加载顺序与优先级
这里有个很多人踩过的坑:skill 的加载是有优先级的,项目级覆盖用户级,用户级覆盖全局默认。
我一开始把所有 skill 都放在用户目录~/.claude/skills/下,结果换项目的时候发现有些规则不适用,比如 A 项目用 pytest,B 项目用 jest,全局 skill 里写死 pytest 就出问题了。
正确的做法是分层:
| 层级 | 路径 | 适用场景 |
|---|---|---|
| 全局 | ~/.claude/skills/ | 个人通用习惯,如提交信息格式 |
| 项目 | <project>/.claude/skills/ | 项目特定规范,如测试框架、目录结构 |
| 会话 | 临时 prompt | 一次性任务,不沉淀 |
提示:项目级 skill 建议提交到 git,这样团队每个人拉下来就自动生效,不需要口头同步规范。
2.3 为什么用 Markdown 而不是 JSON/YAML
我一开始觉得用 JSON 定义规则更"工程化",后来发现 Markdown 才是对的。原因是skill 最终是要喂给 LLM 的,而 LLM 对自然语言 + 结构化标记的混合格式理解最好。纯 JSON 反而会让模型把注意力放在语法上而不是语义上。
而且 Markdown 允许你写解释性文字。比如你可以写"为什么这条规则存在",agent 理解了意图之后,遇到规则没覆盖的边界情况也能做出合理判断。这一点是纯配置格式做不到的。
3. 从零搭建一套可用的 skills 库
3.1 先别急着写,先盘点你重复说了什么
我的经验是,不要一上来就设计一套完美的 skill 体系。正确做法是先记录一周,把你每次对 AI 重复说的话记下来。
我当时记了这么几条高频重复:
- "用 pytest,不要用 unittest"
- "提交信息用 conventional commits 格式"
- "改代码前先看有没有对应测试"
- "不要动 migrations 目录里的历史文件"
- "API 返回统一用
{code, data, message}结构"
这五条就是我的第一批 skill。每条对应一个文件,内容不超过 50 行。
3.2 写 skill 的三个原则
原则一:一条 skill 只干一件事。我见过有人把"测试规范 + 提交规范 + 代码风格"塞进一个文件,结果 trigger 很难写,要么全触发要么全不触发。拆开之后每个 skill 的 trigger 都很精准。
原则二:规则要可验证。"写高质量代码"这种规则等于没写。要写成"函数不超过 50 行""每个 public 方法必须有 docstring"这种 agent 能自查的。
原则三:给反例。这是我从实践中总结的最有用的一条。光说"要怎么做"不够,加一句"不要怎么做"效果翻倍。比如:
## 正确 def get_user(user_id: int) -> User: ... ## 错误(不要这样) def get_user(id): # 缺少类型标注,参数名过于简略 ...3.3 用 skills CLI 管理版本
关键词里提到的skills CLI是配套的命令行工具,主要用来列出、启用、禁用 skill。我常用的几个命令:
# 列出当前生效的所有 skill skills list # 查看某个 skill 的详细内容和来源路径 skills show test-driven-development # 临时禁用某个 skill(调试时很有用) skills disable commit-convention # 重新启用 skills enable commit-convention调试 skill 的时候,skills show特别有用。因为有时候你以为某个 skill 生效了,实际上路径放错了根本没加载。用这个命令能立刻确认。
注意:不同 agent 工具的 CLI 命令名可能不同,有的叫
agent skills,有的直接集成在工具内部。核心逻辑都是 list/show/enable/disable 这四个动作。
4. 把 TDD 真正落地到 agent 工作流里
4.1 为什么 TDD 是最值得做成 skill 的
在所有 skill 里,test-driven-development是投入产出比最高的一个。原因是AI 天然倾向于先写实现再补测试,而且补的测试往往是"验证实现正确"而不是"验证需求正确"。
我踩过的坑:让 agent 写一个"用户注册"功能,它先写了实现,然后写了个测试,测试内容是"调用 register 函数返回 200"。这个测试毫无意义,因为它只是复述了实现的行为,没有验证任何业务规则。
做成 skill 之后,agent 的行为变了。它会先问"注册需要满足哪些规则",然后针对每条规则写测试:
def test_register_fails_when_email_already_exists(): ... def test_register_fails_when_password_too_short(): ... def test_register_succeeds_with_valid_input(): ...4.2 TDD skill 的完整配置
我把实际在用的配置贴出来,你可以直接抄:
--- name: test-driven-development description: 强制红绿重构循环 trigger: 新增功能、修复 bug、重构代码 --- ## 强制流程 1. 理解需求后,先列出所有需要验证的行为 2. 为每个行为写一个测试,测试名描述行为而非实现 3. 运行测试,确认全部失败 4. 逐个实现,每次只让一个测试通过 5. 全部通过后重构,重构期间测试必须保持绿色 ## 禁止事项 - 禁止先写实现再补测试 - 禁止测试中 mock 被测函数本身 - 禁止一个测试断言多个不相关的行为 - 禁止跳过"确认测试失败"这一步 ## 测试命名模板 test_<动作>_<条件>_<预期结果> 示例: - test_login_fails_when_password_wrong - test_cart_total_includes_tax4.3 实测中的意外情况
用了两个月,我发现两个问题。
问题一:agent 有时会"假装"测试失败。它会写一个测试,然后说"测试失败了,现在开始实现",但实际上根本没运行测试。解决办法是在 skill 里加一条"必须展示测试运行的实际输出"。
问题二:小改动也走完整 TDD 流程太重。改个错别字也要先写测试就很荒谬。所以我在 trigger 里加了限定:"仅当涉及逻辑变更时触发,纯文案、格式、注释修改不触发"。
这两个调整之后,TDD skill 才真正变得可用而不是碍事。
5. 多 agent 工具下的 skills 兼容策略
5.1 Claude Code、Cursor、Windsurf 的差异
关键词里大量出现claude code、vscode配置claude code、claude code for vs code,说明很多人是在 VS Code 里用 Claude Code。这里有个现实问题:不同 agent 工具读取 skill 的路径和格式不完全一样。
我实测的对应关系:
| 工具 | skill 路径 | frontmatter 支持 |
|---|---|---|
| Claude Code | .claude/skills/ | 完整支持 |
| Cursor | .cursor/rules/ | 部分支持 |
| Windsurf | .windsurf/ | 部分支持 |
5.2 一套内容多处复用的做法
我的做法是内容只写一份,用软链接或者构建脚本分发到各工具目录。
# 主内容放在 .agent-skills/ # 分发到各工具 ln -s ../.agent-skills/test-driven-development.md .claude/skills/ ln -s ../.agent-skills/test-driven-development.md .cursor/rules/这样改一处,所有工具同步生效。比维护多份副本靠谱得多。
5.3 模型切换时的注意事项
热词里提到使用cc switch 接入 deepseek v4, qwen, glm等模型,这涉及一个关键点:不同模型对 skill 的遵循程度差异很大。
我的实测结论:
- Claude 系列对 skill 的遵循度最高,基本能严格执行
- 部分国产模型对长 skill 文件的后半部分容易"遗忘"
- 小参数模型对复杂 trigger 判断不准
所以如果你要切换模型,建议把 skill 拆得更短,每条规则更独立。我一般控制在 30 行以内,超过就拆。
6. 团队协作中的 skills 治理
6.1 skill 也要 code review
这一点很多人没想到。skill 文件本质上是团队开发规范的代码化,它应该和代码一样走 review 流程。
我们团队的做法是:新增或修改 skill 必须提 PR,至少一人 review。review 的重点是:
- 规则是否可验证
- trigger 是否过宽或过窄
- 是否和现有 skill 冲突
6.2 冲突检测
skill 之间会冲突。我遇到过:一个 skill 说"提交信息用中文",另一个说"提交信息用英文"。agent 遇到这种情况会随机选一个,行为不稳定。
解决办法是定期跑一次冲突检查。简单做法是把所有 skill 的规则提取出来,人工过一遍。复杂点可以写脚本做关键词匹配。
提示:skill 数量超过 15 个之后,冲突概率明显上升。建议控制在 10-15 个核心 skill,其余用项目级覆盖。
6.3 新人上手
skill 体系最大的隐性价值是新人 onboarding。新同事拉下代码,AI agent 自动按团队规范工作,他不需要先读一堆文档。我带的几个新人反馈,有了 skill 之后,他们提交的代码第一次 review 通过率明显提高。
7. 我踩过的几个真实坑
7.1 skill 写太长导致被忽略
我最早写的 TDD skill 有 200 多行,结果 agent 经常只执行前几条。后来砍到 40 行,执行率立刻上去了。LLM 对长指令的注意力是衰减的,越往后越容易忽略。
7.2 trigger 写太宽导致误触发
有个 skill 的 trigger 我写的是"修改代码时",结果连改注释都触发,每次都弹一堆规则。改成"涉及逻辑变更时"就正常了。
7.3 忘了 skill 也会影响 token 消耗
每个激活的 skill 都会占用 context。我有段时间开了 20 个 skill,结果发现 agent 处理复杂任务时容易"忘事"。关掉一半之后恢复正常。skill 不是越多越好,是按需加载。
7.4 路径大小写问题
在 Mac 上路径不区分大小写,部署到 Linux 服务器后.Claude/skills/和.claude/skills/就不一样了,skill 直接不加载。这个坑排查了半小时才发现。
8. 进阶:让 skill 自己进化
8.1 从 review 评论里提取规则
我们团队有个做法:每次 code review 里出现重复的评论,就考虑把它变成 skill。比如 reviewer 第三次说"这个函数缺少错误处理",就该写一条 skill 了。
8.2 用 skill 记录决策而非只记规则
高级用法是让 skill 记录为什么这么规定。比如:
## 为什么 API 返回统一用 {code, data, message} 历史原因:早期接口返回格式混乱,前端需要为每个接口写不同的解析逻辑。 统一之后前端只需要一个通用响应处理器。 新增接口必须遵守,否则前端需要额外适配。agent 理解了背景之后,遇到规则没覆盖的边界情况也能做出符合意图的判断。
8.3 定期清理
skill 会过时。技术栈换了、规范改了,旧 skill 就成了负担。我建议每季度过一遍,删掉不再适用的。判断标准很简单:过去三个月这条 skill 有没有真正影响过 agent 的输出?没有就删。
这套东西用下来,我最大的体会是:agent-skills不是一个工具,而是一种把团队隐性知识显性化的方法。它逼着你想清楚"我们到底怎么写代码",然后把这个答案写成 AI 能执行的文件。这个过程本身,比 AI 帮你写多少代码更有价值。