1. 从“装了一堆技能却用不起来”说起
如果你最近在折腾 AI coding agents,大概率会遇到一个很尴尬的局面:模型本身能力不差,但一到具体项目里就开始“犯迷糊”——不知道你的代码规范、不熟悉你的目录结构、写测试的方式跟你团队完全对不上。你反复在对话里贴规范、贴示例,下一次开新会话又得重来一遍。这种重复劳动,本质上不是模型的问题,而是技能没有沉淀成可复用的资产。
agent-skills这个项目要解决的就是这件事。它把“怎么让 AI coding agent 按你的方式干活”这件事,从一次性对话提示,变成了一套可安装、可版本管理、可组合的技能包体系。配套的skills CLI让你像装 npm 包一样,把技能装进 Claude Code 这类 agent 环境里,按需启用。再叠加test-driven-development这类具体技能,agent 就能在写代码前先写测试、跑测试、再改实现,形成闭环。
这篇内容适合三类人看:一是刚接触 Claude Code、还在纠结安装和配置的入门用户;二是已经在用 agent 写代码、但被“每次都要重新交代背景”折磨的开发者;三是想把团队规范固化进 agent 工作流的 Tech Lead。我会从设计思路讲到实操落地,把技能包的目录结构、CLI 的安装逻辑、TDD 技能的具体运作方式,以及我踩过的坑,全部摊开讲清楚。读完你至少能做到:自己写一个技能包,装进 agent,并让它稳定生效。
2. agent-skills 到底在解决什么问题
2.1 传统提示词工程的三个死穴
先说清楚痛点,不然很难理解这套东西的价值。我们平时用 AI coding agent,最常见的做法是在对话里写一段“你是一个资深工程师,请遵循以下规范……”。这种做法有三个绕不过去的死穴。
第一个是不可复用。你在这个项目里写的规范,换个项目就得重写。哪怕两个项目用的是同一套技术栈,你也得复制粘贴一遍,而且很容易漏掉几条。第二个是不可版本管理。规范写在对话里,改了什么、什么时候改的、为什么改,全都没有记录。团队里三个人用三套说法,agent 的输出自然飘忽不定。第三个是不可组合。你既想让 agent 遵守代码规范,又想让它用 TDD 流程,还想让它按你的 commit message 格式提交,这些需求堆在一段提示里,模型很容易顾此失彼。
agent-skills的思路是把这些规范拆成独立的“技能单元”,每个技能只负责一件事,通过 CLI 安装到 agent 的技能目录里。agent 在运行时按需加载,互不干扰。这跟微服务拆分的逻辑是一样的:单一职责、独立部署、按需组合。
2.2 技能包与普通提示词的本质区别
很多人第一反应是“这不就是把提示词存成文件吗”。表面看是这样,但本质区别在于加载时机和触发机制。
普通提示词是你手动贴进去的,agent 被动接收。而技能包通常带有元数据,比如技能名称、描述、适用场景、触发条件。agent 在接到任务时,会先判断“这个任务需不需要调用某个技能”,需要才加载对应的技能内容。这就避免了把所有规范一股脑塞进上下文导致的 token 浪费和注意力稀释。
举个具体例子。你装了一个test-driven-development技能,它的描述里写着“当用户要求实现新功能或修复 bug 时使用”。那么当你让 agent 写一个新函数时,它会自动加载这个技能,按照“先写失败测试、再写实现、再重构”的流程走。而当你只是让它解释一段代码时,这个技能不会被加载,上下文保持干净。这种按需加载是技能包相比裸提示词最大的工程优势。
2.3 为什么是 Claude Code 这类 agent 先受益
技能包这套机制,对 agent 环境的成熟度有要求。它需要 agent 支持读取本地技能目录、解析技能元数据、在运行时动态加载。Claude Code 这类工具恰好提供了这种扩展能力,所以agent-skills和skills CLI优先适配了它。
这里要提醒一句:不同 agent 对技能目录的约定不一样。有的放在项目根目录的隐藏文件夹里,有的放在用户主目录的全局配置里。安装前一定要确认你的 agent 版本支持哪种路径,否则技能装了也不生效。这个坑我在后面会详细讲。
3. 技能包的目录结构与核心机制
3.1 一个技能包的最小构成
要理解agent-skills,得先看懂一个技能包长什么样。基于常见实践,一个最小可用的技能包通常包含这几个部分:
- 技能主文件:一般是 Markdown 格式,写清楚这个技能要 agent 做什么、遵循什么流程、有哪些约束。
- 元数据文件:描述技能的名称、版本、适用场景、触发关键词。有些实现会把它写在主文件的头部,用类似 frontmatter 的格式。
- 辅助资源:比如代码模板、示例文件、检查清单。这些不是必须的,但能让技能更“厚实”。
我建议新手从单文件技能开始,把元数据写在文件头部,先跑通流程,再考虑拆分成多文件结构。一上来就搞复杂目录,很容易在路径引用上翻车。
3.2 技能是如何被 agent 发现和加载的
这里讲一下底层逻辑,理解了它你就能自己排查“技能为什么不生效”。
agent 启动时,会扫描约定的技能目录。扫描到每个技能后,读取元数据,建立一个“技能索引”。这个索引里通常只有名称和描述,不包含技能正文。当你的请求进来,agent 拿请求内容跟索引里的描述做匹配,判断哪些技能相关。匹配上的技能,才会把正文加载进上下文。
所以有两个关键点:描述写得准不准,决定了技能能不能被正确触发;正文写得精不精,决定了触发后 agent 干得好不好。很多人技能不生效,问题就出在描述太模糊,比如只写“代码相关”,agent 根本判断不出什么时候该用。
3.3 技能之间的组合与优先级
实际项目里,你往往需要多个技能同时生效。比如写一个新功能,既要 TDD 技能管流程,又要代码规范技能管风格,还要 commit 技能管提交格式。这时候就涉及组合和优先级。
常见做法是给技能设置优先级或者依赖关系。流程类技能(如 TDD)优先级高,因为它决定了大方向;风格类技能优先级低,作为补充约束。如果两个技能冲突,比如一个说“函数不超过 20 行”,另一个说“禁止拆分函数”,那 agent 就会犯难。所以写技能时要避免跟其他技能产生硬冲突,把约束写成“建议”而非“强制”,给 agent 留出判断空间。
提示:技能不是越多越好。装太多技能会让 agent 的匹配负担变重,反而降低准确率。我的经验是单个项目常驻技能控制在 5 个以内,其余按需临时启用。
4. skills CLI 安装与 Claude Code 环境配置实操
4.1 安装前的环境确认清单
在动手之前,先把环境确认清楚,能省掉后面一大堆报错。你需要确认这几件事:
| 检查项 | 确认内容 | 常见问题 |
|---|---|---|
| Agent 版本 | 是否支持技能目录扩展 | 老版本可能不识别技能路径 |
| 运行环境 | Node.js 或对应运行时是否就绪 | CLI 通常依赖 Node 环境 |
| 目录权限 | 技能目录是否可写 | 全局目录常因权限写入失败 |
| 网络环境 | 能否正常拉取技能包 | 依赖源不通会导致安装中断 |
我见过最多的情况是目录权限问题。全局技能目录在类 Unix 系统下往往需要提权才能写入,但很多人直接用普通权限跑安装命令,结果技能文件写了一半就失败,agent 扫描到残缺文件直接报错。建议先手动确认目录可写,再执行安装。
4.2 skills CLI 的安装与初始化
skills CLI是管理技能包的命令行工具,核心命令就那么几个:安装、列出、启用、禁用、卸载。安装方式通常是通过包管理器全局安装,然后在项目里初始化。
# 全局安装 skills CLI(以 Node 生态为例) npm install -g skills-cli # 在项目目录初始化技能配置 skills init # 查看当前已安装的技能 skills list # 安装一个技能包 skills install test-driven-development # 启用某个技能 skills enable test-driven-development初始化的作用是生成技能目录和配置文件。这一步做完,你的项目里会多出一个技能存放目录,agent 启动时就会去扫描它。如果你用的是全局技能,初始化时可以选择写到用户主目录,这样所有项目都能共享。
4.3 Claude Code 侧的配置要点
技能装好了,还得让 Claude Code 知道去哪找。这一步是新手最容易卡住的地方。配置的核心是告诉 agent 技能目录的路径。
在 Claude Code 的配置文件里,通常需要指定技能目录的位置。如果你用的是项目级技能,路径指向项目内的技能文件夹;如果是全局技能,指向用户主目录下的配置目录。配置改完记得重启 agent,否则不会重新扫描。
{ "skills": { "directory": "./.agent-skills", "autoLoad": true } }autoLoad这个开关很关键。打开后 agent 会自动扫描并匹配技能;关掉的话就得手动指定加载哪个技能。日常开发建议打开,调试技能时再关掉,避免干扰。
4.4 验证技能是否真正生效
装完别急着用,先验证。最简单的办法是给 agent 一个明确会触发技能的任务,观察它的行为是否符合技能定义。比如装了 TDD 技能后,让它写一个简单函数,看它是不是先写测试。
如果行为不对,按这个顺序排查:技能目录路径对不对、元数据描述是否匹配任务、技能是否处于启用状态、agent 是否重启过。这四步能解决九成的“技能不生效”问题。
注意:有些 agent 会缓存技能索引,改了技能内容后不重启不生效。调试阶段养成“改完就重启”的习惯,能少走很多弯路。
5. 以 test-driven-development 技能为例的完整落地
5.1 TDD 技能的核心流程设计
test-driven-development是agent-skills里最值得先装的技能之一,因为它把一套成熟工程实践固化成了 agent 的默认行为。它的核心流程就是经典的红-绿-重构三步:
- 红:先写一个会失败的测试,明确要实现的预期行为。
- 绿:写最少的实现代码让测试通过,不追求优雅。
- 重构:在测试保护下优化代码结构,保持测试全绿。
技能文件里会把这套流程写成明确的指令,并附上约束,比如“禁止在测试通过前写实现代码”“每次只处理一个测试用例”。这些约束是 TDD 能真正跑起来的关键,因为模型天然倾向于一次性把实现和测试都写完,那就失去 TDD 的意义了。
5.2 技能文件里应该写什么
基于常见实践,一个 TDD 技能文件大致包含这几块内容:
- 触发条件:明确什么时候用这个技能,比如“实现新功能、修复 bug、重构现有代码”。
- 执行步骤:把红绿重构拆成 agent 可执行的动作序列。
- 约束与禁忌:列出不允许的行为,比如跳过测试、一次写多个测试。
- 输出格式:规定 agent 每步要汇报什么,方便你跟踪进度。
写技能文件有个诀窍:用命令式短句,别用描述性长句。模型对“先写测试”这种指令的执行度,远高于“建议采用测试先行的方式”。指令越直接,行为越稳定。
5.3 一次完整的 TDD 实操记录
我拿一个真实场景走一遍。需求是写一个函数,判断字符串是不是回文。
第一步,agent 加载 TDD 技能后,先输出测试代码:
def test_is_palindrome(): assert is_palindrome("racecar") is True assert is_palindrome("hello") is False assert is_palindrome("") is True此时is_palindrome还不存在,测试必然失败,这就是“红”。
第二步,agent 写最简实现:
def is_palindrome(s): return s == s[::-1]跑测试,全绿。注意它没有加任何额外功能,没有处理大小写、没有去空格,因为测试没要求。这就是“绿”阶段该有的克制。
第三步,如果后续需求增加,比如要忽略大小写,那就先加一个失败测试,再改实现。整个循环由测试驱动,而不是由 agent 的“我觉得应该这样”驱动。
5.4 让 TDD 技能稳定生效的三个技巧
第一个技巧是把测试命令写进技能。agent 写完测试后需要自己跑,如果它不知道用什么命令跑测试,流程就断了。在技能里明确写“使用 pytest 运行测试”或“使用 npm test”,能大幅提升稳定性。
第二个技巧是限制单次任务粒度。TDD 最怕 agent 一口气写十个测试再写一堆实现。在技能里加一条“每次只处理一个测试用例,通过后再进行下一个”,能强制它慢下来。
第三个技巧是要求 agent 汇报测试结果。让它每跑一次测试就贴出输出,你能实时看到红绿状态,也方便在它“假装测试通过”时及时纠正。模型偶尔会跳过实际执行直接说通过,这个约束能有效遏制。
6. 常见问题与排查技巧实录
6.1 技能装了但 agent 完全没反应
这是最高频的问题。排查顺序我整理成了一张表:
| 现象 | 可能原因 | 解决方式 |
|---|---|---|
| 技能列表里看不到 | 安装路径不对 | 确认安装目录与配置一致 |
| 列表能看到但不触发 | 描述不匹配任务 | 优化技能描述关键词 |
| 触发了一次后续不触发 | 索引缓存未刷新 | 重启 agent |
| 部分技能生效部分不生效 | 技能间冲突 | 检查约束是否矛盾 |
我遇到过一次特别隐蔽的情况:技能目录路径里带了空格,配置解析时被截断,导致 agent 扫描了一个不存在的目录。这种问题看日志才能发现,所以养成看 agent 启动日志的习惯很重要。
6.2 技能之间互相打架怎么办
多个技能同时生效时,冲突几乎不可避免。比如代码规范技能要求“函数必须写类型注解”,而某个快速原型技能说“优先保证速度,可省略注解”。agent 夹在中间就会摇摆。
解决办法是分层。把技能分成流程层和风格层,流程层优先级高,风格层作为默认建议。在风格层技能里加一句“当与其他技能冲突时,以流程层技能为准”,给 agent 一个明确的裁决规则。另外,能合并的技能尽量合并,减少冲突面。
6.3 技能更新后行为变了
技能是活的,你会不断迭代它。但更新后 agent 行为突变,往往是因为改动影响了触发匹配或流程约束。我的做法是给技能加版本号,每次改动记录变更点。出问题时能快速回滚到上一个稳定版本。
还有个小坑:如果你用的是全局技能,更新后所有项目都会受影响。所以重大改动前,先在单个项目里用项目级技能验证,确认没问题再推到全局。
6.4 关于模型接入的一些现实问题
很多人关心能不能用第三方模型跑这套技能体系。从机制上讲,技能包本质是文本资源和加载逻辑,跟底层模型是解耦的。只要 agent 环境支持技能目录扫描,换模型不影响技能生效。
但要注意,不同模型对指令的遵循度差异很大。同一份 TDD 技能,在遵循度高的模型上能严格走红绿重构,在遵循度低的模型上可能直接跳过测试。所以换模型后,建议重新验证核心技能的行为,别默认它还能按老样子工作。技能写得越明确、约束越硬,跨模型的稳定性就越好。
7. 自己动手写一个技能包的完整方法
7.1 从重复劳动里找技能选题
写技能包的第一步不是写代码,是找选题。方法很简单:回顾你最近一周跟 agent 的对话,哪些话你重复说了三遍以上?那些就是最该固化成技能的内容。
常见的选题方向有:代码风格规范、提交信息格式、测试流程、文档模板、review 检查清单、特定框架的用法约定。选题的原则是高频且明确。如果一个需求你自己都说不清楚,那写成技能也是模糊的,agent 执行起来照样飘。
7.2 技能文件的写作模板
我总结了一个通用模板,你可以直接套:
--- name: 技能名称 description: 一句话说明什么时候用这个技能 version: 1.0.0 --- ## 目标 这个技能要达成什么。 ## 执行步骤 1. 第一步做什么 2. 第二步做什么 ## 约束 - 不允许做什么 - 必须做什么 ## 输出要求 每步要汇报什么内容。description是最关键的一行,它决定触发匹配。写法是“当……时使用”,把触发场景写具体。比如“当需要为新功能编写测试时使用”,比“测试相关”强太多。
7.3 技能调试与迭代的实操心得
技能写完不是终点,是起点。第一版几乎不可能完美,得靠实际使用来打磨。我的迭代节奏是:先用一周,记录每次 agent 行为不符合预期的地方,周末集中改一版。
调试时有个技巧:把技能里的约束一条条单独测试。比如你写了“禁止跳过测试”,那就故意给一个容易让 agent 偷懒的任务,看它会不会违反。逐条验证比整体感觉靠谱得多。
另外,技能描述里的关键词要跟你的实际用词对齐。你平时说“写单测”,技能描述里就别只写“单元测试”,把常见说法都覆盖进去,匹配率会明显提升。
8. 技能体系的扩展与团队协作
8.1 把团队规范沉淀成共享技能
个人用技能包已经能省不少事,团队用价值更大。做法是把团队共识的规范写成技能,放进共享仓库,成员通过 CLI 安装。这样新人入职第一天,agent 就已经懂团队规矩了,不用口口相传。
团队技能要特别注意共识性。别把某个人的个人偏好写成团队技能,否则会引起抵触。建议先在小范围试用,收集反馈,稳定后再推广。技能仓库也要有 review 机制,改动走 PR,保证质量。
8.2 技能版本管理与分发
技能多了以后,版本管理就成了刚需。建议给技能仓库打 tag,CLI 安装时支持指定版本。这样某个技能更新出问题时,团队可以锁定旧版本,不影响日常开发。
分发方式上,小团队直接共享仓库地址就行;规模大了可以考虑私有 registry,但别过度工程化。我见过团队为了技能分发搞了一套复杂系统,结果维护成本比技能本身还高,得不偿失。
8.3 技能体系的边界与注意事项
最后说几个边界问题。技能包不是万能的,它擅长固化明确的、可重复的工作流,但不擅长处理需要大量上下文判断的模糊任务。别指望一个技能解决所有问题。
还有,技能内容里不要放敏感信息,比如内部密钥、私有地址。技能文件会被加载进上下文,等于把这些信息暴露给了模型。团队技能尤其要注意这点,提交前过一遍敏感信息检查。
我个人在实际操作中的体会是,技能体系最大的价值不在于让 agent 变聪明,而在于让它的行为可预期、可复现。当 agent 的输出稳定了,你才敢把它真正接进生产流程。从装第一个 TDD 技能开始,慢慢积累属于你自己的技能库,这件事的复利效应会超出你的预期。