☰
agent-skills:为AI编码代理构建可复用技能库的工程实践
2026/10/7 4:01:37 网站建设 项目流程

1. 从“agent-skills”说起:为什么我们需要给AI编码代理装上一套技能库

第一次看到agent-skills这个项目名的时候,我正被一堆重复的提示词折磨得够呛。那段时间我在用 Claude Code 做日常开发,每次开新会话都要重新交代一遍项目结构、代码规范、测试要求,烦得不行。后来我意识到,问题不在于模型不够聪明,而在于我一直在用“一次性对话”的方式使用一个本该被系统化配置的工具。

agent-skills解决的就是这个问题。它本质上是一套面向 AI coding agents 的技能定义与管理方案,核心思路是把“你希望代理怎么干活”这件事从每次对话里抽出来,变成可复用、可版本管理、可组合的技能模块。你可以把它理解成给 AI 编码代理准备的“岗位操作手册”——不是告诉它“你是一个资深工程师”这种空话,而是明确告诉它:在这个项目里,写测试要遵循什么流程,提交代码前要跑哪些检查,遇到特定类型的 bug 应该按什么顺序排查。

这套东西适合谁?如果你只是偶尔让 AI 帮你补全几行代码,那确实用不上。但如果你已经把 Claude Code 或者类似的 AI coding agent 接入了日常开发流程,每天都要用它写功能、改 bug、跑测试,那agent-skills这类方案能帮你省下大量重复沟通的成本。它解决的核心问题是:让 AI 代理的行为从“随机发挥”变成“按规程执行”。

我后面会从设计思路、核心机制、实操配置、常见坑几个角度,把这套东西拆开讲清楚。文章里涉及的具体配置和命令,我会尽量给出可直接复现的版本,但你要知道,这类工具迭代很快,细节可能随时变化,思路比具体命令更重要。

2. 核心设计思路拆解:技能到底是怎么被组织和调用的

2.1 为什么不是“写一个超长提示词”就完事

很多人第一反应是:不就是让 AI 按规矩干活吗,我写一个巨长的 system prompt 不就行了?我一开始也这么想,试过之后发现根本行不通。原因有三个。

第一,提示词长度是有代价的。你把所有规范、流程、示例都塞进一个 prompt 里,每次对话都要消耗大量 token,而且模型对超长上下文的注意力是会被稀释的。我实测过一个 3000 字的系统提示,模型在前几轮还能记住关键约束,聊到后面就开始“忘记”某些规则了。

第二,不同任务需要的技能不一样。写新功能和修 bug 的流程完全不同,重构和写文档的要求也不一样。你不可能用一个静态提示词覆盖所有场景,但你又不想每次手动切换。

第三,提示词没法版本管理。你今天改了一版规范,明天想回滚,或者想看看上周的版本和现在的差异,纯文本提示词很难做到。而agent-skills把技能做成独立文件,天然就支持 git 管理。

所以这套方案的核心设计决策是:把技能拆成独立模块,按需加载,按场景组合。这跟传统软件工程里“关注点分离”的思路是一脉相承的。

2.2 技能文件的组织结构与加载逻辑

agent-skills通常采用目录化的组织方式。一个典型的技能库结构大概长这样:

agent-skills/ skills/ test-driven-development/ SKILL.md examples/ code-review/ SKILL.md checklist.md debugging/ SKILL.md playbook.md config.yaml

每个技能目录下有一个核心的SKILL.md,里面定义了这个技能的触发条件、执行步骤、约束规则和示例。config.yaml则负责声明哪些技能在什么场景下被激活。

这种结构的好处是,你可以把test-driven-development这个技能单独拿出来看,它就是一个自包含的文档,不依赖其他技能也能理解。当代理需要执行 TDD 流程时,系统只加载这一个技能的内容,不会把无关的代码审查规则也塞进去。

