1. 从 agent-skills 说起:为什么 AI 编码代理需要一套技能体系
第一次接触agent-skills这个概念,是在给团队搭一套 AI 编码代理工作流的时候。当时我们已经在用 Claude Code 做日常的代码生成和重构,但很快就撞上了一堵墙:同一个模型,同一个提示词,今天生成的代码能跑,明天生成的代码就漏了边界条件;让代理写测试,它写出来的测试全是“happy path”,稍微复杂一点的异常分支完全不覆盖。问题不在模型本身,而在于我们从来没有给代理定义过“什么叫把这件事做好”。
agent-skills要解决的就是这个问题。它本质上是一套面向 AI 编码代理的技能定义与组织规范,把“如何写测试”“如何做代码审查”“如何拆解需求”这类隐性经验,变成代理可以加载、可以复用、可以组合的显式技能模块。配合skills CLI这类命令行工具,你可以把技能安装到本地项目、在 Claude Code 里按需调用,也可以把团队沉淀的最佳实践打包成技能分发给所有人。
这套东西适合谁?如果你只是偶尔让 AI 帮你补个函数,那确实用不上;但如果你已经把 AI 编码代理接进了日常开发流程,每天要它处理几十个任务,那你迟早会遇到我上面说的那些问题。agent-skills加上test-driven-development这类成熟技能,就是让代理从“偶尔灵光一现”变成“稳定可预期输出”的关键一步。下面我把自己从零搭建这套体系的过程完整拆一遍,包括踩过的坑和最后跑通的配置。
2. 核心思路拆解:技能化到底解决了什么问题
2.1 代理能力不稳定的根源在哪里
大部分人用 AI 编码代理的方式是“一次性提示”:把需求描述丢进去,等结果,不满意就重新描述一遍。这种方式在简单任务上没问题,但任务一复杂,失败率就飙升。我统计过我们团队早期的使用记录,单文件、50 行以内的改动,一次通过率大概 70%;一旦涉及多文件、需要改测试、需要保持接口兼容,一次通过率直接掉到 20% 以下。
根本原因有三个。第一,上下文缺失:代理不知道这个项目的测试规范是什么、命名习惯是什么、哪些目录不能碰。第二,流程缺失:代理不知道“先写测试再写实现”还是“先写实现再补测试”,每次都在随机选择。第三,验收标准缺失:代理不知道什么叫做“完成”,它觉得代码能编译就算完成,但你觉得要测试全绿、lint 通过、覆盖率不降才算完成。
agent-skills的思路很直接:把这三样东西显式化。技能文件里写清楚这个技能适用的场景、执行的步骤、每一步的验收标准,代理加载技能后就相当于拿到了一份操作手册,而不是每次都靠猜。
2.2 为什么选择技能文件而不是超长提示词
有人会问,那我直接把所有这些规范写进系统提示词不就行了?我试过,结论是不行。系统提示词一旦超过一定长度,模型对其中每一条的注意力就会被稀释,而且不同任务需要的规范是不一样的——写测试和做重构需要的规范完全不同,全塞在一起只会互相干扰。
技能化的好处是按需加载。skills CLI支持把技能安装到项目的特定目录,Claude Code 在处理任务时会根据任务类型匹配相关技能。写测试的时候加载test-driven-development,做代码审查的时候加载审查技能,各管各的,互不干扰。这就像你给一个新员工培训,不会把公司所有岗位的 SOP 一次性塞给他,而是他做什么岗位就给他什么手册。
2.3 技能、CLI、代理三者的关系
这里要把三个概念理清楚,不然配置的时候很容易懵。代理是执行者,比如 Claude Code,它负责理解你的需求、调用工具、生成代码。技能是知识包,是一份份 Markdown 或结构化文件,描述“这类任务该怎么做”。skills CLI是搬运工和管家,负责把技能从仓库安装到本地、管理版本、在需要的时候提供给代理。
三者串起来的流程是:你用skills CLI把技能装到项目里,Claude Code 启动时读取可用技能列表,处理任务时匹配并加载对应技能,然后按照技能里定义的步骤执行。理解了这个链路,后面配置的时候每一步在干什么就清楚了。
3. 环境准备:把 skills CLI 和 Claude Code 装到位
3.1 安装 Claude Code 的几种方式和选择建议
Claude Code 的安装方式这几年变化挺大,我按平台分别说一下当前比较稳的路径。macOS 和 Ubuntu 上,官方推荐的方式是通过包管理器安装,这样后续升级最省心。macOS 用 Homebrew,Ubuntu 用官方的安装脚本,装完之后claude命令就能直接在终端调用。
Windows 用户如果不想折腾 WSL,可以用桌面版,但我要提醒一句:桌面版和命令行版在技能加载的行为上偶尔会有差异,如果你要跑agent-skills这套东西,我强烈建议用命令行版,行为最可预期。VS Code 用户可以直接装 Claude Code 的 VS Code 插件,插件本质上还是调用底层的命令行,但集成度更好,能在编辑器里直接看到代理的操作过程。
安装完之后第一件事是验证版本,claude --version能正常输出就说明装好了。这里有个坑:如果你之前装过旧版本,升级的时候一定要确认新版本真的生效了,我遇到过 PATH 里指向旧版本、新版本装了但没被调用的情况,排查了半天。
3.2 skills CLI 的安装与初始化
skills CLI的安装相对简单,它本身是一个命令行工具,装完之后在项目根目录执行初始化命令,它会生成一个技能配置目录。这个目录的结构很关键,我建议你一开始就规划好:
.agent-skills/ skills/ # 已安装的技能 config.json # 技能加载配置 cache/ # 技能缓存config.json里主要配置两件事:技能来源(从哪里拉取技能)和加载策略(哪些技能默认启用、哪些按需加载)。我的建议是默认只启用最基础的几个技能,其他全部设为按需加载,避免启动时加载一堆用不上的技能拖慢响应。
3.3 第三方模型接入的注意事项
很多人会想把 Claude Code 接到第三方模型上,比如通过 cc switch 这类工具接入 DeepSeek、Qwen、GLM 等。这里我要说清楚:agent-skills的技能定义本身是模型无关的,它描述的是流程和标准,不依赖特定模型。但不同模型对技能文件的遵循程度差别很大。
我的实测经验是,技能文件里的步骤越具体、验收标准越可量化,不同模型之间的表现差异就越小。比如“写测试要覆盖所有分支”这种模糊描述,弱一点的模型基本会忽略;但如果你写成“每个 if 分支至少一个测试用例,每个异常抛出点至少一个测试用例”,遵循度就高很多。所以如果你用的是第三方模型,技能文件要写得更“死”一点,少用模糊表述。
提示:接入第三方模型时,先拿一个简单技能做验证,确认模型能正确读取并遵循技能文件,再批量启用其他技能。不要一上来就全量启用,出了问题很难定位是哪个技能导致的。
4. 核心技能拆解:以 test-driven-development 为例
4.1 这个技能到底定义了什么
test-driven-development是我认为最值得第一个装的技能,因为它把 AI 编码代理最容易出问题的环节——测试——给规范住了。这个技能的核心定义是:代理在写任何实现代码之前,必须先写测试;测试必须先失败(红),再写实现让它通过(绿),最后重构。
听起来简单,但技能文件里要把每一步的细节都写清楚才有用。比如“先写测试”这一步,技能里会明确:测试文件放在哪个目录、命名规范是什么、用哪个测试框架、断言风格是什么。这些如果不写,代理就会按自己的习惯来,每个任务生成的测试风格都不一样,维护起来很痛苦。
4.2 技能文件的结构与关键字段
一个典型的技能文件包含几个部分:元信息(名称、版本、适用场景)、前置条件(需要哪些工具、哪些文件存在)、执行步骤(分步骤描述)、验收标准(怎么算完成)、示例(正例和反例)。我拿test-driven-development举例,它的执行步骤大概是这样组织的:
- 读取任务描述,识别需要修改的函数或模块
- 在测试目录下创建对应的测试文件
- 为每个待实现的行为写一个测试用例,确保测试能运行且失败
- 运行测试,确认失败信息符合预期
- 编写最小实现让测试通过
- 运行完整测试套件,确认没有破坏其他测试
- 重构实现,保持测试全绿
每一步都有对应的验收标准,比如第 3 步的验收标准是“测试文件能被测试框架识别,且至少有一个用例失败”。这种颗粒度才能让代理真正按流程走。
4.3 技能之间的组合与依赖
单个技能能力有限,真正强大的是技能组合。比如test-driven-development可以和代码审查技能组合:代理写完实现后,自动触发审查技能,检查代码是否符合项目规范。也可以和需求拆解技能组合:先把大需求拆成小任务,每个小任务走一遍 TDD 流程。
技能文件里可以声明依赖关系,skills CLI在加载时会自动把依赖的技能一起加载。这里要注意避免循环依赖,我踩过一次坑:A 技能依赖 B,B 又依赖 A,结果加载直接死循环。后来养成的习惯是,技能依赖尽量保持单向,基础技能不依赖上层技能。
5. 实操过程:从零跑通一个完整任务
5.1 项目初始化与技能安装
我拿一个真实的小项目来演示。假设有一个 Node.js 项目,需要给一个工具函数库添加一个新的日期格式化函数。第一步是初始化技能环境:
cd my-project skills init skills install test-driven-development skills install code-review安装完成后,.agent-skills/skills/目录下会出现对应的技能文件夹。每个技能文件夹里至少有一个SKILL.md文件,描述技能内容。你可以直接打开看,确认技能内容符合预期。
5.2 配置 Claude Code 加载技能
接下来配置 Claude Code 让它能读取这些技能。在项目根目录的 Claude Code 配置文件里,指定技能目录路径。配置完成后启动 Claude Code,它会自动扫描技能目录并加载可用技能。
验证技能是否加载成功的方法很简单:直接问代理“你现在有哪些可用技能”,它应该能列出你安装的技能名称。如果列不出来,说明配置路径有问题,检查一下配置文件的路径是不是写成了相对路径而代理的工作目录不对。
5.3 执行一个 TDD 任务的完整记录
现在给代理下任务:“给 utils 模块添加一个 formatDate 函数,接收 Date 对象和格式字符串,返回格式化后的日期字符串。”
代理加载test-driven-development技能后,执行过程大致如下。首先它在测试目录创建formatDate.test.js,写入几个测试用例:正常日期格式化、无效日期输入、格式字符串为空的情况。然后运行测试,确认全部失败(因为函数还不存在)。接着在 utils 模块里写最小实现,再次运行测试,逐步让测试通过。最后运行完整测试套件,确认没有影响其他测试。
整个过程我全程观察,最明显的感受是:代理的行为变得可预期了。以前它可能直接写实现,测试随便补两个;现在它严格按红绿重构的节奏走,测试覆盖也明显更全面。这个任务从下达到完成大概用了三分钟,生成的测试覆盖了 5 个用例,包括两个边界情况。
5.4 验收与人工复核要点
代理说“完成”不等于真的完成,人工复核这一步不能省。我通常检查三件事:测试是否真的覆盖了需求描述里的所有行为、实现是否有明显的性能或安全问题、代码风格是否符合项目规范。前两项靠读代码,第三项可以靠 lint 工具自动检查。
有一次代理生成的实现里用了一个已经废弃的 API,测试全绿但代码审查没通过。这提醒我:技能能规范流程,但不能替代人的判断。技能是给代理的护栏,不是给你自己的免责声明。
6. 常见问题与排查技巧实录
6.1 技能加载失败的排查路径
技能加载失败是最常见的问题,表现是代理说“没有可用技能”或者技能列表为空。排查顺序我总结成一张表:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 技能列表为空 | 配置路径错误 | 检查配置文件里的技能目录路径是否为绝对路径 |
| 部分技能缺失 | 安装未完成 | 重新执行 skills install,查看输出有无报错 |
| 技能加载报错 | 技能文件格式错误 | 检查 SKILL.md 的元信息字段是否完整 |
| 加载后不生效 | 加载策略配置问题 | 检查 config.json 里该技能是否被设为禁用 |
我遇到最多的是路径问题。skills CLI默认用相对路径,但 Claude Code 的工作目录可能和你执行命令的目录不一致,导致找不到技能。解决办法是在配置里统一用绝对路径,一劳永逸。
6.2 代理不遵循技能步骤怎么办
有时候技能加载成功了,但代理执行任务时还是按自己的方式来,不遵循技能里定义的步骤。这种情况通常是技能描述不够具体,或者任务描述和技能的适用场景不匹配。
我的处理办法是两步:先检查技能文件里的步骤描述是否足够具体,把模糊的动词换成可执行的动作;再检查任务描述里有没有明确要求使用某个技能。如果任务描述里没提,代理可能觉得这个技能不适用。你可以在任务开头加一句“请使用 test-driven-development 技能完成这个任务”,强制它走流程。
6.3 第三方模型下的兼容性问题
用第三方模型接入时,技能遵循度普遍比原生模型低。我实测下来,DeepSeek 和 Qwen 对结构化技能文件的遵循度还不错,但需要把步骤写得更细。GLM 在长技能文件上的表现稍弱,建议把大技能拆成小技能,减少单次加载的内容量。
还有一个坑是模型对技能文件里示例的理解。原生模型能从一两个示例里推断出模式,第三方模型往往需要更多示例才能理解。所以如果你用第三方模型,技能文件里的正例反例要多写几个,别省这点篇幅。
6.4 技能版本管理与团队协作
团队协作时,技能文件的版本管理很重要。我们团队的做法是把技能文件放在独立的 Git 仓库里,项目通过skills CLI引用特定版本。这样技能更新不会影响正在开发的项目,需要升级时手动切换版本。
另外,技能文件也要走代码审查。我见过有人把技能文件当成个人配置文件随便改,结果改出了一个有问题的步骤,导致整个团队的代理行为都异常。技能文件是团队资产,改动要经过审查,这个规矩要一开始就立好。
7. 我踩过的坑和几条实用建议
第一个坑是技能装太多。刚开始我觉得技能越多越好,一口气装了十几个,结果代理启动变慢,而且技能之间偶尔会冲突——两个技能对同一个步骤给出不同要求,代理就懵了。后来精简到五个核心技能,反而效果更好。技能不在多,在于每个都真正用得上。
第二个坑是技能文件写得太抽象。我早期写的技能文件里全是“确保代码质量”“遵循最佳实践”这种话,代理看了等于没看。后来改成“每个函数必须有对应的单元测试”“所有异步操作必须有错误处理”,遵循度立刻上来了。写技能文件的原则是:能写成检查项的就别写成形容词。
第三个坑是忽略技能的维护。技能不是装完就不管了,项目在演进,技能也要跟着更新。我们现在的做法是每个季度回顾一次技能文件,把过时的步骤删掉,把新踩的坑补进去。技能文件是活的文档,不是一次性配置。
最后分享一个提高技能遵循度的小技巧:在技能文件的验收标准里加入可自动检查的项。比如“测试覆盖率不低于 80%”这种,代理可以自己跑覆盖率工具验证;“lint 无错误”这种,代理可以自己跑 lint。可自动验证的标准,代理的遵循度远高于需要主观判断的标准。这个技巧是我试了很多次才总结出来的,效果立竿见影。