1. 从 agent-skills 说起:为什么 AI 编码代理需要一套技能体系
第一次看到agent-skills这个项目名的时候,我的直觉是:这大概率又是一个把提示词打包成模板的仓库。但真正翻完它的结构、跑通它的 CLI、再把它接到 Claude Code 里用了几轮之后,我改主意了。它解决的不是"提示词怎么写"的问题,而是"AI 编码代理怎么稳定地做对一件事"的问题——这两件事的难度差了一个量级。
先把概念说清楚。所谓agent-skills,本质上是给 AI 编码代理(AI coding agents)准备的一套可复用、可组合、可被程序化调用的能力单元。每个 skill 通常包含三部分:一段描述这个能力做什么的元信息、一份指导代理如何执行的操作说明、以及可选的辅助脚本或资源文件。代理在接到任务时,不是靠一段万能提示词硬扛,而是先判断"这个任务该调用哪个 skill",再按 skill 里定义的流程一步步执行。
这套思路为什么重要?因为大模型在编码场景里最大的问题从来不是"不会写代码",而是"不稳定"。同一个需求,今天给你写个能跑的版本,明天给你写个漏了边界条件的版本,后天干脆把测试文件也一起改了。test-driven-development这类 skill 的价值就在于,它把"先写测试、再写实现、最后重构"这个流程固化下来,让代理每次都必须走同一条路,而不是自由发挥。
这个项目适合谁?三类人最该看:一是已经在用 Claude Code 或类似工具、但总觉得输出质量飘忽的开发者;二是想把 AI 编码能力集成进自己 CI/CD 或内部工具链的工程团队;三是想理解"代理工程"这套方法论到底怎么落地的人。哪怕你只是刚装完 Claude Code 想找个靠谱的起点,这套 skill 组织方式也比你自己攒一堆提示词要省事得多。
下面我会按"设计思路—核心细节—实操落地—问题排查"这条线,把 agent-skills 从里到外拆一遍,中间会穿插我自己踩过的坑和实测有效的配置。
2. 整体设计与思路拆解:为什么是"技能"而不是"提示词"
2.1 从提示词工程到技能工程的范式转变
早两年大家玩 AI 编码,主流做法是攒一个超长的 system prompt,把编码规范、项目结构、命名习惯全塞进去。这套做法在小项目上还能凑合,一旦项目变大就崩了——提示词越长,模型对其中每一条的注意力越稀释,最后变成"什么都说了等于什么都没说"。
agent-skills 的设计思路正好相反:把一个大而全的提示词,拆成一堆小而专的技能。每个 skill 只负责一件事,比如"写单元测试""做代码审查""生成数据库迁移脚本"。代理在执行任务时按需加载,上下文里只出现当前真正需要的那部分指令。这个转变带来的直接好处是上下文利用率大幅提升,间接好处是每个 skill 都可以独立迭代、独立测试。
我打个生活化的比方。传统提示词像是一本厚厚的员工手册,新员工入职先背完整本,干活时还得自己翻。技能体系更像是贴在工位旁边的一张张操作卡片,做咖啡的时候看咖啡那张,修打印机的时候看打印机那张。手册不会消失,但它退居到"背景知识"的位置,真正指导动作的是那些卡片。
2.2 技能目录结构背后的考量
一个典型的 skill 目录长这样:
skills/ test-driven-development/ SKILL.md scripts/ run-tests.sh references/ testing-patterns.md code-review/ SKILL.md核心是那个SKILL.md,它承担了元信息和操作说明两个职责。文件开头通常有一段结构化的元数据,声明这个 skill 的名字、适用场景、触发条件;正文部分则是给代理看的操作指南。把脚本和参考资料放在子目录里,是为了让 skill 保持"自包含"——一个 skill 文件夹拷到哪都能用,不依赖外部路径。
提示:SKILL.md 里的描述要写得像给一个新同事交代任务,而不是像写 API 文档。代理理解自然语言指令的能力远强于理解结构化配置,把"什么时候用、怎么用、注意什么"用大白话讲清楚,效果比堆参数好得多。
2.3 与 Claude Code 的契合点在哪里
Claude Code 这类工具的一个关键特性是它能读写文件、执行终端命令、并且能在多轮对话里保持任务上下文。agent-skills 恰好利用了这三点:skill 文件本身是文件,代理可以直接读;skill 里的脚本可以通过终端执行;整个"读 skill—执行—验证"的循环天然就是多轮的。
这也是为什么 skills CLI 这类工具会出现。手动管理几十个 skill 文件夹、还要保证它们被正确加载,太容易出错了。CLI 的作用就是把"安装、更新、列出、移除 skill"这些操作标准化,让 skill 的分发像装 npm 包一样简单。
3. 核心细节解析与实操要点
3.1 SKILL.md 到底该怎么写
这是整个体系里最容易被低估的部分。很多人第一次写 SKILL.md,会写成一段泛泛的"你要认真写测试"之类的废话。代理拿到这种指令,跟没拿到差不多。有效的写法是把流程拆成可验证的步骤,每一步都有明确的输入和输出。
以 test-driven-development 这个 skill 为例,一份能用的 SKILL.md 大致包含这些内容:
- 触发条件:当用户要求新增功能、修复 bug、或重构现有代码时启用
- 前置检查:确认项目里已有测试框架,确认测试命令是什么
- 执行流程:先写一个会失败的测试,运行确认它确实失败,再写最小实现让它通过,最后重构
- 验证标准:所有测试通过,且新增测试确实覆盖了目标行为
- 禁止事项:不允许在没写测试的情况下直接改实现代码
注意最后那条"禁止事项"。这是 skill 和普通提示词最大的区别之一——好的 skill 会明确划出红线。模型在没有约束的时候倾向于走捷径,你告诉它"必须先写测试",它可能还是会先写实现再补测试。但如果你明确写"禁止先改实现",它在多数情况下会遵守。
3.2 脚本与代理的分工边界
一个常见的困惑是:哪些事该让代理用自然语言推理完成,哪些事该写成脚本让代理调用?
我的经验法则是:确定性的、重复性的、容易出错的操作用脚本,需要判断和权衡的操作用自然语言。比如"运行测试并返回结果"这件事,写成脚本最稳,因为命令是固定的,代理只需要读输出。"判断这个测试是否覆盖了边界条件"这件事,就得靠代理推理,写不成脚本。
在 agent-skills 里,脚本通常放在scripts/目录下,SKILL.md 里用相对路径引用。这样设计的好处是脚本可以被单独测试——你可以不启动代理,直接跑一遍脚本看它是否正常工作。这一点在排查问题时特别有用,能快速区分"是脚本坏了"还是"是代理理解错了"。
3.3 技能的粒度控制
粒度太粗,一个 skill 管一大堆事,等于没拆;粒度太细,一个 skill 只管一行代码的写法,代理光加载 skill 就耗尽了上下文。我实测下来比较舒服的粒度是:一个 skill 对应一个完整的、有明确起止的工作单元。
"写一个函数的单元测试"太细,"完成一个功能模块的开发"太粗,"为一个已有函数补充测试覆盖"刚好。判断标准很简单:如果这个 skill 执行完之后,你能明确说"这件事做完了",那粒度就合适。
3.4 版本管理与团队协作
skill 是要演进的。今天你觉得"先写测试"这条规则没问题,明天可能发现某些场景下需要先写接口定义。这时候就需要版本管理。agent-skills 的目录结构天然适合放进 Git,每个 skill 一个文件夹,改动通过 PR 走审查。
团队协作时有个坑要注意:不同人对同一个 skill 的理解可能不一样。我见过一个团队,两个人分别改了 code-review 这个 skill,一个强调"必须指出性能问题",一个强调"不要吹毛求疵",结果合并之后代理彻底懵了。解决办法是在 SKILL.md 里明确写出优先级——哪些问题必须报,哪些问题可以忽略。
4. 实操过程与核心环节实现
4.1 环境准备与 skills CLI 安装
假设你已经在 Ubuntu 或 macOS 上装好了 Claude Code,接下来装 skills CLI。这类 CLI 工具通常通过包管理器分发,具体命令以官方文档为准,我这里给一个通用的流程:
# 确认 Node.js 环境(多数 skills CLI 基于 Node) node -v npm -v # 全局安装 skills CLI(包名以官方为准) npm install -g <skills-cli-package> # 验证安装 skills --version装完之后第一件事是初始化一个 skills 目录:
skills init这个命令会在当前目录下创建skills/文件夹和一份基础配置。如果你是在已有项目里用,建议把 skills 目录放在项目根目录,跟.git平级,这样代理在项目里工作时能直接读到。
注意:如果你用的是 VS Code 里的 Claude Code 插件,skills 目录的路径要跟插件的工作区根目录对齐。我踩过一次坑,skills 放在上层目录,插件死活读不到,排查了半小时才发现是工作区范围的问题。
4.2 安装第一个 skill:以 test-driven-development 为例
# 从仓库安装指定 skill skills install test-driven-development # 列出已安装的 skill skills list # 查看某个 skill 的详情 skills info test-driven-development装完之后,skills/目录下会多出一个test-driven-development/文件夹。打开里面的 SKILL.md 通读一遍,这一步别跳过——你得知道代理接下来会按什么流程走,否则出了问题你都不知道该从哪查。
4.3 在 Claude Code 里触发 skill
skill 装好了不等于代理会自动用。触发方式通常有两种:
第一种是显式触发,你在对话里直接说"用 test-driven-development 这个 skill 来完成这个任务"。这种方式最可控,适合刚开始磨合的阶段。
第二种是隐式触发,代理根据 SKILL.md 里写的触发条件自己判断。这种方式更自然,但前提是你的触发条件写得足够清晰。我建议新手先用显式触发跑通几轮,确认 skill 行为符合预期之后,再放开隐式触发。
实测下来,一个完整的 TDD 流程在 Claude Code 里大概是这样:
- 你描述需求:"给用户模块加一个邮箱格式校验函数"
- 代理读取 test-driven-development skill
- 代理先写测试文件,包含正常邮箱、缺 @ 符号、缺域名等用例
- 代理运行测试,确认失败
- 代理写实现代码
- 代理再次运行测试,确认通过
- 代理检查是否有可重构的地方
整个过程你能在终端里看到每一步的命令和输出。如果第 4 步代理跳过了"确认失败"直接写实现,说明 skill 的约束没生效,需要回去检查 SKILL.md 的措辞。
4.4 参数与配置的取舍
skills CLI 一般会提供一些配置项,比如 skill 的加载优先级、是否允许代理自动安装新 skill、脚本执行的超时时间等。这些参数没有标准答案,取决于你的使用场景。
| 配置项 | 保守设置 | 激进设置 | 适用场景 |
|---|---|---|---|
| 自动安装 skill | 关闭 | 开启 | 个人探索 vs 团队规范 |
| 脚本超时 | 30 秒 | 300 秒 | 单元测试 vs 集成测试 |
| 隐式触发 | 关闭 | 开启 | 磨合期 vs 熟练期 |
| 脚本执行权限 | 需确认 | 自动执行 | 生产项目 vs 实验项目 |
我的建议是从保守设置起步。尤其是脚本执行权限,让代理自动跑命令这件事,在实验项目里很爽,在生产项目里就是定时炸弹。等你对某个 skill 的行为完全信任了,再逐步放开。
4.5 把 skill 接进现有工作流
skill 不是只能手动触发。你可以把它接进 Git hooks、CI 流程、甚至编辑器快捷键。比如在 pre-commit 阶段自动跑一遍 code-review skill,让代理先审一遍改动再提交。
# 示例:在 pre-commit 里调用 code-review skill #!/bin/bash skills run code-review --staged if [ $? -ne 0 ]; then echo "代码审查未通过,请检查代理输出" exit 1 fi这种接法的好处是把 AI 审查变成了流程的一部分,而不是靠人记得去用。坏处是如果 skill 本身有问题,会阻塞整个提交流程。所以接进 CI 之前,一定要先在本地跑够足够的样本。
5. 常见问题与排查技巧实录
5.1 代理不按 skill 流程走怎么办
这是最高频的问题。表现是:skill 明明装了,代理还是按自己的习惯来。排查顺序如下:
先确认 skill 是否真的被加载了。在 Claude Code 里问一句"你现在能用哪些 skill",看它列出来的清单里有没有你要的那个。如果没有,检查 skills 目录路径是否正确、CLI 是否装在了正确的环境里。
如果 skill 加载了但行为不对,八成是 SKILL.md 写得不够明确。重点检查三处:触发条件是否写得太宽泛(导致代理觉得"这个任务不适用")、执行步骤是否有歧义(导致代理自由发挥)、禁止事项是否缺失(导致代理走捷径)。
我遇到过一个典型案例:skill 里写"应该先写测试",代理理解成"可以最后补测试"。把"应该"改成"必须",把"先写测试"改成"在修改任何实现代码之前,必须先创建对应的测试文件并运行确认其失败",问题就解决了。给代理写指令,措辞的确定性比文采重要一百倍。
5.2 脚本执行失败的排查路径
脚本失败通常分三类:环境问题、权限问题、逻辑问题。
环境问题最常见,比如脚本里用了python3但系统只有python,或者依赖的某个命令行工具没装。排查方法是脱离代理,直接在终端里手动跑一遍脚本,看报什么错。
权限问题在 macOS 和 Ubuntu 上表现不同。Ubuntu 上可能是文件没有执行权限,chmod +x一下就好。macOS 上可能是 Gatekeeper 拦截,需要在系统设置里放行。
逻辑问题最麻烦,因为脚本本身能跑,但结果不对。这时候要看脚本的输入输出是否符合预期。我习惯在脚本开头加一行set -e,让它在任何一步失败时立即退出,而不是带着错误状态继续往下跑。
5.3 常见问题速查表
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| 代理完全无视 skill | skill 未加载或路径错误 | 询问代理可用 skill 列表 |
| 代理部分遵循 skill | SKILL.md 措辞模糊 | 检查触发条件和步骤描述 |
| 脚本报 command not found | 依赖工具未安装 | 手动执行脚本看报错 |
| 脚本无输出 | 权限不足或路径错误 | 检查执行权限和相对路径 |
| 测试通过但结果不对 | 测试用例覆盖不足 | 审查测试文件内容 |
| skill 之间行为冲突 | 多个 skill 触发条件重叠 | 明确各 skill 的优先级 |
5.4 几个我踩过的坑
第一个坑是skill 装太多。刚开始新鲜,一口气装了十几个,结果代理每次都要在众多 skill 里挑,反而变慢了,还经常挑错。后来精简到五六个核心 skill,效率明显提升。skill 不是越多越好,够用就行。
第二个坑是忽略 skill 的更新。skill 仓库是会迭代的,早期版本可能有 bug 或者措辞不当。定期跑一下skills update能省不少事。但更新前记得看一眼 changelog,有次更新改了一个 skill 的触发条件,导致我原来的工作流全乱了。
第三个坑是在 skill 里写死项目路径。这种 skill 换个项目就用不了。正确做法是用相对路径或者环境变量,让 skill 保持可移植。
第四个坑是把 skill 当成万能药。有些任务就是不适合用 skill 固化流程,比如探索性的原型开发,你根本不知道下一步要做什么,硬套 skill 反而束手束脚。skill 适合的是那些流程明确、重复性高的任务。
5.5 关于模型选择的补充
Claude Code 本身支持接入不同的模型后端,社区里也有各种切换方案。我的经验是:skill 的效果跟模型能力高度相关。同一个 test-driven-development skill,在能力强的模型上能完整走完流程,在能力弱的模型上可能走到第三步就忘了前面的约束。
所以如果你发现 skill 行为不稳定,先别急着改 skill,换个模型试试。如果换模型之后就好了,那问题在模型不在 skill。反过来,如果换什么模型都不行,那大概率是 SKILL.md 本身有问题。
另外,不同模型对指令格式的敏感度不一样。有的模型对 Markdown 结构响应好,有的对纯文本段落响应好。SKILL.md 用 Markdown 写是通用做法,但如果你的模型表现异常,可以试试把关键指令用纯文本再强调一遍。
6. 把 agent-skills 用出价值的几个思路
skill 体系真正的价值不在于单个 skill 有多强,而在于组合。我现在的做法是把几个基础 skill 串成一条流水线:接到需求先用一个"需求澄清"skill 把模糊描述变成明确任务,再用 test-driven-development 写实现,最后用 code-review 过一遍。三个 skill 各管一段,代理在每段里的行为都可预测。
这套组合用下来,最大的感受是可预测性比峰值能力更重要。一个偶尔写出惊艳代码但经常跑偏的代理,不如一个每次都稳定输出合格代码的代理。skill 的作用就是把代理的行为收敛到一个可接受的范围内,牺牲一点上限,换来大量的确定性。
如果你刚开始接触这套东西,我的建议是从一个 skill 开始,把它用熟、用透,理解它为什么这么设计,再考虑加第二个。贪多嚼不烂这件事,在 skill 体系里体现得特别明显。等你对某个 skill 的行为完全有把握了,再把它接进自动化流程,那时候你才真正拥有了一个可靠的 AI 编码伙伴,而不是一个需要时刻盯着的不确定因素。