加载逻辑上,通常有两种触发方式。一种是显式触发,你在对话里说“用 TDD 方式实现这个功能”,代理就会去加载对应的技能。另一种是隐式触发,通过配置文件里的规则,比如“当用户要求写新功能时,自动加载 TDD 技能”。我个人的习惯是混合使用:日常开发用隐式触发减少操作,特殊场景用显式触发精确控制。

2.3 技能与代理的交互协议

这里有一个容易被忽略但很关键的设计点:技能不是简单地“把文档喂给模型”,而是定义了一套交互协议。什么意思?就是技能文件里不仅写“要做什么”,还写“在什么条件下做什么”“做完之后怎么验证”“如果失败怎么回退”。

举个例子,一个 TDD 技能可能会这样定义流程:

  1. 收到功能需求后,先写一个会失败的测试
  2. 运行测试,确认它确实失败(这一步很多人会跳过,但它是 TDD 的核心)
  3. 写最少的代码让测试通过
  4. 运行全部测试,确认没有破坏其他功能
  5. 重构代码,保持测试通过

每一步都有明确的输入、输出和验证条件。代理不是“理解”了 TDD 的概念,而是按照这个协议一步步执行。这种设计让行为变得可预测,也方便你在某一步失败时定位问题。

注意:技能文件里的步骤描述要足够具体,但也不能太死板。我见过有人把技能写成“第 1 行写 import,第 2 行写函数定义”这种程度,结果代理完全失去了灵活性。好的技能定义应该像给一个聪明的新人写操作手册——告诉他目标和约束,而不是替他做每一个决定。

3. 核心细节解析:一个技能文件里到底该写什么

3.1 触发条件的写法与常见误区

触发条件是技能被激活的“开关”。写得太宽,技能会在不该用的时候被加载,浪费上下文;写得太窄,该用的时候又触发不了。

我踩过的坑是这样的:一开始我把触发条件写成“当用户要求写代码时”,结果代理在每次对话里都加载 TDD 技能,包括我只是让它解释一段代码的时候。后来改成“当用户要求实现新功能或修改现有功能时”,就准确多了。

触发条件通常包含几个维度:

  • 任务类型:写新功能、修 bug、重构、写文档、代码审查
  • 关键词:用户消息里出现的特定词汇,比如“测试”“重构”“性能”
  • 文件类型:操作的是测试文件、配置文件还是业务代码
  • 项目状态:比如当前分支是否有未提交的更改

你可以用组合条件来精确控制。比如“当任务类型是写新功能,且操作的是业务代码文件时,加载 TDD 技能”。这种粒度需要根据你的实际工作流来调整,没有万能公式。

3.2 执行步骤的粒度控制

执行步骤写多细?这是我最常被问到的问题。我的经验是:写到“一个步骤对应一个可验证的动作”这个粒度。

比如“写测试”这个步骤,如果只写“写测试”,代理可能会写一个覆盖不全的测试,或者写一个根本不会失败的测试。但如果你写成“针对用户描述的功能点,写一个测试用例,该用例在当前代码下必须失败”,代理就知道要验证测试的有效性。

再比如“运行测试”这个步骤,要明确是运行单个测试文件还是全部测试,是只跑当前模块还是全量回归。这些细节不写清楚,代理就会按自己的理解来,结果往往不是你想要的。

我通常会在步骤后面加一个“验证”子项,说明这一步做完之后怎么确认是对的。比如:

  • 步骤:写一个会失败的测试
  • 验证:运行该测试,确认输出为失败状态,且失败原因是功能未实现,而不是语法错误

这种写法看起来啰嗦,但实际用起来能省掉大量来回沟通。

3.3 约束规则与边界条件

约束规则是技能文件里最容易被低估的部分。它定义了代理“不能做什么”,往往比“能做什么”更重要。

常见的约束包括:

  • 不允许修改测试文件来让测试通过(这是 TDD 里最常见的作弊行为)
  • 不允许在未运行测试的情况下声称功能已完成
  • 不允许一次性重写超过 N 个文件
  • 不允许在重构步骤中改变外部行为

