
1. 从 agent-skills 说起为什么它值得单独拿出来聊第一次看到agent-skills这个项目名的时候我下意识以为又是一个把提示词打包成 JSON 的小工具。真正翻完仓库结构、跑通几个 skill 之后才发现它想解决的问题比提示词管理要底层得多——它试图给 AI coding agents 建立一套可复用、可组合、可测试的能力单元。说白了现在用 Claude Code、Cursor、Copilot 这类工具的人越来越多但绝大多数人的用法还停留在打开对话框把需求敲进去等它吐代码。这种用法在单次任务里没问题可一旦你每天都要重复写测试→跑测试→改代码→再跑测试这套流程或者团队里五个人各写各的提示词质量参差不齐问题就暴露了。agent-skills的核心主张是把那些高频、稳定、有明确输入输出的操作抽象成独立的 skill让 agent 按需调用而不是每次靠人现场描述。这个思路和test-driven-development这个热搜词高度契合。TDD 本身就是一套先写测试、再写实现、循环验证的固定流程天然适合被封装成 skill。你不需要每次都跟 agent 解释先别写实现先给我写测试用例而是直接触发一个tddskill它内部已经固化了这套纪律。适合谁来读这篇三类人。第一类是把 Claude Code 当日常主力工具、想从会用进阶到用得好的开发者第二类是团队里负责搭建 AI 辅助开发规范的技术负责人第三类是对skills CLI这类工具链好奇、想搞清楚 agent 能力抽象到底怎么落地的人。如果你只是偶尔让 AI 帮你补个函数这篇可能有点重但如果你每天有大量编码任务要交给 agent那这套东西值得花时间吃透。我下面会从设计思路、核心机制、实操流程、踩坑经验四个层面拆开讲尽量把为什么这么设计讲清楚而不是只丢一堆命令让你抄。2. agent-skills 的整体设计与思路拆解2.1 核心命题把临时对话变成可调用能力传统用 AI coding agent 的方式本质是无状态对话。你打开一个新会话agent 对你的项目结构、编码规范、测试习惯一无所知全靠你在提示词里现补。这就导致两个问题一是重复劳动同样的上下文每次都要重新喂二是不可控同一个需求换个说法agent 的输出质量可能天差地别。agent-skills的设计出发点就是把这个过程结构化。一个 skill 本质上是一个目录里面包含一份描述文件通常声明这个 skill 叫什么、什么时候该用、需要哪些输入具体的执行逻辑可能是提示词模板也可能是脚本甚至是一段可执行代码可选的测试用例用来验证这个 skill 在给定输入下是否产出预期结果这种结构和软件工程里的函数概念几乎一模一样。函数有签名、有实现、有单元测试skill 有描述、有逻辑、有验证。区别在于函数的调用者是程序skill 的调用者是 AI agent。这里有个关键认知skill 不是给机器执行的死代码而是给 agent 看的能力说明书。agent 读到 skill 的描述后自己决定要不要调用、怎么调用。所以描述文件写得好不好直接决定 skill 能不能被正确触发。2.2 为什么选择技能而不是插件或工作流市面上其实已经有几种类似思路。插件plugin偏向扩展工具本身的功能工作流workflow偏向把多个步骤串成固定流水线。agent-skills选择技能这个粒度我认为是权衡后的结果。插件的粒度太粗一个插件往往绑定特定平台换个 agent 就用不了。工作流的粒度又太死一旦流程里某一步需要 agent 临场判断整个流水线就卡住了。技能刚好卡在中间它比插件轻不依赖特定运行时又比工作流灵活允许 agent 在 skill 内部做决策。举个具体例子。假设你要实现给现有函数补单元测试这个需求。做成插件你得针对 Claude Code 写一套、针对别的工具再写一套。做成工作流你得规定死先读函数→再分析分支→再生成用例→再运行验证中间任何一步 agent 想调整都不行。做成 skill你只需要描述输入是一个函数输出是覆盖主要分支的测试用例优先用项目已有的测试框架剩下的交给 agent 判断。2.3 与 test-driven-development 的天然契合TDD 之所以特别适合做成 skill是因为它有一套明确的纪律红写一个失败的测试→ 绿写最少的代码让测试通过→ 重构在测试保护下优化代码。这套纪律对人类开发者来说是习惯对 agent 来说却需要反复强调否则它总想一步到位把实现和测试一起写完。把 TDD 封装成 skill 之后你可以在 skill 描述里硬性规定每次只允许推进一个红绿循环agent 调用这个 skill 时就会遵守这个约束。这比你在对话里反复叮嘱先写测试要可靠得多因为约束被固化在了能力定义里而不是依赖每次对话的临场发挥。2.4 方案选型的几个取舍在搭建自己的 skill 体系时有几个决策点绕不开我把自己踩过的坑和最终选择列出来供参考。决策点选项 A选项 B我的选择与理由skill 粒度一个 skill 干一件事一个 skill 干一类事选 A。粒度越细越容易被正确触发组合也更灵活逻辑载体纯提示词提示词脚本视情况。需要确定性输出的用脚本需要判断的用提示词测试方式人工验证自动化断言尽量自动化。skill 多了以后人工根本测不过来版本管理跟主仓库混在一起独立仓库独立仓库。skill 迭代频率和业务代码完全不同这些取舍没有绝对对错但如果你打算长期维护一套 skill粒度细、可测试、独立管理这三条基本是共识。3. 核心机制解析与实操要点3.1 skill 的目录结构与描述文件一个标准的 skill 目录大概长这样skills/ tdd/ SKILL.md # 描述文件agent 读这个决定是否调用 prompt.md # 具体的提示词模板 scripts/ run_tests.sh # 可选的辅助脚本 tests/ case_01.md # 可选的验证用例SKILL.md是整个 skill 的门面也是最需要花心思的部分。它通常包含几个关键字段名称、触发条件、输入说明、输出说明、约束条件。我见过很多人把这里写成一段散文结果 agent 根本抓不住重点。正确的写法是结构化、短句、动词开头。比如一个tddskill 的描述可以这样写# Skill: tdd ## 何时使用 当用户要求为某个函数或模块补充测试或要求按测试驱动方式实现新功能时。 ## 输入 - 目标文件路径或函数名 - 项目使用的测试框架若未指定则自动探测 ## 输出 - 一个失败的测试用例红 - 让该测试通过的最小实现绿 - 重构建议可选 ## 约束 - 每次只推进一个红绿循环 - 不得在测试未通过前编写额外实现 - 测试用例必须覆盖至少一个边界条件这份描述里约束部分是最容易被忽略但最重要的。agent 的行为边界基本靠这里划定写清楚了它就不会乱来。3.2 skills CLI 的安装与基本用法skills CLI是管理这些 skill 的命令行工具负责安装、列出、更新、删除 skill。安装方式通常是通过包管理器具体命令取决于你的环境。装好之后几个高频命令值得记住# 列出当前已安装的所有 skill skills list # 从仓库安装一个 skill skills install tdd # 查看某个 skill 的详细信息 skills info tdd # 更新所有 skill 到最新版本 skills update # 移除某个 skill skills remove tdd这里有个实操细节skills install默认会装到全局目录但如果你希望 skill 跟着项目走比如团队共享需要指定本地目录。我一般建议项目相关的 skill 装本地通用的装全局这样换项目时不会互相干扰。注意不同版本的 CLI 命令参数可能有差异装之前先跑skills --help确认一下别照着旧文档硬套。3.3 skill 的触发机制agent 怎么知道该用哪个这是很多人困惑的地方——我装了一堆 skillagent 怎么知道什么时候该调用哪个答案在于描述匹配。当你的请求进来时agent 会扫描所有已安装 skill 的描述文件找出触发条件匹配的那个。这就带来一个直接后果描述写得越模糊越容易被误触发或漏触发。我踩过的坑是给一个 skill 写了用于处理代码相关任务这种万能描述结果它几乎在所有场景下都被触发反而干扰了正常判断。后来改成当用户明确要求重构且不改变外部行为时使用误触发率立刻降下来了。另一个技巧是给 skill 加否定条件。比如某个 skill 只在不涉及数据库操作时使用就把这条写进描述里。agent 读到否定条件后会在不满足时主动跳过。3.4 把 TDD 流程拆成可调用的 skill 链单靠一个tddskill 其实还不够因为完整的 TDD 循环涉及多个动作。我的做法是拆成一条 skill 链analyze-target分析目标函数识别分支和边界write-failing-test生成一个必然失败的测试run-test执行测试确认它确实失败minimal-impl写最少代码让测试通过refactor-check检查是否有可重构点每个 skill 只干一件事agent 按顺序调用。这样做的好处是每一步都可验证——如果第 3 步发现测试居然通过了说明第 2 步生成的测试有问题能立刻定位。如果把它们揉成一个 skill出问题时你根本不知道是哪一环坏了。3.5 实操要点与常见禁忌几个我反复验证过的要点描述文件用英文写。不是崇洋媚外而是实测下来 agent 对英文描述的解析准确率更高尤其是涉及技术术语时。每个 skill 只解决一个明确问题。贪多必失一个 skill 塞三个功能最后三个都用不好。给 skill 配测试用例。哪怕只是几个手写的输入输出对也能在你改描述时快速回归验证。不要硬编码项目路径。skill 应该通过参数接收路径而不是写死否则换个项目就废了。禁忌方面最要命的是在 skill 里写死具体业务逻辑。skill 应该是通用的能力单元一旦掺进某个项目的业务规则它就失去了复用价值还不如直接写在提示词里。4. 完整实操流程从零搭一套 TDD skill4.1 环境准备与 CLI 初始化假设你在 Ubuntu 或 macOS 上已经装好了 Claude Code 或类似的 agent 工具。第一步是装skills CLI。具体命令因包管理器而异装完后先验证skills --version如果提示命令找不到检查一下 PATH 是否包含 CLI 的安装目录。这一步看着简单但我见过不少人卡在这里以为是 CLI 没装好其实是 shell 没重新加载配置。接着初始化一个 skill 工作目录mkdir -p ~/agent-skills-workspace cd ~/agent-skills-workspace skills initskills init会生成一个基础目录结构和一份示例 skill你可以照着它改。4.2 编写第一个 skillwrite-failing-test我们从这个 skill 开始因为它是 TDD 循环的起点。先建目录skills create write-failing-test然后编辑生成的SKILL.md# Skill: write-failing-test ## 何时使用 当需要为指定函数生成一个当前必然失败的测试用例时。 ## 输入 - target: 目标函数的文件路径和函数名 - framework: 测试框架可选默认自动探测 ## 输出 - 一个测试文件或测试函数运行后应当失败 ## 约束 - 测试必须针对目标函数的真实行为不得 mock 掉被测逻辑 - 必须包含至少一个边界条件用例 - 不得同时生成实现代码写完描述后在prompt.md里放具体的提示词模板。这里的关键是把变量用占位符标出来agent 调用时会自动替换请为以下目标生成一个失败的测试 目标{{target}} 框架{{framework}} 要求 1. 测试应当调用目标函数并断言其行为 2. 当前实现下该测试必须失败 3. 覆盖至少一个边界输入 4. 只输出测试代码不要输出实现4.3 参数计算与选择过程这里有个容易被忽略的细节边界条件怎么选。不是随便挑一个极端值就行得根据函数的输入类型来定。我一般按这个顺序过一遍数值型输入取 0、负数、最大值、最小值字符串输入取空串、超长串、含特殊字符的串集合输入取空集合、单元素、大量元素可选参数取未传、传 null、传有效值举个具体例子。假设目标函数是divide(a, b)边界条件至少要考虑b 0的情况。如果 skill 生成的测试里没有覆盖除零那这个测试就是不完整的。我在prompt.md里会明确要求 agent针对每个数值参数至少考虑零值和负值实测下来覆盖率明显提升。4.4 运行验证与红绿循环skill 写好后实际跑一遍。假设目标是一个简单的add(a, b)函数skills run write-failing-test --target src/math.js:add --framework jestagent 会生成一个测试文件。接着手动或自动运行npx jest src/math.test.js预期结果是测试失败。如果它居然通过了说明生成的测试没有真正验证行为需要回头改 skill 的描述。确认失败后再调用minimal-implskill 生成最小实现再跑一次这次应该通过。这就是一个完整的红绿循环。提示每次循环结束后把成功的输入输出对存进 skill 的tests/目录作为回归用例。skill 迭代时先跑这些用例能快速发现描述改动是否引入了退化。4.5 把 skill 接入 Claude Code 工作流skill 本身是独立的要让它真正在 Claude Code 里生效需要配置 agent 去读取 skill 目录。具体方式取决于你用的工具版本通常是在项目根目录放一个配置文件声明 skill 的搜索路径。配置好之后你在 Claude Code 里提出帮我给这个函数补测试agent 就会自动匹配到write-failing-testskill 并调用。如果没触发八成是描述文件的触发条件写得太窄回去放宽一点。我实测下来接入后最大的变化是输出稳定性。以前同样的需求agent 有时写测试有时直接写实现现在基本都会先走测试这一步因为 skill 的约束把它框住了。5. 常见问题与排查技巧实录5.1 skill 不被触发怎么办这是最高频的问题。排查顺序我一般这样走现象可能原因排查方法完全不触发描述文件路径不对检查 CLI 的 skill 搜索路径配置偶尔触发触发条件太窄放宽描述里的何时使用频繁误触发描述太宽泛加否定条件收窄适用范围触发了但报错输入参数缺失检查调用时是否传了必填参数大部分不触发其实是路径问题。CLI 默认只扫描特定目录你把 skill 放在别处它当然找不到。先跑skills list确认 skill 是否被识别识别不到就是路径问题识别到了但不触发才是描述问题。5.2 生成的测试质量不稳定这个问题的根源通常在提示词模板。如果模板里对测试的要求写得含糊agent 每次的理解就会有偏差。我的做法是把要求拆成可勾选的清单每条都具体到能判断真假测试函数名是否描述了被测行为是否至少有一个断言是否覆盖了边界条件是否没有 mock 被测逻辑本身清单越具体输出越稳定。另外给几个正例和反例放进模板里效果比纯文字描述好得多。5.3 skill 之间的依赖与冲突当你装了十几个 skill 后可能会遇到两个 skill 都想处理同一个请求的情况。这时候 agent 的决策依据是描述的匹配度匹配度接近时就会摇摆。解决办法是给 skill 划分清晰的职责边界。比如write-failing-test只负责生成测试minimal-impl只负责生成实现两者不重叠。如果发现两个 skill 职责有交叉果断合并或重新拆分别让它们互相抢活。5.4 版本升级后的兼容问题skills CLI和 agent 工具本身都在快速迭代升级后 skill 描述格式或调用方式可能变化。我的经验是升级前先备份 skill 目录升级后跑一遍回归用例确认没问题再继续用。如果发现某个字段不再被识别对照官方文档改一下通常就能解决。注意不要盲目追新版本。如果当前版本跑得好好的没有你需要的特性没必要为了升级而升级。我吃过一次亏升级后一个关键 skill 的触发逻辑变了排查了大半天。5.5 独家避坑技巧汇总几条用血泪换来的经验skill 描述里的动词要具体。处理、优化这种词太虚换成生成、校验、替换这类明确的动作。给每个 skill 写一句反例说明告诉 agent 什么情况下不该用它。这比只写正向条件有效得多。定期清理不用的 skill。装太多会拖慢 agent 的匹配速度也会增加误触发概率。skill 的测试用例要跟着描述一起改。改了描述不更新用例回归测试就形同虚设。团队共享 skill 时用 Git 管理别靠手动拷贝。版本对不齐是团队协作里最常见的坑。6. 把 skill 体系用起来的几点个人体会搭这套东西的过程中我最大的感受是skill 的价值不在于省了多少打字而在于把隐性经验显性化。以前团队里那个写测试特别规范的同事他的习惯只存在于他脑子里现在把这些习惯固化成 skill所有人都能调用同一套标准。另一个体会是别追求一步到位。我一开始想设计一套覆盖所有场景的 skill 体系结果搞了两周发现根本用不起来因为太复杂了。后来改成先解决一个最痛的点从 TDD 这一个流程切入跑顺了再扩展反而推进得更快。如果你现在就想动手我的建议是从你每天重复次数最多的那个操作开始把它做成第一个 skill。不用管它完不完美先跑通一个完整循环你对这套机制的理解会比看十篇文档都深。等第一个 skill 稳定了第二个、第三个自然就有感觉了。