1. 从装完就吃灰说起agent-skills 到底解决了什么问题如果你最近半年在折腾 AI coding agent大概率经历过这个循环兴冲冲装好 Claude Code 或者 Cursor跑通第一个 demo觉得哇这玩意儿真神然后一周之后发现——它还是只会帮你补全代码、改改 bug稍微复杂一点的任务就开始胡言乱语上下文一长就失忆让它按团队规范写代码更是想都别想。问题不在模型本身。现在的模型能力早就溢出了真正卡住你的是你没有给它一套可复用的技能包。agent-skills这个项目本质上就是干这件事的。它是一套围绕 AI coding agent 构建的技能Skills管理与分发体系配套一个skills CLI工具让你能把怎么让 agent 干某件事这件事本身从一次性的 prompt 变成可版本化、可复用、可分享的资产。你可以把它理解成给 AI agent 装的插件系统——只不过插件里装的不是代码而是结构化的指令、上下文和工具调用约定。我第一次接触这个概念是在给一个团队做 Claude Code 落地的时候。当时最大的痛点是每个工程师都在自己的CLAUDE.md里写一堆规则格式五花八门新人来了完全不知道该抄谁的。后来我们把常用场景抽出来做成 skill——代码审查、提交信息生成、数据库迁移检查、接口文档同步——统一放进仓库用 CLI 分发。效果立竿见影agent 的输出质量稳定了团队协作成本也降下来了。这篇文章我会把 agent-skills 这套东西从设计思路到落地实操完整拆一遍。适合三类人看一是刚上手 Claude Code / Cursor、还在摸索怎么让 agent 听话的新手二是想把 AI coding 引入团队、但不知道怎么标准化的技术负责人三是已经在用 agent 但总觉得差一口气的老手。不管你在哪个阶段下面这些内容应该都能让你少走点弯路。2. agent-skills 的整体设计与思路拆解2.1 为什么是技能而不是提示词先聊一个根本问题为什么 agent-skills 要用技能这个抽象而不是继续用提示词prompt提示词的问题是它太轻了。一段 prompt 就是一段文本没有结构、没有版本、没有依赖关系、没有触发条件。你在 Claude Code 里写一句帮我审查代码它每次给你的东西都不一样因为模型不知道你的审查标准是什么、要检查哪些维度、输出格式长什么样。技能不一样。一个 skill 通常包含几个固定部分元信息名称、描述、适用场景、触发关键词指令主体具体要 agent 做什么、按什么步骤做上下文依赖需要读取哪些文件、参考哪些规范工具约定允许调用哪些工具、参数怎么传输出契约结果长什么样、格式怎么约束这套结构带来的最大好处是可预测性。你调用同一个 skill得到的输出质量是稳定的因为它把模糊的自然语言请求变成了结构化的任务定义。提示不要把 skill 想得太玄。它本质上就是一份写得更严谨、更工程化的 prompt加上一点元数据和工具约定。你完全可以从一个 markdown 文件开始。2.2 skills CLI 的设计取舍skills CLI是这个项目里最实用的部分。它的核心职责就三件事安装、管理、分发。为什么需要一个 CLI 而不是手动复制文件我踩过的坑是这样的早期我们团队把 skill 文件放在共享盘里每个人手动拷贝到~/.claude/skills/目录下。结果三个月后同一个 skill 在五个人的机器上有五个版本谁也不知道哪个是最新的。更离谱的是有人改了 skill 但忘了同步导致 agent 行为不一致排查了半天才发现是 skill 版本问题。CLI 解决的正是这个。它把 skill 当成包来管理有版本号、有来源、有依赖。你可以从远程仓库安装 skill 到本地列出当前已安装的 skill 和版本更新、卸载、锁定版本把本地 skill 发布出去给别人用这个设计思路其实借鉴了 npm、pip 那套包管理器的经验。为什么这么设计因为 skill 的复用场景和代码库高度相似——都需要版本控制、都需要依赖管理、都需要分发渠道。用一套成熟的模式去套比重新发明轮子靠谱得多。2.3 与 Claude Code、Cursor 的关系这里要说清楚一个容易混淆的点agent-skills 不是 Claude Code 或 Cursor 的替代品它是寄生在它们之上的增强层。Claude Code 本身有 skills 的概念它会在~/.claude/skills/目录下读取 skill 文件。Cursor 也有类似的规则系统.cursorrules或者新的 rules 目录。agent-skills 做的事情是用一套统一的格式和 CLI管理这些不同 agent 的 skill。为什么需要统一因为现实情况是一个团队里有人用 Claude Code有人用 Cursor有人两个都用。如果 skill 格式不统一你就得维护两套。agent-skills 的思路是写一份 skill通过 CLI 分发到不同 agent 的对应目录格式转换由工具处理。这个设计的好处是降低维护成本。坏处是抽象层多了一层偶尔会遇到格式转换不完美的情况。我的建议是如果你的团队只用一种 agent直接用原生的 skill 机制就够了如果混用agent-skills 的价值才真正体现出来。2.4 方案选型为什么不用 MCP有人会问既然要扩展 agent 能力为什么不用 MCPModel Context Protocol这是个好问题。MCP 和 skills 解决的是不同层面的问题维度MCPagent-skills核心能力连接外部工具和数据源定义 agent 的行为模式典型场景让 agent 读数据库、调 API让 agent 按规范写代码、做审查实现方式服务端进程 协议结构化文本 CLI 分发学习成本较高需要写服务较低写 markdown 即可适用对象需要外部集成的场景需要行为标准化的场景简单说MCP 管能做什么skills 管怎么做。两者是互补的不是竞争关系。一个成熟的 agent 工作流里通常既有 MCP 提供工具能力又有 skills 提供行为规范。我个人的经验是先上 skills把 agent 的行为规范起来等行为稳定了再考虑用 MCP 接入外部系统。反过来做的话你会陷入工具很多但 agent 还是不会用的困境。3. 核心细节解析与实操要点3.1 一个 skill 的最小结构先看一个能跑起来的最小 skill 长什么样。假设我们要做一个生成规范提交信息的 skill--- name: commit-message description: 根据 git diff 生成符合 Conventional Commits 规范的提交信息 triggers: - 生成提交信息 - commit message - 写 commit --- # 提交信息生成技能 ## 执行步骤 1. 运行 git diff --staged 获取暂存区变更 2. 分析变更类型feat/fix/docs/refactor/test/chore 3. 识别影响范围scope 4. 生成符合规范的提交信息 ## 输出格式 type(scope): subject body ## 约束 - subject 不超过 50 字符 - 使用中文描述 - 不添加 emoji - body 说明为什么而不是做了什么这个文件里---包裹的部分是 YAML frontmatter定义元信息下面是 markdown 正文定义具体行为。就这么简单。为什么用 markdown 而不是 JSON 或 YAML因为 skill 的读者是模型不是程序。markdown 的层级结构对模型来说更自然也更容易被人阅读和修改。你写 JSON 的话改一个逗号都得小心翼翼体验差太多。3.2 触发机制的设计skill 怎么被触发这是很多人第一次用会困惑的地方。目前主流有两种方式方式一关键词触发。在 frontmatter 里定义triggers当你的请求里包含这些词时agent 自动加载对应 skill。这种方式的好处是无感你正常说话就行坏处是可能误触发尤其是关键词太宽泛的时候。方式二显式调用。你直接说用 commit-message 技能帮我写提交信息。这种方式精确但需要你记住 skill 名字。我的建议是两者结合给 skill 定义精确的触发词避免代码这种泛词同时在文档里告诉团队怎么显式调用。实测下来触发词控制在 3-5 个、每个都足够具体误触发率能降到很低。注意触发词不要用中文和英文混着写一堆同义词。模型对触发词的理解比你想象的灵活写太多反而会互相干扰。三个精准的比十个模糊的强。3.3 上下文注入的三种粒度skill 里最容易被忽视、但影响最大的是上下文注入。也就是agent 执行这个 skill 时应该看到哪些信息我把它分成三种粒度全局上下文所有 skill 共享的信息比如项目技术栈、代码规范、目录结构。这部分通常放在 agent 的全局配置文件里Claude Code 的CLAUDE.mdCursor 的 rules不需要每个 skill 重复。技能级上下文这个 skill 专属的参考信息。比如代码审查skill 需要知道团队的审查清单数据库迁移skill 需要知道表命名规范。这部分写在 skill 文件里。任务级上下文执行时动态获取的信息。比如当前 git diff、当前打开的文件、用户的具体需求。这部分由 agent 在运行时自己收集skill 里只需要说明需要读取什么。分清楚这三层你的 skill 就不会写得又臭又长。我见过有人把整个代码规范塞进一个 skill 里结果文件 2000 多行模型读到后面都忘了前面。正确的做法是全局的放全局技能级的精简到必要任务级的让 agent 自己找。3.4 输出契约的重要性输出契约是 skill 里最工程化的部分也是最容易被跳过、但最不该跳过的部分。什么叫输出契约就是明确规定 agent 的输出格式。比如是纯文本还是 markdown有没有固定的章节结构代码块用什么语言标注长度限制是多少允不允许自由发挥为什么这个重要因为没有契约的输出无法被下游消费。举个例子你让 agent 生成接口文档如果它每次格式都不一样你就没法把它自动写进文档系统。但如果你规定必须输出符合 OpenAPI 3.0 的 YAML那这个输出就能直接被工具链消费。我在团队里推的一个硬性规则是凡是输出会被程序处理的 skill必须定义严格的输出契约。纯给人看的 skill 可以宽松一点但也建议至少规定结构。3.5 版本管理与依赖skill 也是代码也需要版本管理。agent-skills 的 CLI 支持给 skill 打版本号这个设计很有必要。什么时候需要升版本我的经验是补丁版本1.0.0 → 1.0.1修错别字、调整措辞、优化触发词次版本1.0.0 → 1.1.0新增功能、调整输出格式、增加约束主版本1.0.0 → 2.0.0改变核心行为、输出契约不兼容依赖关系也要考虑。比如生成 PR 描述的 skill 可能依赖生成提交信息的 skill。CLI 支持声明依赖安装时会自动拉取。这个机制在 skill 数量多了之后特别有用避免手动一个个装。4. 实操过程与核心环节实现4.1 环境准备从零到能跑假设你现在什么都没装我们从零开始。以 Claude Code 为例Cursor 的流程类似只是目录不同。第一步确认你的 agent 已经能正常工作。Claude Code 装好之后在终端里跑一下claude命令能进交互界面就说明基础环境 OK。如果你还没装官方文档里有各平台的安装方式Windows 用户建议用 WSL原生 Windows 支持虽然有了但偶尔会有路径问题。第二步安装 skills CLI。具体命令取决于项目发布方式通常是 npm 或类似的包管理器npm install -g agent-skills-cli装完之后验证一下skills --version能输出版本号就说明 CLI 装好了。第三步初始化本地 skill 目录。CLI 通常会提供一个 init 命令skills init这个命令会在你的用户目录下创建 skill 存储位置并生成一个配置文件。配置文件里记录了 skill 的安装路径、默认来源仓库等信息。提示如果你之前手动往~/.claude/skills/里放过文件init 的时候注意别覆盖了。先备份一下再操作。4.2 安装第一个 skill环境准备好之后装一个现成的 skill 试试水。假设我们要装一个代码审查skillskills install code-reviewCLI 会从配置的源仓库拉取这个 skill放到本地目录并在配置文件里登记。装完之后你可以用skills list看到已安装的 skill 列表。这时候打开 Claude Code说一句帮我审查一下这段代码如果 skill 的触发词匹配上了agent 就会按 skill 定义的流程走。如果没触发可以显式调用用 code-review 技能审查 src/main.py第一次用建议先拿一段简单的代码测试确认 skill 真的生效了。怎么确认看 agent 的输出结构——如果它开始按 skill 里定义的步骤走比如先列检查项、再逐项分析、最后给结论说明生效了。4.3 写一个自己的 skill完整流程现成的 skill 用顺了之后你肯定会想写自己的。我拿一个真实场景走一遍数据库迁移检查。第一步明确需求边界。这个 skill 要做什么我的定义是当有人修改了数据库 schema 文件时检查这次修改是否安全。具体检查项包括是否删除了列、是否修改了列类型、是否添加了非空约束但没有默认值、是否重命名了表或列。第二步写元信息。frontmatter 部分--- name: db-migration-check description: 检查数据库迁移脚本的安全性识别破坏性变更 triggers: - 检查迁移 - migration check - 数据库变更检查 version: 1.0.0 ---第三步写执行步骤。这部分要具体到 agent 能照着做## 执行步骤 1. 读取用户指定的迁移文件或查找最近修改的 migrations 目录下文件 2. 解析 SQL 语句识别以下操作类型 - DROP COLUMN / DROP TABLE - ALTER COLUMN TYPE - ADD COLUMN NOT NULL无 DEFAULT - RENAME 3. 对每个识别到的操作判断风险等级 4. 输出检查报告第四步定义输出契约。规定报告格式## 输出格式 ### 检查结果 | 操作 | 位置 | 风险等级 | 说明 | |------|------|----------|------| | ... | ... | 高/中/低 | ... | ### 建议 针对高风险操作给出回滚方案或替代方案。第五步本地测试。把文件放到 skill 目录用 CLI 注册skills add ./db-migration-check.md然后找几个真实的迁移文件测试。我建议至少测三类安全的变更加列带默认值、中等风险的变更改类型、高危变更删列。看 agent 的判断是否准确。第六步迭代。第一版肯定不完美。我第一版写的时候漏了添加唯一索引这个场景测试时才发现。补上之后又发现 agent 对复合索引的判断有问题再调整措辞。大概迭代三四轮才能稳定。4.4 团队分发从个人到协作个人用顺了之后下一步是团队分发。这里有几个关键决策决策一skill 放哪我的建议是单独建一个 git 仓库专门放 skill。不要和业务代码混在一起因为 skill 的更新频率和业务代码完全不同混在一起会让 PR 变得很乱。决策二怎么分发两种方式Git 直接拉取团队成员 clone skill 仓库用 CLI 从本地路径安装。简单但更新需要手动 pull。私有 registry搭一个内部的 skill registryCLI 从 registry 安装。复杂但更新方便还能做权限控制。小团队10 人以下用第一种就够了。大团队建议上 registry否则版本混乱的问题迟早会爆发。决策三怎么保证质量skill 也是代码也需要 review。我的做法是skill 仓库设置 PR 流程任何 skill 的修改都要经过至少一个人 review。review 的重点是触发词是否精确、执行步骤是否可复现、输出契约是否明确。4.5 与 Cursor 的协同配置如果你的团队混用 Claude Code 和 Cursor配置会稍微复杂一点。核心思路是一份 skill 源文件分发到两个目录。Claude Code 读~/.claude/skills/Cursor 读它自己的 rules 目录。agent-skills 的 CLI 通常支持配置多个目标路径安装时自动分发。具体配置在 CLI 的配置文件里大概长这样{ targets: [ { name: claude-code, path: ~/.claude/skills/, format: claude }, { name: cursor, path: ~/.cursor/rules/, format: cursor } ] }配置好之后skills install会自动往两个目录都放一份。格式转换由 CLI 处理。注意Cursor 的 rules 机制和 Claude Code 的 skills 机制并不完全等价。Cursor 的 rules 更偏向全局行为约束而 Claude Code 的 skills 更偏向任务级技能。转换的时候可能会有信息损失建议在 Cursor 里测试一下关键 skill 是否还能正常工作。5. 常见问题与排查技巧实录5.1 skill 不触发怎么办这是最高频的问题。排查思路按顺序来第一检查触发词。你的请求里有没有包含 skill 定义的触发词如果没有agent 当然不会加载。解决方法是显式调用或者把触发词改得更贴近你的日常表达。第二检查 skill 是否真的被加载。有些 agent 有调试模式能看到当前加载了哪些 skill。Claude Code 里可以用/skills之类的命令查看具体命令看版本。如果 skill 没在列表里说明安装路径不对。第三检查文件格式。frontmatter 的 YAML 语法很容易出错比如冒号后面没空格、缩进不对。用 YAML 校验工具过一遍。第四检查优先级冲突。如果你装了多个 skill触发词有重叠agent 可能加载了另一个。这时候要么改触发词要么显式指定 skill 名。5.2 skill 输出不稳定有时候同一个 skill今天输出很好明天就拉胯。可能的原因现象可能原因排查方法输出格式偶尔不对输出契约不够严格增加格式约束给出示例步骤执行不完整指令太长模型漏读精简 skill拆分步骤判断标准不一致约束条件模糊把应该改成必须给出反例上下文丢失skill 太长超出窗口拆分 skill减少冗余我的经验是skill 越短越稳定。一个 skill 控制在 200 行以内超过就考虑拆。模型对长指令的遵循度是递减的前面记得住后面就忘了。5.3 版本冲突与依赖地狱skill 数量多了之后版本冲突是必然的。典型场景A skill 依赖 B skill 的 1.0 版本C skill 依赖 B skill 的 2.0 版本而 2.0 不兼容 1.0。解决方案有两个方案一锁定版本。在安装时指定版本号CLI 会保留多个版本按需加载。缺点是磁盘占用增加管理复杂。方案二统一升级。把所有依赖 B 的 skill 一起升级到兼容 2.0 的版本。缺点是工作量大需要测试。我的建议是skill 的依赖关系尽量扁平。不要让 skill 之间形成复杂的依赖网。如果两个 skill 有共享逻辑把共享部分抽成基础 skill其他 skill 依赖它而不是互相依赖。5.4 团队协作中的权限问题skill 里可能包含敏感信息比如内部 API 地址、数据库连接串、业务规则。这些 skill 不能随便分发。处理方式敏感 skill 单独仓库权限收紧skill 里用占位符实际值从环境变量读分发时做过滤CLI 支持排除特定文件我见过最离谱的案例是有人把生产数据库的连接串写进了 skill然后 skill 仓库是公开的。这种事一旦发生后果很严重。所以skill 仓库的权限管理必须和代码仓库一个级别不能因为是配置文件就放松。5.5 性能问题skill 太多导致响应慢skill 装多了之后agent 每次启动都要加载所有 skill 的元信息响应会变慢。我实测下来超过 30 个 skill 之后启动延迟明显增加。优化方法按项目启用不是所有 skill 都需要全局加载。用 CLI 的 project 级别配置只加载当前项目需要的 skill。归档不用的 skill定期清理把不常用的 skill 归档需要时再启用。精简元信息description 写短一点触发词少一点减少加载开销。5.6 常见问题速查表问题快速排查根治方法skill 不触发检查触发词和安装路径显式调用 精确触发词输出格式乱检查输出契约增加格式约束和示例步骤漏执行检查 skill 长度拆分 skill版本冲突skills list看版本扁平化依赖响应变慢数一下 skill 数量按项目启用敏感信息泄露检查 skill 内容占位符 权限控制6. 我踩过的坑和几条实在建议写到这里把几个用血泪换来的经验分享一下。第一条不要一开始就追求完美。我见过太多人花两周设计一套完美的 skill 体系结果一个都没落地。正确的做法是先写一个最丑但能用的 skill跑起来用一周再迭代。skill 的价值在于用不在于设计。第二条skill 的粒度要刚刚好。太粗一个 skill 干所有事会导致指令模糊、输出不稳定太细每个小操作一个 skill会导致管理成本爆炸。我的经验是一个 skill 对应一个完整的任务闭环。比如生成提交信息是一个闭环分析 diff就不是它只是闭环里的一步。第三条给 skill 写测试。听起来很怪但真的有用。准备一组输入和期望输出每次改完 skill 跑一遍。我现在的做法是每个 skill 配一个test.md里面放三五个典型场景改完 skill 手动过一遍。虽然土但能挡住 80% 的回归问题。第四条别忽视文档。skill 仓库里一定要有 README说明每个 skill 干什么、怎么用、有什么坑。新人进来第一件事就是读 README。我见过 skill 写得很好但没文档的团队结果新人根本不知道有这些 skill白白浪费。第五条定期清理。skill 会像代码一样腐化。三个月不用的 skill要么删掉要么归档。留着只会增加认知负担和加载开销。最后说一个我最近在试的方向把 skill 和 CI 结合。比如在 PR 流程里自动跑代码审查skill把结果作为评论贴出来。这样 skill 的价值就从个人提效升级到了团队流程自动化。这个方向还在摸索等跑通了再单独写一篇。如果你也在折腾 agent-skills欢迎交流。这东西没有标准答案每个团队的最佳实践都不一样多看看别人的做法总没坏处。