这些约束要写得明确、可检查。比如“不允许修改测试文件”这种约束,代理在执行时是可以自己检查的——它会看到自己准备修改的文件路径里包含test或spec,然后停下来。

边界条件则是指那些“特殊情况怎么处理”的说明。比如:如果测试运行环境不可用怎么办?如果依赖缺失怎么办?如果用户的需求本身有矛盾怎么办?这些情况不一定会发生,但一旦发生,有预设的处理方式会让代理的行为稳定很多。

提示:约束规则不要写太多。我见过有人写了 30 条约束,结果代理在执行时频繁“卡住”,因为太多规则互相冲突。我的建议是控制在 5 到 8 条核心约束,其他的通过示例来传达。

4. 实操过程:从零搭建一套可用的技能库

4.1 环境准备与基础配置

假设你已经装好了 Claude Code,并且能在终端里正常调用。如果还没装,官方文档里有详细的安装步骤,Mac、Ubuntu、VS Code 插件的配置方式都有说明,这里不展开。

第一步是创建技能库的目录结构。我习惯在项目根目录下建一个.agent-skills文件夹,跟.github、.vscode这些配置目录平级。这样做的好处是技能库跟着项目走,换机器或者换协作者都能直接复用。

mkdir -p .agent-skills/skills touch .agent-skills/config.yaml

然后创建第一个技能,比如 TDD:

mkdir -p .agent-skills/skills/test-driven-development touch .agent-skills/skills/test-driven-development/SKILL.md

config.yaml里声明技能库的根路径和默认加载策略:

skills_root: .agent-skills/skills default_skills: - test-driven-development auto_load: true

这个配置的意思是:技能库在.agent-skills/skills下,默认加载 TDD 技能,并且允许自动触发。

4.2 编写第一个技能文件:以 TDD 为例

SKILL.md的内容我一般按这个结构来写:

# Test-Driven Development ## 触发条件 - 用户要求实现新功能 - 用户要求修改现有功能的行为 - 操作的文件是业务代码(非测试、非配置) ## 执行步骤 ### 步骤 1:理解需求并写失败测试 - 从用户描述中提取功能点 - 在对应的测试文件中写一个测试用例 - 测试用例必须覆盖用户描述的核心行为 - 验证:运行该测试,确认失败,且失败原因是功能未实现 ### 步骤 2:写最少代码让测试通过 - 只实现让当前测试通过所需的代码 - 不添加测试未覆盖的额外功能 - 验证:运行该测试,确认通过 ### 步骤 3:运行全量测试 - 运行项目全部测试 - 确认没有破坏现有功能 - 验证:全量测试通过 ### 步骤 4:重构 - 在不改变外部行为的前提下优化代码 - 每次重构后重新运行测试 - 验证:重构后全量测试仍然通过 ## 约束 - 不允许修改测试文件来让测试通过 - 不允许跳过“确认测试失败”这一步 - 不允许在步骤 2 中添加测试未覆盖的功能 - 如果全量测试失败,必须回退到上一个通过状态 ## 示例 (这里放一个完整的 TDD 流程示例,包括测试代码和实现代码)

这个文件写完之后,你在 Claude Code 里说“用 TDD 方式实现一个用户注册功能”,代理就会按照这个流程走。我实测下来,有了这个技能文件之后,代理写出的测试质量明显提升,而且不会出现“先写实现再补测试”这种反模式。

4.3 技能的组合与优先级管理

实际开发中,一个任务往往需要多个技能配合。比如“重构一个模块并补充测试”,既需要重构技能,又需要 TDD 技能。这时候就需要处理技能之间的组合和优先级。

我的做法是在config.yaml里定义技能组合:

skill_combinations: refactor_with_tests: skills: - refactoring - test-driven-development priority: test-driven-development

priority表示当两个技能的约束冲突时,以哪个为准。比如重构技能可能允许“先改代码再补测试”,但 TDD 技能要求“先写测试”,这时候以 TDD 为准。

