ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

agent-skills 实战:AI coding agent 技能复用与 Claude Code 集成

agent-skills 实战:AI coding agent 技能复用与 Claude Code 集成 1. 从 agent-skills 说起为什么它值得单独拿出来聊第一次看到agent-skills这个项目名我的直觉是这又是一个把提示词打包成文件夹的仓库。但真正翻完它的结构、跑通它的 CLI、再把它接到自己的 AI coding agent 工作流里之后我改变了判断。它解决的不是“提示词写得好不好”的问题而是“同一套能力怎么在不同 agent、不同项目、不同人之间稳定复用”的问题。简单说agent-skills是一套面向 AI coding agents 的技能组织规范与配套工具链。它把“让 agent 做某件事”的经验从散落在聊天记录、个人笔记、某个仓库的.prompt文件里收敛成有目录结构、有元数据、有加载规则的 skill 单元。配套的 skills CLI 负责发现、安装、组合、校验这些 skill让 Claude Code 这类 agent 在需要的时候按需加载而不是一次性把所有上下文塞进窗口。它适合谁三类人最该关注。第一类是把 Claude Code 当日常主力工具、但每次开新项目都要重新“教”它一遍规矩的开发者第二类是团队里想把代码规范、测试流程、发布检查固化成可共享资产的 tech lead第三类是正在做 agent 应用、需要一套可插拔能力层的工程师。哪怕你只是刚装好 Claude Code、还在摸索CLAUDE.md怎么写理解 skill 的组织方式也能让你的配置从“一坨”变成“一层一层”。我自己的使用场景很典型手上有几个长期维护的项目技术栈不同但都要求 test-driven-development 的节奏——先写失败测试再补实现最后重构。以前我是在每个项目的CLAUDE.md里重复写一遍 TDD 流程改一次要改好几处。用agent-skills之后TDD 变成一个独立 skill项目里只留一行引用。这个变化看起来小但它把“流程知识”和“项目知识”解耦了后面会详细讲为什么这个解耦是关键。2. 核心设计思路拆解skill 到底该怎么切2.1 为什么不是一个大而全的提示词很多人第一次接触 agent 定制习惯写一个超长的系统提示把编码风格、测试要求、提交规范、目录约定全塞进去。我早期也这么干过结果是上下文窗口被吃掉一大块agent 在简单任务上也要背着全部规则响应变慢而且规则之间偶尔互相干扰——比如“快速原型”和“严格 TDD”两条指令同时存在时agent 会犹豫。agent-skills的思路是反过来把能力切成原子化的 skill每个 skill 只回答“做这类事时该遵循什么”。加载是按需的任务涉及测试才加载 TDD skill涉及发布才加载 release skill。这背后的逻辑和微服务拆分是一样的——不是越小越好而是边界要清晰、职责要单一。判断一个 skill 切得好不好我总结了一个土办法如果这个 skill 的描述里出现了“并且”连接的两个不相关动作那它大概率该拆。比如“写测试并且部署”就该拆成两个。反过来如果两个 skill 总是同时被需要、从不单独出现那它们可能该合并。2.2 目录结构与元数据的设计考量一个典型的 skill 目录长这样skills/ test-driven-development/ SKILL.md references/ tdd-checklist.md scripts/ run-tests.sh code-review/ SKILL.md核心是SKILL.md它承担两件事一是给人和 agent 看的说明二是机器可解析的元数据。元数据通常包含 name、description、触发条件什么时候该加载这个 skill、依赖项。这里有个容易踩的坑description 写得太泛比如“帮助写更好的代码”agent 根本判断不出何时加载写得太窄又会漏掉本该匹配的场景。我的经验是 description 要写成“动词 对象 约束”的形式例如“在修改业务逻辑前先编写会失败的单元测试并确认其失败原因”。这样 agent 在规划阶段就能判断当前任务是否命中。2.3 与 Claude Code 的衔接方式Claude Code 本身支持通过项目根目录的配置文件注入上下文。agent-skills与它的衔接有两种常见做法。一种是把 skill 内容在会话初始化时按需注入适合 skill 数量少、任务类型固定的场景。另一种是让 agent 通过 skills CLI 主动查询和加载适合 skill 库较大、需要动态组合的场景。我实测下来第二种更稳因为它不会一次性污染上下文agent 只在真正需要时才把 skill 正文读进来。代价是 agent 需要多一步“发现”动作对模型的任务规划能力有一点要求。如果你用的是能力较强的模型这个代价可以忽略。注意skill 的加载顺序会影响 agent 的行为。如果两个 skill 对同一件事给出冲突指令后加载的通常会覆盖先加载的。所以我在组织 skill 时会把“通用规范”放在前面“项目特例”放在后面让特例有机会覆盖通用。3. 核心细节解析与实操要点3.1 SKILL.md 的写法说清楚“何时”比“如何”更重要新手写 SKILL.md容易把重点放在“怎么做”的步骤罗列上。但 agent 真正需要的是“什么时候该用我”。因为步骤 agent 可以自己推理触发时机却需要明确告知。一个我反复打磨过的 TDD skill 片段--- name: test-driven-development description: 在实现或修改任何业务逻辑前使用。先写失败测试确认失败再写最小实现使其通过最后重构。 triggers: - 新增功能 - 修改现有逻辑 - 修复 bug --- ## 流程 1. 阅读需求写出一个会失败的测试 2. 运行测试确认它因预期原因失败 3. 写最小实现让测试通过 4. 重构保持测试绿色注意 triggers 字段。它不是装饰而是给 agent 的匹配信号。我试过把 triggers 写得很抽象如“开发”结果 agent 在纯文档任务上也加载了 TDD skill白白消耗上下文。后来改成具体动作词命中率明显提升。3.2 references 与 scripts 的分工references/放的是 agent 需要阅读的补充材料比如检查清单、规范文档、示例代码。scripts/放的是可以直接执行的脚本比如跑测试、跑 lint、生成报告。这个分工的意义在于能执行的就不要让它读。让 agent 读一个 200 行的测试脚本再自己判断怎么跑不如直接给它一条命令。前者消耗 token 且容易出错后者确定性强。我在 release skill 里就放了一个check-version.shagent 直接调用比让它解析 package.json 再推理版本号可靠得多。3.3 参数与依赖的处理skill 之间可以有依赖。比如code-review可能依赖test-driven-development的检查清单。处理依赖有两种方式显式声明或者运行时组合。显式声明的好处是加载时能自动带上依赖坏处是可能引入不需要的内容。运行时组合更灵活但要求 agent 有组合能力。我倾向于只对强依赖做显式声明。所谓强依赖是“没有它这个 skill 就无法正确工作”。弱依赖有更好、没有也能跑交给 agent 运行时判断。这样能避免依赖树膨胀。3.4 版本与兼容性skill 是会演进的。今天写的 TDD 流程下个月可能因为团队规范变化而调整。如果不做版本管理agent 加载到旧版本会给出过时建议。我的做法是在 SKILL.md 的元数据里加 version 字段并在 CLI 层面支持锁定版本。对于团队共享的 skill 库这一步几乎是必须的。提示skill 的变更最好走和代码一样的 review 流程。我见过因为一个人随手改了共享 skill、导致整个团队 agent 行为漂移的情况排查起来非常费劲。4. 实操过程与核心环节实现4.1 环境准备与 skills CLI 安装假设你已经在本地装好了 Claude Code并且能正常在终端里调用。skills CLI 的安装通常通过包管理器完成。以常见的 Node 环境为例npm install -g agent-skills/cli装完后验证skills --version skills listskills list会扫描当前目录及配置的 skill 路径列出可用 skill。如果输出为空说明路径没配对检查一下配置文件里的 skills 目录指向。这里有个细节CLI 的全局配置和项目级配置是分开的。全局配置放你个人常用的 skill项目级配置放这个项目特有的。加载时项目级优先。我建议个人通用能力如 TDD、code-review放全局业务特定能力如“本项目的数据库迁移规范”放项目级。4.2 创建第一个 skill 并接入 Claude Code我拿 TDD 举例完整走一遍。第一步建目录mkdir -p skills/test-driven-development第二步写 SKILL.md内容参考 3.1 节的片段。关键是 description 和 triggers 要具体。第三步在项目配置里注册 skill 路径。具体配置项名称随 CLI 版本可能不同核心是告诉 CLI“去哪个目录找 skill”。第四步验证加载。在 Claude Code 会话里触发一个“新增功能”类任务观察 agent 是否引用了 TDD 流程。如果没引用先检查 triggers 是否命中再检查 skill 是否被 CLI 正确发现。我踩过的一个坑SKILL.md 的 frontmatter 格式错误比如少了闭合的---会导致整个 skill 被静默跳过CLI 不一定报错。所以写完一定要用skills validate之类的命令校验一遍。4.3 参数计算上下文预算怎么估skill 不是免费的每个加载的 skill 都占上下文。粗略估算一个中等复杂度的 SKILL.md 约 500 到 1500 tokenreferences 里的文档可能几千 token。如果你同时加载五个 skill光 skill 内容就可能吃掉上万 token。我的预算原则是常驻 skill 不超过两个其余按需加载。常驻的通常是项目最核心的规范比如代码风格按需的是流程类TDD、review、release。这样在大多数任务上上下文留给实际代码的空间是充足的。具体怎么判断我会在会话里观察 agent 的响应质量。如果它开始“忘记”前面的指令或者回答变得笼统往往是上下文压力大了。这时候就该精简 skill 或改成按需加载。4.4 把 skill 接入实际工作流光有 skill 不够得让它真正在流程里起作用。我的做法是把 skill 和具体命令绑定。比如提交前跑skills run pre-commit它会加载相关 skill 并执行检查脚本。这样 skill 不只是“建议”而是流程里的一个环节。对于团队协作我会把 skill 库作为独立仓库维护项目通过子模块或包依赖引入。这样 skill 的更新可以独立发布项目按需升级不会互相绑架。5. 常见问题与排查技巧实录5.1 skill 不生效的排查顺序这是被问得最多的问题。我整理了一个排查顺序按这个走基本能定位现象可能原因排查动作agent 完全不提 skill路径未注册检查 CLI 配置的 skills 目录部分任务不加载triggers 不匹配用具体动作词重写 triggers加载了但行为不对SKILL.md 指令冲突检查是否有多个 skill 覆盖同一行为时好时坏上下文压力减少常驻 skill改按需加载校验报错frontmatter 格式检查---闭合与字段拼写我遇到过一次“时好时坏”排查了半天才发现是 skill 加载顺序不稳定导致的。后来固定了加载顺序问题消失。所以顺序这件事别指望它自动稳定该显式指定就显式指定。5.2 指令冲突怎么处理两个 skill 对同一件事给出不同要求agent 会困惑。比如一个 skill 说“提交信息用中文”另一个说“用英文”。解决办法不是删掉一个而是明确优先级。我通常在项目级 skill 里写一句“本 skill 的约定优先于全局 skill”让 agent 有明确的裁决依据。5.3 独家避坑技巧第一个技巧skill 的 description 要能被“反向搜索”。意思是当 agent 面对一个任务时它是在做“哪个 skill 的描述匹配当前任务”的判断。所以 description 里要包含任务本身会出现的词。比如任务里常说“加个接口”那 description 里就该有“接口”这个词而不是只写“API”。第二个技巧给 skill 写一个“反例”。在 SKILL.md 里明确写“以下情况不要使用本 skill”。这能显著减少误加载。比如 TDD skill 里写“纯文档修改、配置调整不需要走 TDD 流程”。第三个技巧定期清理。skill 库会随着时间膨胀很多 skill 可能几个月没被加载过。我每季度会看一次加载日志把长期未命中的 skill 归档。库越干净agent 的判断越准。5.4 关于模型选择的现实考量热词里提到用第三方 API 接入不同模型这确实是很多人的需求。我的看法是skill 这套东西对模型的指令遵循能力有要求。能力弱的模型可能无法正确判断何时加载 skill或者加载后不严格遵守。所以如果你用的是能力较弱的模型建议把 skill 写得更直白、更短减少推理负担。反过来能力强的模型可以处理更抽象、更组合化的 skill。注意不同模型对 frontmatter、结构化指令的解析能力差异较大。换模型后务必重新验证核心 skill 是否仍然生效别默认它能无缝迁移。6. 我对 agent-skills 这套东西的真实看法用了一段时间后我最大的体会是agent-skills的价值不在于它提供了多少现成 skill而在于它逼你把“隐性经验”显性化。以前很多规范只存在于老员工的脑子里或者散落在各种文档角落。要把它写成 skill你必须回答“什么时候用、具体做什么、什么情况不适用”这个过程本身就是一次知识梳理。另一个体会是skill 的粒度控制是门手艺。切太细agent 要加载一堆才能干活组合成本高切太粗又失去了按需加载的意义。我现在的做法是先用粗粒度跑起来观察哪些 skill 总是被一起加载再考虑是否合并哪些 skill 内部出现了明显的“分支”再考虑拆分。让实际使用数据来指导拆分比一开始就追求完美结构靠谱得多。最后分享一个我最近在试的扩展方向把 skill 和项目的测试覆盖率、lint 结果挂钩让 agent 在加载 skill 时能读到当前项目的实际状态从而给出更有针对性的建议。比如 TDD skill 加载时如果发现当前模块覆盖率很低就优先建议补测试。这个方向还在摸索但初步效果不错skill 从“静态规范”变成了“带上下文的动态建议”。如果你也在做类似的事欢迎交流踩坑经验。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进