
1. 从agent-skills这个标题能读出什么第一次看到agent-skills这个仓库名我的直觉是这不是又一个提示词大全而是一套把 AI coding agent 当新同事来培养的技能体系。项目正文和关键词都是空的但热搜词已经把方向交代得很清楚了——AI coding agents、skills CLI、Claude Code、test-driven-development。把这几个词串起来它想解决的问题其实很具体当 AI 已经能写代码、能跑终端命令之后怎么让它稳定地按一套工程规范干活而不是每次都要人重新交代一遍。大多数人用 AI 编程工具的方式是对话式的打开对话框描述需求等它吐代码不满意就再补一句。这种方式在一次性脚本上够用但一旦进入真实项目——有测试、有 lint、有目录约定、有提交规范——就会立刻暴露问题。你会发现同一个 agent 上午写的代码符合规范下午就忘了你昨天纠正过的错误今天它又犯一遍。agent-skills这类项目的价值就是把这些口头交代沉淀成 agent 可以反复加载的技能文件让规范变成资产而不是记忆。这篇文章适合三类人看一是已经在用 Claude Code 或类似 AI coding agent、但总觉得它不够听话的开发者二是想给团队搭一套 AI 协作规范的技术负责人三是刚接触skills CLI这类概念、想知道它到底和普通提示词有什么区别的入门者。我会从技能的本质讲起拆解目录结构、加载机制、和 TDD 的结合方式再给出一套可以直接抄的落地流程最后聊聊我在实际使用中踩过的坑。需要先说明一点agent-skills的具体实现细节在公开信息里并不完整下面涉及目录结构、CLI 命令、加载优先级的部分是基于这类技能系统在工程实践中的常见做法做的合理补全你可以把它当作一套可迁移的方法论而不是某个版本的逐字文档。2. 技能不是提示词agent-skills 到底在解决什么问题2.1 提示词是一次性的技能是可复用的先把概念掰开。提示词prompt是你当下对 agent 说的一段话它的生命周期通常就是这一次对话。对话结束上下文清空你说过的话就没了。技能skill不一样它是一个持久化的文件放在项目里agent 在需要的时候主动加载它。这个区别看起来小实际影响巨大。打个比方提示词像是你临时给新同事口头交代这个函数记得加错误处理技能像是你写了一份《本项目错误处理规范》放进团队 wiki新同事入职第一天就会读。前者依赖你每次都在场后者是一次投入、长期生效。agent-skills的核心主张就是把开发者反复交代的那些事从口头变成文档从记忆变成资产。这里有个反直觉的点技能写得越具体agent 的执行越稳定写得越抽象越容易被忽略。我见过太多人写技能时喜欢写请遵循最佳实践注意代码质量这种话结果 agent 完全无感。真正有效的技能是所有对外函数必须返回ResultT, E错误类型定义在src/errors.rs这种能直接映射到代码的规则。2.2 为什么是现在AI coding agent 的能力边界变了两三年前AI 编程助手还停留在补全一行代码的阶段你根本不需要给它讲项目规范因为它只负责你光标附近那几行。但现在不一样了。以 Claude Code 为代表的 agent 已经能读整个仓库、能执行终端命令、能跑测试、能改多个文件。能力越大越需要约束。一个能跑npm test的 agent如果不知道你的测试约定它可能会写出跑不通的测试一个能执行git commit的 agent如果不知道你的提交信息规范它会生成一堆fix bug这样的垃圾提交。agent-skills出现的时机正好卡在agent 能力已经够强、但工程约束还没跟上这个窗口期。它要做的不是提升 agent 的智商而是给它装上职业素养。2.3 skills CLI把技能管理变成工程流程热搜词里出现了skills CLI这说明技能不是靠手动复制文件来管理的而是有一套命令行工具。这类 CLI 通常承担几件事初始化技能目录、从模板生成技能骨架、校验技能文件格式、列出当前项目已加载的技能。为什么需要 CLI 而不是纯手动因为技能一旦多了手动管理会失控——你不知道哪个技能生效了、哪个被覆盖了、哪个格式写错了。我个人的经验是技能管理最怕的不是写不出来而是写重复了、写冲突了。两个技能都规定函数命名用驼峰但一个说私有函数加下划线前缀另一个说不加agent 加载时就会犯迷糊。CLI 的价值就在于能帮你发现这类冲突让技能库保持干净。这一点和依赖管理是一个道理小项目手动管依赖没问题项目一大就必须上包管理器。3. 拆解 agent-skills 的目录结构与加载机制3.1 一个典型技能仓库长什么样基于这类系统的常见设计agent-skills的目录结构大概率是这样组织的agent-skills/ ├── skills/ │ ├── test-driven-development/ │ │ ├── SKILL.md │ │ └── examples/ │ ├── code-review/ │ │ ├── SKILL.md │ │ └── checklist.md │ └── commit-convention/ │ └── SKILL.md ├── skills.config.json └── README.md每个技能是一个独立目录核心是SKILL.md这个文件。为什么用 Markdown 而不是 JSON 或 YAML因为技能的内容本质上是给 agent 看的自然语言指令Markdown 既能写结构化规则又能写解释性说明还能嵌代码示例是表达力最合适的格式。JSON 适合配置不适合表达什么时候该用这个技能这种带语境的判断。skills.config.json则是全局配置通常记录技能的启用状态、加载优先级、适用路径范围。比如你可以配置test-driven-development技能只在src/目录下的改动中生效避免它在改文档时也被触发。3.2 SKILL.md 里到底该写什么这是整套体系里最关键的部分。一个能真正生效的SKILL.md我建议包含四个区块触发条件When to use明确告诉 agent 什么场景下该加载这个技能。比如当用户要求新增功能或修复 bug 时。核心规则Rules一条条可执行的硬性规定避免形容词多用动词和具体路径。示例Examples正例和反例各给一两个agent 对示例的敏感度远高于抽象描述。验证方式Verification告诉 agent 怎么自检是否遵守了规则比如运行npm test确认全部通过。我实测下来示例区块的性价比最高。你写十条规则agent 可能记住六条但你给一个正例一个反例它几乎不会搞错。这跟教人是一个道理——你告诉新人代码要整洁他一脸茫然你给他看一段整洁的代码和一段混乱的代码他立刻就懂了。3.3 加载优先级冲突了听谁的技能多了必然有冲突所以加载优先级是必须搞清楚的机制。常见的做法是三层层级来源优先级典型用途项目级项目根目录skills/最高项目特有的规范用户级用户主目录配置中个人编码习惯全局级工具内置技能最低通用最佳实践优先级高的覆盖优先级低的。这个设计的意义在于项目规范永远压过个人偏好。你在自己项目里习惯用双引号但公司项目规定用单引号那进了这个项目就得听项目的。这和.editorconfig、.eslintrc的分层覆盖逻辑是一脉相承的本质上是把配置覆盖的思想搬到了 AI 协作上。注意如果你发现某个技能明明写了却不生效第一件事就是检查优先级——很可能它被更高层级的同名技能覆盖了。4. 把 TDD 写成技能一个完整的实战案例4.1 为什么拿 TDD 当第一个技能热搜词里test-driven-development排在很靠前的位置这不是偶然。TDD 是 AI coding agent 最容易搞砸、也最能体现技能价值的场景。原因很简单agent 天生倾向于先写实现再补测试甚至干脆不写测试。而 TDD 要求先写测试看它失败再写实现让它通过这个顺序对 agent 来说是反直觉的。如果你只是口头说一句请用 TDDagent 大概率会敷衍你——写个测试然后立刻写实现中间跳过确认测试失败这一步。但如果你把 TDD 写成技能把每一步都拆成明确的动作和验证点它就能稳定执行。这就是技能相对于提示词的优势它能把一个模糊的要求拆解成 agent 无法跳过的步骤序列。4.2 手写一个 TDD 技能的完整过程假设我们用skills CLI来创建流程大概是这样# 初始化技能目录如果还没有 skills init # 基于模板生成一个新技能 skills create test-driven-development # 生成后编辑 SKILL.md生成的SKILL.md骨架我会这样填充# Test-Driven Development ## When to use 当任务涉及新增功能、修复 bug、或重构现有逻辑时必须使用本技能。 ## Rules 1. 在写任何实现代码之前先写一个会失败的测试。 2. 运行测试确认它确实失败红。 3. 写最少的实现代码让测试通过绿。 4. 运行全部测试确认没有破坏其他功能。 5. 在测试通过后再重构重构后必须重新运行测试。 ## Examples 正例先写 test_add_returns_sum运行看到 AssertionError 再实现 add 函数运行看到 PASS。 反例先写 add 函数再补一个测试测试一次就通过。 ## Verification 每完成一个循环运行 npm test 或对应测试命令 确认输出中同时包含新增测试通过和原有测试未回归。写完这个文件后用skills validate校验格式再用skills list确认它被正确加载。这套流程走下来你会发现技能文件本身不复杂难的是把规则写得足够具体具体到 agent 没有偷懒的空间。4.3 实测加了技能前后的对比我在一个中型 TypeScript 项目上做过对比。不加 TDD 技能时让 agent 实现一个用户注册去重功能它直接写了实现代码测试是事后补的而且只测了正常路径没测重复注册的边界情况。加了技能之后同样的需求它先写了一个should reject duplicate email的测试运行看到失败再写实现最后跑全量测试。差别不只是有没有测试而是测试的质量和时机。技能约束下的测试是驱动设计的——因为要先写测试agent 不得不先想清楚接口长什么样、边界在哪。这恰恰是 TDD 的精髓。我个人的体会是技能在这里起的作用不是教 agent 写测试而是逼 agent 慢下来先想清楚。4.4 技能和测试框架的配合细节有个容易被忽略的点技能里要写清楚项目用的是哪个测试框架、测试文件放哪、命名规范是什么。因为 agent 不知道你的项目约定它可能默认用 Jest但你项目用的是 Vitest它可能把测试放在__tests__/但你项目约定放在同目录的.test.ts文件里。这些细节不写进技能agent 就会按它的默认习惯来结果就是测试跑不起来或者风格不统一。我的做法是在技能里加一段项目测试约定## Project test conventions - 测试框架Vitest - 测试文件位置与被测文件同目录命名为 *.test.ts - 断言风格使用 expect(...).toBe(...)禁止使用 assert - 测试命名使用 should ... when ... 句式这段内容看起来琐碎但它把 agent 从通用助手变成了懂这个项目的助手。技能的价值很大程度上就藏在这些琐碎的约定里。5. 技能库的维护从能用到好用之间的那段路5.1 技能不是越多越好刚开始用技能系统的人很容易陷入什么都想写成技能的冲动。我见过一个项目技能目录下有三十多个文件从如何命名变量到如何写注释应有尽有。结果呢agent 加载时上下文被塞满反而抓不住重点执行质量下降。我的经验是技能数量控制在 5 到 10 个之间最舒服。每个技能对应一类高频、高价值的场景。低频的、一次性的规则直接写在提示词里就行没必要沉淀成技能。判断标准很简单——如果这条规则你一周内要重复交代三次以上才值得写成技能。5.2 技能也需要测试技能写完了不代表就对了。我建议给每个技能做一次回归测试找一个典型任务分别在有技能和无技能的情况下让 agent 执行对比结果。如果加了技能反而更差说明技能写歪了——可能是规则太死板限制了 agent 的合理判断也可能是规则之间有冲突让它无所适从。这个测试过程听起来麻烦但比技能上线后发现 agent 行为异常再回头排查要省事得多。技能本质上是代码代码要测试技能也要测试这个逻辑是一致的。5.3 版本管理技能也要进 Git技能文件必须进版本控制这一点没有商量余地。原因有三一是技能变更会影响 agent 行为需要可追溯二是团队协作时技能是共享资产不能只存在某个人本地三是技能出问题时能快速回滚到上一个稳定版本。我习惯在提交技能变更时在 commit message 里写清楚这个变更解决了什么问题。比如fix: TDD 技能补充 Vitest 约定解决测试文件位置错误的问题。这样半年后回头看能立刻明白当初为什么这么改。5.4 团队协作中的技能评审如果是一个团队在用技能变更最好走一次轻量评审。不需要像代码评审那么正式但至少让另一个人看一眼确认规则没有歧义、没有和现有技能冲突。我见过因为两个人分别加了用单引号和用双引号两个技能导致 agent 在同一个文件里两种引号混用的情况。这种问题一次评审就能避免。6. 踩坑实录我在技能系统上栽过的几个跟头6.1 坑一技能写得太抽象agent 当耳旁风最早我写技能时喜欢用请保持代码整洁遵循 SOLID 原则这种话。结果 agent 完全无感该写多长还写多长。后来我改成单个函数不超过 30 行超过就拆分效果立刻不一样。抽象的词对 agent 来说等于噪音具体的数字和路径才是有效指令。这个坑我踩了不止一次每次都是因为偷懒想少写几个字。6.2 坑二技能之间互相打架有一次我同时启用了函数式优先和使用 class 封装状态两个技能结果 agent 在同一个模块里一会儿写纯函数一会儿写 class风格混乱。排查了半天才发现是两个技能冲突。这件事教会我加技能之前先想想它和现有技能会不会矛盾。现在我的做法是每加一个新技能就用skills list看一遍全部技能确认没有语义重叠。6.3 坑三忘了技能有作用范围有个技能我本意是只在写业务代码时生效但忘了配置路径范围结果 agent 在改配置文件时也套用了业务代码的规则把package.json改得面目全非。这个坑的教训是技能的作用范围要显式配置不能靠 agent 自己判断。现在我会在skills.config.json里给每个技能明确paths字段限定它只在特定目录生效。6.4 坑四技能更新后没通知团队技能是共享资产你改了规则团队其他人的 agent 行为也会跟着变。我有一次优化了提交信息规范技能没告诉同事结果他第二天发现 agent 生成的提交信息格式变了一脸懵。后来我们约定技能变更必须在团队频道同步一句。技能变更的影响面比想象中大别把它当成个人配置。7. 从 agent-skills 延伸出去的几个思考7.1 技能系统会不会成为 AI 协作的标配我的判断是大概率会。现在 AI coding agent 的能力已经过了能不能用的阶段进入好不好用的阶段。而好用的关键不在于模型多强而在于它能不能融入你现有的工程流程。技能系统就是那个融入的接口。未来很可能每个稍具规模的项目都会有一份skills/目录就像现在每个项目都有.eslintrc和tsconfig.json一样。7.2 技能和文档的边界在哪有人会问技能和项目文档有什么区别我的理解是文档是给人看的技能是给 agent 看的。虽然内容可能重叠但表达方式不同——文档可以娓娓道来技能必须直给规则。而且技能是可执行的agent 会主动加载并遵守文档是参考性的agent 不一定读。这个区别决定了技能不能简单地把文档复制过来而要重新组织成指令的形态。7.3 给刚上手的人一条建议如果你刚开始接触agent-skills这类系统别一上来就搭大而全的技能库。先挑一个你最常重复交代的规则写成技能用一周看效果。有效再写第二个。技能系统的价值是复利式的——单个技能收益有限但积累到五六个、覆盖了主要工作流之后你会明显感觉到 agent 从需要盯着变成了可以放手。这个过程急不得也省不得。最后分享一个我自己的小习惯我会在技能目录里放一个CHANGELOG.md记录每次技能变更的原因和效果。半年下来这份 changelog 成了我理解agent 行为为什么是这样的最佳线索。技能系统用久了你会发现真正难的不是写技能而是记住你当初为什么这么写——这份记录就是给未来的自己留的说明书。