还有一种情况是技能之间的依赖关系。比如代码审查技能可能依赖 TDD 技能已经执行完毕,因为审查时要检查测试覆盖情况。这种依赖可以在技能文件里用depends_on字段声明,加载时系统会自动处理顺序。

4.4 与 Claude Code 的集成方式

把技能库接入 Claude Code 有几种方式,我试过两种比较稳的。

第一种是通过项目配置文件引用。在项目根目录的 Claude Code 配置里,指定技能库的路径和加载规则。这样每次在这个项目里启动 Claude Code,技能库会自动生效。

第二种是通过 CLI 显式加载。Claude Code 支持在启动时传入额外的上下文文件,你可以把技能文件作为参数传进去。这种方式适合临时使用某个技能,或者在不同项目之间共享技能库。

claude --context .agent-skills/skills/test-driven-development/SKILL.md

两种方式可以结合使用:项目级配置放通用技能,CLI 参数放临时技能。我个人的习惯是项目级配置只放最核心的两三个技能,其他的按需加载,避免上下文被塞得太满。

注意:如果你用的是第三方 API 接入方式,比如通过 cc switch 接入其他模型,技能库的加载逻辑可能会有所不同。核心思路是一样的——把技能文件作为上下文的一部分传给模型——但具体的配置方式需要参考对应工具的文档。

5. 常见问题与排查技巧实录

5.1 技能不生效或触发错误

这是最常见的问题。表现是:你明明配置了技能,但代理的行为跟没配置一样。

排查顺序我一般是这样的:

  1. 检查文件路径:config.yaml里的skills_root是否指向了正确的目录。我遇到过因为多了一层文件夹导致技能加载不到的情况。
  2. 检查触发条件:你的消息是否匹配了技能的触发条件?可以临时把触发条件放宽,看技能是否能被加载。
  3. 检查文件格式:SKILL.md的 Markdown 格式是否正确?特别是标题层级,有些解析器对#和##的层级很敏感。
  4. 检查加载日志:Claude Code 在启动时通常会输出加载了哪些上下文文件,看看你的技能文件是否在列表里。

如果以上都没问题,那可能是技能文件内容本身的问题。比如步骤写得太模糊,代理“理解”不了;或者约束太多,代理直接忽略了。

5.2 代理“忘记”技能约束

这种情况通常发生在对话轮次比较多的时候。代理在前面几轮还能遵守约束,聊到后面就开始“自由发挥”了。

根本原因是上下文窗口的限制。技能文件的内容会随着对话进行逐渐被“挤”出有效注意力范围。解决办法有几个:

  • 缩短技能文件:把不必要的内容删掉,只保留核心步骤和约束。
  • 在关键节点重新注入:在对话进行到关键步骤时,手动提醒代理“请回顾 TDD 技能的约束”。
  • 拆分任务:不要把一个大任务从头到尾放在一个会话里,拆成多个小会话,每个会话重新加载技能。

我实测下来,把技能文件控制在 500 字以内,配合任务拆分,能显著减少“忘记约束”的情况。

5.3 技能之间的冲突处理

当多个技能同时被加载时,约束冲突是难免的。比如 TDD 技能要求“先写测试”,但某个快速原型技能可能允许“先写实现”。

处理冲突的原则是:明确优先级,并在技能文件里声明冲突解决方式。我通常会在优先级高的技能里加一条约束:“当与其他技能冲突时,以本技能的约束为准”。这样代理在执行时就有明确的判断依据。

如果冲突频繁发生,那说明技能拆分得太细了。可以考虑把两个经常冲突的技能合并成一个,或者重新设计触发条件,让它们不在同一个场景下同时激活。

5.4 常见问题速查表

问题现象可能原因排查方法解决方式
技能完全不生效路径配置错误检查 config.yaml 和实际目录修正路径
技能偶尔生效触发条件太窄放宽触发条件测试调整关键词
代理忽略约束技能文件太长统计技能文件字数精简到 500 字以内
多个技能冲突优先级未定义查看技能组合配置声明 priority
代理行为不稳定上下文被挤占检查会话轮次拆分任务
测试被修改约束不够明确检查约束条款加“不允许修改测试文件”

