
1. 从agent-skills这个标题说起它到底在解决什么问题第一次看到agent-skills这个仓库名我脑子里冒出来的第一个念头是这又是一个把提示词打包成文件夹的项目吗翻了一圈之后发现它想做的事情比提示词合集要实在得多——它试图给 AI coding agent 定义一套可复用、可组合、可测试的能力单元也就是所谓的 skill。先把概念说清楚。这里的 skill 不是模型权重里的能力而是外挂给 agent 的一套操作手册 工具封装 验收标准。你可以把它理解成给一个刚入职的实习生发的岗位 SOP告诉他这类任务该按什么顺序做、用哪些命令、做到什么程度算合格。agent-skills这个项目就是把这些 SOP 标准化让不同的 agentClaude Code、各类 CLI agent、IDE 里的编码助手都能加载同一套技能定义。为什么这件事值得单独做一个项目因为现在大多数人用 AI coding agent 的方式还停留在聊天框里许愿的阶段。你说一句帮我加个登录功能agent 就开始自由发挥写出来的东西能不能跑、边界情况处理没有、测试覆盖了没有全靠运气。而 skill 化的思路是把许愿变成派活任务有明确的输入输出、有固定的执行流程、有可验证的完成标准。关键词里出现的test-driven-development其实透露了这个项目的核心取向——它把 TDD 当作一种 skill 来对待。这很关键。TDD 不是一个建议你这么做的软性规范而是一套有严格节奏的流程先写失败的测试、再写最小实现让它通过、最后重构。这套节奏非常适合被固化成一个 skill因为它的每一步都有明确的判定条件agent 不需要理解意图只需要执行流程并检查断言。所以agent-skills的定位可以概括成三句话它是 agent 能力的模块化封装方案它用 CLI 的方式做技能的安装、加载和管理它把 TDD 这类工程实践变成了 agent 可以直接执行的流程而不是停留在文档里的口号。适合谁来研究如果你已经在用 Claude Code 或者类似的编码 agent但总觉得输出质量不稳定、每次都要重复交代同样的规矩那这个项目值得你花时间拆一拆。2. skills CLI 的设计逻辑为什么是命令行而不是配置文件2.1 技能分发为什么绕不开一个 CLI很多人第一反应是技能不就是几个 markdown 文件吗我手动拷到目录里不就行了为什么要搞个 CLI我一开始也这么想直到我同时维护三四个项目、每个项目用的 agent 不一样、技能版本还各不相同的时候才发现手动拷贝是灾难。skills CLI存在的第一个理由是版本一致性。技能定义会迭代今天你写的代码审查 skill要求检查五个点下周可能变成七个点。如果靠手动拷贝你根本不知道某个项目里用的是哪个版本。CLI 通过一个清单文件锁定版本跟package.json锁定依赖是一个道理。第二个理由是跨 agent 的可移植性。不同 agent 加载技能的目录约定、文件格式、元数据字段可能都不一样。CLI 充当了适配层你写一份技能定义CLI 负责把它转换成目标 agent 能识别的形式。这跟构建工具把同一份源码编译成不同平台产物是一个思路。第三个理由比较隐蔽但很重要可发现性。当技能多起来之后我到底装了哪些技能、每个技能干什么用会变成一个真问题。CLI 提供的list、info这类子命令本质上是在做技能的索引和检索。没有这层技能库就会退化成一堆没人记得住的文件夹。2.2 一个技能单元应该包含哪些部分基于我对这类项目的理解一个完整的 skill 通常由四块内容组成缺一块都会影响可用性组成部分作用缺失后的后果元数据名称、版本、适用场景、依赖agent 无法判断何时该调用它触发条件什么情况下激活这个技能技能要么从不触发要么乱触发执行步骤具体的操作流程和工具调用agent 只能瞎猜怎么做验收标准怎么判断任务完成了输出质量无法保证这里我要特别强调触发条件。这是最容易被忽略、但最影响体验的部分。一个技能如果触发条件写得太宽比如只要涉及代码就激活那它会污染所有对话写得太窄比如要求精确匹配某个文件名那它基本不会被用到。好的触发条件应该描述的是任务类型而不是关键词比如当用户要求为已有函数补充测试时就比当消息里出现 test 时要准确得多。2.3 技能之间的组合与依赖单个技能能解决的问题有限真正有价值的是技能的组合。比如写测试和重构这两个技能在 TDD 流程里是交替使用的写测试 → 实现 → 重构 → 再写测试。如果技能之间不能组合那 agent 每次只能执行一个孤立的动作流程就断了。agent-skills这类项目通常会在元数据里声明依赖关系让 CLI 在安装时自动拉取前置技能。这跟包管理器的依赖解析是一回事。我在实际使用中踩过的一个坑是循环依赖。技能 A 依赖 BB 又依赖 A安装时直接死循环。所以设计技能时一定要保证依赖是有向无环的把公共部分抽成独立的原子技能。提示设计技能依赖时先画出依赖图再动手写。我见过太多人凭感觉写依赖最后装都装不上。3. 把 TDD 做成 skill流程固化的关键细节3.1 为什么 TDD 特别适合被 skill 化前面提到 TDD 有严格的节奏这里展开说说为什么这个特性让它成为 skill 化的理想对象。TDD 的核心循环是红-绿-重构先写一个会失败的测试红然后写刚好能让它通过的最少代码绿最后在不改变行为的前提下清理代码重构。这个循环的每一步都有客观的判定条件——测试失败就是失败通过就是通过没有模糊地带。这跟帮我优化一下这段代码这种主观任务完全不同。正因为判定条件客观agent 执行 TDD skill 时不需要理解什么叫优化好了它只需要运行测试、看结果、决定下一步。这大幅降低了 agent 出错的概率也让整个流程可以被自动化验证。3.2 一个 TDD skill 的执行步骤拆解我把这类 skill 的典型执行流程拆成下面几步每一步都对应 agent 的一个明确动作解析需求确定测试目标agent 先要搞清楚要测什么行为。这一步的产出是一句话描述的行为规格比如当输入为空时函数应返回空数组。编写失败测试根据行为规格写出测试代码然后运行确认它确实失败。这一步不能跳过——如果测试一上来就通过说明要么测试写错了要么功能已经存在。编写最小实现只写让测试通过所需的代码不多写一行。这是 TDD 最反直觉的地方很多人忍不住顺手把其他情况也处理了结果破坏了节奏。运行测试确认通过全绿之后才能进入下一步。重构在测试保护下清理代码每次重构后都要重新运行测试。循环回到第 1 步处理下一个行为。这里第 2 步和第 3 步的顺序是绝对不能颠倒的。我见过有人为了效率先写实现再补测试结果测试变成了对实现的描述而不是对需求的描述完全失去了 TDD 的意义。3.3 让 agent 真正先写测试的难点说起来简单让 agent 老老实实先写测试其实很难。原因是训练数据里绝大多数代码都是实现在前、测试在后的agent 有很强的惯性直接开始写实现。解决这个问题的办法是在 skill 里加入强制检查点。比如要求 agent 在写任何实现代码之前必须先输出测试文件的内容并运行一次把失败输出贴出来。如果 agent 跳过了这一步直接写实现skill 的验收标准就会判定失败。另一个技巧是把写测试和写实现拆成两个独立的技能中间用一个确认测试失败的技能隔开。这样 agent 在流程上就没法绕过测试环节了。这种拆分看起来啰嗦但实测下来对约束 agent 行为非常有效。注意不要指望一次就把 TDD skill 调好。我前几次写的 skillagent 总能找到各种理由跳过测试步骤后来是靠不断加检查点才收敛的。4. 在 Claude Code 里落地 agent-skills 的实操路径4.1 环境准备阶段容易忽略的几件事在 Claude Code 里使用技能第一步是把技能放到它约定的目录下。不同版本的目录约定可能不同所以先确认你当前版本的加载路径别照着旧教程一顿操作最后发现根本没加载。我建议的准备顺序是这样的先确认 Claude Code 的版本用claude --version之类的命令查看版本不同加载机制可能有差异。找到技能目录的约定位置通常在用户配置目录下的一个固定子目录里。先用一个最简单的技能做加载测试确认能被识别再批量导入。检查技能的元数据格式是否符合当前版本要求字段名大小写、必填项这些细节最容易出错。这里有个很实际的坑技能文件编码和换行符。如果你在 Windows 上编辑技能文件然后拿到 Linux 环境用CRLF 换行符有时会导致解析异常。统一用 LF 能省掉很多莫名其妙的报错。4.2 技能加载后的验证方法技能装上了不代表能用。我习惯用三步验证法第一步用list类命令确认技能出现在列表里且状态是启用。第二步构造一个明确应该触发该技能的任务观察 agent 是否真的调用了它。第三步检查 agent 的执行过程是否符合技能定义的步骤而不是看起来完成了任务但流程全错。第三步最容易被忽略。很多时候 agent 确实把任务做完了但它是用自己的方式做的根本没走你的 skill。这种情况下你以为 skill 生效了其实只是运气好。要确认 skill 真的被使用得看 agent 的执行日志里有没有引用技能定义。4.3 和现有工作流的衔接技能不是孤立存在的它要嵌进你现有的开发流程。我的做法是把技能分成两类流程类技能比如 TDD、代码审查和工具类技能比如特定的构建、部署命令封装。流程类技能在对话开始时激活工具类技能在需要时按需调用。衔接时要注意优先级冲突。如果你同时装了多个技能它们的触发条件可能重叠agent 不知道该听谁的。解决办法是在元数据里明确优先级或者干脆把重叠的技能合并。我倾向于后者因为优先级规则一多维护成本就上去了。5. 技能设计中的常见坑与排查链路5.1 技能不触发从现象到根因的排查技能装了但从来不触发这是最高频的问题。我的排查顺序是这样的先看触发条件是否过于具体。很多人写触发条件时喜欢堆关键词结果 agent 的输入只要措辞稍有不同就匹配不上。把触发条件从关键词匹配改成意图描述通常能解决大半问题。再看元数据字段是否被正确解析。有时候是字段名写错了CLI 静默忽略了整个技能。这种情况要靠查看加载日志来发现光看列表是看不出来的。最后看技能之间是否互相屏蔽。如果两个技能的触发范围重叠可能一个把另一个盖住了。临时禁用其他技能只留一个测试能快速定位。5.2 技能触发了但执行走样比不触发更麻烦的是触发了但执行不对。典型表现是 agent 跳过了技能里的某些步骤或者顺序乱了。根因通常是步骤描述不够强制。如果你写的是建议先写测试agent 就可能不写写成必须先写测试并运行确认失败否则不得进入下一步约束力就强很多。措辞的强制性直接影响 agent 的遵守程度这一点我在反复调试中体会很深。另一个原因是步骤之间存在歧义。比如处理边界情况这种描述agent 根本不知道具体指哪些情况。把每一步都写成可执行、可验证的动作是避免走样的根本办法。5.3 技能版本升级后的兼容问题技能会迭代升级之后老项目可能出问题。我踩过的坑是新版本技能改了元数据格式老项目里锁定的旧版本加载器解析不了直接报错。应对办法是给技能做语义化版本并且在项目里锁定版本号跟锁依赖一个道理。升级时先在测试项目里验证确认没问题再推到主项目。别图省事直接全局升级出问题的时候回滚很麻烦。问题现象可能根因排查动作技能不触发触发条件过窄改为意图描述放宽匹配技能不触发元数据解析失败查看加载日志核对字段名执行走样步骤描述不强制改用必须/否则句式执行走样步骤有歧义拆成可验证的原子动作升级后报错版本不兼容锁定版本测试环境先验证6. 把技能库当成长期资产来经营用了一段时间之后我意识到技能库不是一次性配置而是需要持续经营的资产。几个我总结出来的经验保持技能的原子性。一个技能只做一件事做透。我早期喜欢写大而全的技能一个技能包揽从需求分析到部署的全流程结果就是任何一个环节出问题都要改整个技能牵一发动全身。拆成原子技能后复用率和可维护性都上来了。给技能写测试。听起来有点绕——给约束 agent 的技能写测试。但这是可行的构造一批典型输入检查 agent 是否按预期触发了技能、是否走完了流程。技能本身的质量也需要被验证否则你永远不知道它是不是在假装工作。定期清理。技能库会积累有些技能随着项目变化已经没用了有些被新技能取代了。定期过一遍把废弃的删掉能减少触发冲突也让 agent 的选择更清晰。记录踩坑。每个技能旁边记一句为什么这么写比如这里必须加检查点否则 agent 会跳过测试。这些注释在几个月后你自己回头看的时候价值巨大。最后分享一个我个人的小习惯每次 agent 执行技能出了意外我都会问自己一句是技能没写清楚还是 agent 能力不够。大部分时候答案是前者。技能设计的本质是把模糊的期望翻译成精确的指令这件事没有终点只有不断逼近。