5.5 几个我踩过的坑

第一个坑是技能文件写得太像文档。我一开始把技能写成了“TDD 最佳实践指南”,结果代理把它当参考资料读,而不是当操作指令执行。后来改成“步骤 1、步骤 2、步骤 3”这种命令式写法,效果就好多了。

第二个坑是忽略了技能的版本管理。有次我改了一个技能的约束,结果之前能正常工作的流程突然出问题了。后来我把技能库纳入 git 管理,每次修改都提交,出问题可以快速回滚。

第三个坑是在不同项目之间复制技能库。复制的时候没注意路径配置,导致技能加载失败。后来我改成用 git submodule 或者符号链接的方式共享技能库,避免了路径问题。

6. 技能库的扩展与长期维护

6.1 从单个技能到技能体系

当你有了三五个技能之后,就需要考虑它们之间的关系了。我的经验是,技能体系应该围绕你的实际工作流来组织,而不是围绕技术概念。

比如,一个典型的开发工作流可能是:需求分析 → 写测试 → 写实现 → 代码审查 → 提交。对应的技能就是:需求拆解技能、TDD 技能、代码审查技能、提交规范技能。这些技能按顺序组合,就形成了一个完整的工作流。

你可以在config.yaml里定义工作流:

workflows: feature_development: steps: - requirement-analysis - test-driven-development - code-review - commit-convention

这样当你启动一个新功能开发时,代理会按这个顺序依次加载和执行技能。

6.2 技能效果的度量与迭代

技能写得好不好,不能凭感觉。我通常会关注几个指标:

  • 测试通过率:用了 TDD 技能之后,测试通过率有没有提升
  • 返工次数:代理完成的任务,需要人工修改的比例
  • 约束违反次数:代理违反技能约束的频率
  • 任务完成时间:从开始到完成的中位时间

这些指标不需要很精确,但要有记录。我一般会在技能文件里加一个简单的日志输出,每次技能执行时记录关键节点,然后定期回顾。

如果某个技能的约束违反次数很高,说明约束写得不清楚,或者代理“不理解”这个约束。这时候需要调整约束的表述方式,或者增加示例。

6.3 团队协作中的技能库管理

如果你在团队里推广这套方案,技能库的管理就需要更规范。我的建议是:

  • 技能库独立仓库:不要放在业务项目里,单独建一个仓库,通过 submodule 或包管理工具引入
  • 技能变更走 PR:任何技能修改都要经过代码审查,避免个人偏好影响团队
  • 技能文档化:每个技能文件头部写清楚作者、最后修改时间、适用场景
  • 定期回顾:每个月回顾一次技能库的使用情况,删掉不再使用的技能,合并重复的技能

团队协作里最大的挑战不是技术,而是习惯。很多人习惯了“跟 AI 随便聊聊”的方式,不愿意花时间写技能文件。我的做法是先在一个小项目里试点,让团队看到效果,再逐步推广。

6.4 技能库的长期演进方向

从我个人使用经验来看,技能库的演进大概会经历几个阶段:

第一阶段是单点技能,针对具体任务写技能文件,解决重复沟通的问题。第二阶段是技能组合,把相关技能串成工作流,覆盖完整开发流程。第三阶段是自适应技能,技能能根据项目状态和上下文自动调整参数和步骤。

目前大多数团队还在第一阶段和第二阶段之间。第三阶段需要更复杂的机制,比如技能能读取项目配置文件、能根据测试覆盖率动态调整约束等。这些还在探索中,但方向是明确的:让技能从“静态文档”变成“动态策略”。

我在实际使用中最大的体会是,技能库的价值不在于写了多少技能,而在于你是否真的在用。我见过有人花了一周写了二十个技能,结果日常开发还是靠手动提示。技能库只有融入日常工作流,才能产生复利效应。所以我的建议是:从一个小技能开始,用起来,再慢慢扩展。不要追求大而全,追求“今天比昨天少说一句重复的话”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询