ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

agent-skills 实战:从零构建可复用的 AI 编码能力单元

agent-skills 实战:从零构建可复用的 AI 编码能力单元 1. 从“agent-skills”说起为什么它值得单独拎出来聊第一次看到agent-skills这个词是在翻 Claude Code 相关生态的时候。当时我的第一反应是这不就是把“提示词工程”换了个马甲吗但真正上手用了一段时间、又自己动手拆过几个 skill 之后我改变了看法。agent-skills本质上是一套给 AI coding agent 用的能力封装规范它把过去散落在各个 prompt 模板、系统提示、项目约定里的“怎么让 AI 按我的规矩干活”这件事收敛成了一种可复用、可版本管理、可组合的结构化单元。说白了以前你用 Claude Code 写代码每次开新会话都得重新交代一遍“我们项目用 pnpm 不用 npm”“测试必须用 TDD 流程”“提交前跑 lint”。现在这些约定可以打包成一个 skillagent 在合适的时机自动加载不用你反复念叨。这就是agent-skills最直接的价值把重复的上下文交代变成一次性的能力沉淀。它适合谁我觉得有三类人最该关注。第一类是重度使用 Claude Code、Cursor 这类 AI coding agent 的开发者尤其是团队里负责定规范的那个人第二类是想把内部工具链、私有流程“喂”给 AI 的工程团队第三类是对 AI agent 架构感兴趣、想理解“能力层”怎么设计的技术人。哪怕你只是刚装好 Claude Code 的新手理解 skill 的概念也能让你少走很多弯路——因为你会明白为什么有些操作 agent 做得又快又准有些却总是跑偏。这篇文章我不打算写成官方文档的复述。我想做的是把agent-skills这套东西拆开讲清楚它的设计逻辑、一个 skill 到底由什么组成、怎么从零写一个能用的 skill、以及我在实操中踩过的那些坑。中间会穿插 Claude Code 的安装配置、TDD 流程怎么和 skill 结合、常见报错怎么排查这些具体问题。内容会比较长但都是能直接抄作业的干货。2. agent-skills 的整体设计与核心思路拆解2.1 为什么需要“技能”这一层抽象要理解agent-skills得先理解当前 AI coding agent 的一个根本矛盾模型的通用能力和项目的特殊约定之间存在一道鸿沟。模型再强它也不知道你们团队那个祖传的构建脚本为什么要先跑一个 Python 脚本再跑 make它也不知道你们的测试规范要求每个 PR 必须带一个失败用例先红后绿。传统的解法是把这些都塞进系统提示或者CLAUDE.md这类项目记忆文件里。这招在项目小的时候管用但一旦约定变多问题就来了提示词越来越长模型注意力被稀释而且这些约定是“全局常驻”的不管当前任务需不需要都占着上下文。更麻烦的是它们没法按需加载、没法组合、没法单独测试。agent-skills的思路是引入一层按需加载的能力单元。每个 skill 是一个独立目录里面有说明文档、有可选的脚本、有触发条件。Agent 在运行时根据当前任务判断“这个活需要哪个 skill”然后只把那部分内容加载进上下文。这就像给 agent 配了一个工具箱而不是让它背着一整本说明书干活。这个设计的好处很实在。上下文利用率高了因为无关的 skill 不占 token可维护性好了每个 skill 可以单独迭代、单独 review可组合性强了一个复杂任务可以串起好几个 skill。我实测下来把项目里最常用的五六个约定做成 skill 之后新会话的“热身时间”明显缩短agent 第一次尝试就踩对点的概率高了不少。2.2 skill 的目录结构与文件约定一个标准的 skill 目录核心是这么几样东西。最外层是 skill 的名字目录比如test-driven-development/。里面通常有一个SKILL.md作为主入口这是 agent 读取的核心文件用自然语言描述这个 skill 是干什么的、什么时候用、怎么用。除此之外可以有scripts/放辅助脚本references/放参考资料assets/放模板文件。SKILL.md的写法有讲究。它开头一般有一段 frontmatter 或者明确的元信息区声明 skill 的名称、描述、触发关键词。描述要写得让 agent 能判断“什么场景该用我”。我见过有人把描述写成“这是一个测试相关的 skill”太模糊了agent 根本不知道该不该加载。好的描述应该是“当用户要求编写新功能、修复 bug 或重构代码且项目采用测试驱动开发流程时使用本 skill”。正文部分就是具体的指导内容。这里有个经验不要写成教程要写成给 agent 的操作指令。教程是给人看的会解释背景、会铺垫给 agent 的指令要直接、结构化、可执行。比如不要写“测试驱动开发是一种先写测试再写实现的开发方法它的好处是……”而要写“执行以下步骤1. 先根据需求编写一个会失败的测试用例2. 运行测试确认它失败3. 编写最小实现让测试通过4. 重构”。2.3 触发机制agent 怎么知道该用哪个 skill这是很多人第一次接触时最困惑的点。Skill 不是自动全量加载的agent 需要先“发现”有哪些 skill 可用再“决定”加载哪个。发现阶段通常靠扫描 skill 目录读取每个SKILL.md的元信息形成一个可用 skill 的清单。这个清单本身很轻量只包含名称和简短描述。决定阶段就依赖模型的判断了。当用户提出一个任务agent 会拿任务描述去匹配各个 skill 的描述和触发关键词。匹配上了就加载完整内容匹配不上就不加载。所以描述写得准不准直接决定了 skill 会不会在该用的时候被用上。我踩过的坑就是描述写得太窄结果 agent 只在特定措辞下才触发换个说法就失灵了。后来我把触发场景列得宽一些命中率就上来了。还有一种显式触发的方式就是用户在对话里直接点名比如“用 TDD skill 来做这个功能”。这种方式最可靠适合你知道自己需要什么的时候。实际使用中我建议两者结合日常靠自动匹配关键任务靠显式点名兜底。2.4 和 Claude Code 生态的关系agent-skills不是某个工具的专属功能它更像是一种约定俗成的规范Claude Code 是把它落地得比较完整的代表。在 Claude Code 里skill 可以放在项目目录下也可以放在用户全局目录下。项目级的 skill 跟着仓库走团队共享全局级的 skill 跟着人走个人习惯。Claude Code 加载 skill 的时机和它的 agent 循环是绑定的。当它规划一个任务、决定要调用工具或者执行命令之前会先看看有没有相关 skill 能提供指导。这个机制让 skill 天然适合承载“流程性知识”——那些不是单次问答能解决、而是需要多步骤执行的任务。理解了这一层你就能明白为什么agent-skills和test-driven-development这类关键词会绑在一起。TDD 本身就是一个强流程、多步骤、有明确红绿重构节奏的方法论把它做成 skillagent 每次做功能开发时都能按这个节奏走而不是想起来才用。这就是 skill 的威力把最佳实践从“需要人记得”变成“agent 默认执行”。3. 核心细节解析与实操要点3.1 写一个 SKILL.md 的完整结构我拿一个实际写过的 TDD skill 来拆。目录叫tdd-workflow/里面只有一个SKILL.md因为逻辑不复杂不需要额外脚本。文件开头是这样的元信息区--- name: tdd-workflow description: 当需要开发新功能、修复缺陷或重构现有代码时使用。引导 agent 遵循红-绿-重构的测试驱动开发流程确保每次代码变更都有测试覆盖。 triggers: - 写新功能 - 修复 bug - 重构 - 加测试 ---这个 frontmatter 是给 agent 做匹配用的。description要同时说清楚“什么时候用”和“用了能得到什么”。triggers是关键词列表覆盖用户可能的各种说法。注意这里我用了中文触发词因为我的使用场景主要是中文对话。如果你的团队中英混用两种都列上。正文部分我分成几块。第一块是流程总览用编号列出红绿重构的四个阶段。第二块是每个阶段的详细指令包括具体要执行什么命令、判断标准是什么。第三块是禁止事项比如“不允许在测试失败之前编写实现代码”“不允许跳过重构阶段”。第四块是常见例外情况比如“如果是纯配置修改且无逻辑变更可豁免测试要求”。这个结构的关键在于指令要可判定。什么叫可判定就是 agent 执行完能明确知道自己做对没有。比如“运行测试并确认输出包含 FAILED”就是可判定的“确保测试质量良好”就不可判定。写 skill 的时候要时刻问自己这条指令 agent 能不能自己验证3.2 触发描述的写法与常见误区触发描述写得好不好直接决定 skill 的命中率。我总结了一个简单的公式动作 对象 场景限定。动作是用户想干什么对象是干在什么东西上场景限定是排除掉不该触发的情况。举个例子。差的写法“处理测试相关任务”。这个太宽agent 可能在你只是想看看测试报告的时候也加载它。好的写法“当用户要求新增功能、修改现有逻辑或修复缺陷且需要产出可运行的代码变更时使用。不适用于仅查看测试结果、仅讨论测试策略的场景。”另一个误区是描述里堆砌太多同义词。有人觉得多写点触发词命中率就高结果写了一大串近义词反而让描述变得模糊。我的做法是核心触发词三到五个覆盖最主要的说法就行剩下的靠 description 的语义匹配。模型理解语义的能力比关键词匹配强得多不用太担心漏掉某种说法。还有一个细节描述里要体现 skill 的边界。明确写出“不适用于什么”能有效减少误触发。比如一个部署 skill要写清楚“仅适用于生产环境部署不适用于本地开发环境启动”。这样 agent 在本地调试时就不会去加载部署流程。3.3 脚本与资源的组织方式不是所有 skill 都只靠文字指令。有些流程需要跑脚本、读模板、查参考文档这时候就要用到scripts/、assets/、references/这些子目录。scripts/里放的是可执行脚本。比如一个代码生成 skill可能带一个根据模板生成骨架代码的 Python 脚本。Agent 在执行 skill 时可以直接调用这些脚本比让它自己现写要可靠得多。脚本要用常见的解释器Python 和 Node 最稳妥因为大多数开发环境都有。脚本的输入输出要设计得简单最好是通过命令行参数传入、通过标准输出返回方便 agent 调用和解析。assets/放模板文件。比如一个写技术文档的 skill可以放一个 Markdown 模板agent 生成文档时直接套用。模板的好处是保证输出格式一致不会这次一个样下次一个样。references/放参考资料。比如一个涉及内部 API 的 skill可以把 API 文档的摘要放这里agent 需要时读取。注意参考资料要精简只放 agent 真正需要的那部分不要把整本手册塞进去否则又回到上下文膨胀的老问题。我个人的经验是能用文字指令解决的就别加脚本。脚本增加了维护成本和出错点。只有当某个操作 agent 自己做得不稳定、或者有明确的确定性要求时才值得写脚本。比如格式化输出、调用特定 CLI 工具这类脚本比自然语言指令靠谱。3.4 版本管理与团队协作Skill 是代码资产应该纳入版本管理。我建议把项目级 skill 放在仓库的.agent-skills/或者类似目录下跟代码一起提交。这样 skill 的变更可以走 code review可以追溯是谁在什么时候改了什么。团队协作时有个实际问题不同人对同一个流程的理解可能不一样。比如 TDD 到底要不要强制先写测试团队里可能有人觉得小改动可以例外。这种分歧应该在写 skill 的时候就讨论清楚而不是让 agent 每次随机选一种做法。Skill 文件其实是一个很好的“流程共识载体”把口头约定变成书面规范。我还建议给 skill 加一个简单的变更记录在SKILL.md末尾或者单独一个CHANGELOG.md里记一下每次改了什么、为什么改。这样当 agent 行为发生变化时能快速定位是不是 skill 改动导致的。4. 实操过程与核心环节实现4.1 环境准备Claude Code 的安装与配置要跑通agent-skills的完整流程得先把 Claude Code 装好。不同系统的安装方式不太一样我分别说下我实际操作过的路径。macOS 上最省事的是用官方安装脚本一条命令搞定。装完之后在终端输入claude能拉起交互界面就说明成功了。Ubuntu 上稍微麻烦一点需要先确认 Node 环境然后通过包管理器安装。我遇到过 Ubuntu 上权限报错的情况一般是全局安装目录没有写权限改一下 npm 的 prefix 或者用 sudo 都能解决但更推荐改 prefix避免后续权限混乱。VS Code 用户可以直接装 Claude Code 的插件在扩展市场搜就能找到。装完之后在 VS Code 里打开集成终端插件会自动接管。这里有个配置点要注意插件默认可能用的是内置终端如果你想让它调用系统终端里的 Claude Code需要在设置里指定路径。我一开始没注意这个结果插件和命令行两个环境的行为不一致排查了半天。关于账号注册和不注册的区别主要在于可用模型和额度。不注册也能用一部分功能但高级模型和较长的上下文会受限。如果你只是轻度试用可以先不注册如果要正经做项目建议注册体验完整很多。提示安装过程中如果遇到网络相关的报错先检查本地环境的基础配置是否正常。很多看似是 Claude Code 的问题其实是环境本身的问题。4.2 创建第一个 skill从零到能用我拿一个最简单的场景来演示给项目加一个“提交前检查”的 skill。目标是让 agent 在准备提交代码前自动跑 lint 和测试。第一步在项目根目录建.agent-skills/pre-commit-check/目录。第二步创建SKILL.md写入元信息和指令。指令部分我这样写## 执行流程 1. 运行 pnpm lint检查是否有报错。 2. 如果有报错逐条修复修复后重新运行直到通过。 3. 运行 pnpm test检查测试是否全部通过。 4. 如果有失败用例分析失败原因。如果是本次改动导致的修复如果是既有问题记录并告知用户。 5. 两项都通过后输出“检查通过可以提交”。 ## 禁止事项 - 不允许跳过任何一步。 - 不允许在检查未通过时声称可以提交。 - 不允许修改测试用例来让测试通过除非用户明确要求。第三步测试这个 skill 是否生效。我在对话里说“帮我提交这次改动”观察 agent 是否自动加载了这个 skill 并执行了检查流程。第一次没触发我检查发现是 description 写得太窄只写了“提交代码”而我说的是“提交改动”。把触发词补全后第二次就正常触发了。这个过程中我最大的体会是skill 写完一定要实测触发。光看文件觉得没问题实际跑起来可能因为措辞、路径、加载顺序等各种原因不生效。测试的时候要覆盖几种不同的说法确保触发稳定。4.3 把 TDD 流程做成可复用的 skillTDD 是我用得最多的 skill因为它把“先写测试”这个容易偷懒的步骤变成了强制流程。完整实现如下。SKILL.md的指令部分我分成四个阶段。红阶段根据需求写一个测试用例运行它确认它失败并且失败原因是“功能未实现”而不是语法错误。绿阶段写最少的代码让测试通过不追求优雅只追求通过。重构阶段在测试保持通过的前提下优化代码结构消除重复。循环阶段如果还有未覆盖的需求回到红阶段继续。这里有个关键细节怎么判断测试失败是“正确的失败”。我要求 agent 在红阶段输出失败信息并确认失败信息里包含预期的断言失败而不是导入错误或者语法错误。这个判断标准写进 skill 后agent 就不会拿一个根本跑不起来的测试来糊弄。另一个细节是重构阶段的边界。重构很容易变成“顺便加点功能”这就破坏了 TDD 的节奏。我在 skill 里明确写重构阶段只允许改变代码结构不允许改变行为测试必须保持通过。如果发现需要新功能回到红阶段重新开始。实测下来这个 skill 让 agent 的开发节奏稳定了很多。以前它经常一口气写完实现再补测试现在会老老实实先红后绿。当然也有例外比如改一个错别字这种硬套 TDD 就太僵了。所以我在 skill 里加了一条豁免纯文档、纯配置、纯注释的改动可以不走 TDD 流程。4.4 多 skill 组合与优先级处理实际项目里往往同时有多个 skill比如 TDD skill、代码风格 skill、提交检查 skill。它们可能在同一任务里都被触发这时候就涉及组合和优先级问题。我的处理原则是流程性 skill 优先于风格性 skill。因为流程决定了做事顺序风格是在流程内部生效的。比如 TDD 和代码风格同时触发时先按 TDD 的红绿重构走在写代码的环节再应用风格规范。如果两个 skill 的指令冲突怎么办比如一个 skill 说“提交前必须跑全量测试”另一个说“小改动只跑相关测试”。这种冲突要在写 skill 的时候就避免方法是明确各自的适用范围。全量测试 skill 限定在“发布前”或“合并到主分支前”相关测试 skill 限定在“日常开发迭代中”。范围划清楚了就不会打架。我还试过用一个“元 skill”来协调其他 skill就是在 skill 里写“按以下顺序加载先 TDD再风格最后提交检查”。这种方式适合流程固定的场景但灵活性差一些。大多数情况下靠清晰的描述和范围划分就够了不需要额外的协调层。5. 常见问题与排查技巧实录5.1 skill 不触发怎么办这是最高频的问题。Agent 该用 skill 的时候没用原因通常有这么几个。第一描述和触发词没覆盖用户的实际说法。解决办法是把用户可能的各种表达都列进去或者把 description 写得更语义化一些。第二skill 目录位置不对。项目级 skill 要放在项目根目录下的约定位置放错地方 agent 扫描不到。第三加载顺序问题某些环境下 skill 需要重启会话才生效。我的排查顺序是先确认目录位置再检查 frontmatter 格式是否正确YAML 对缩进敏感很容易写错然后在对话里显式点名 skill 看能不能加载。如果显式点名能加载、自动匹配不行那就是描述问题如果显式点名也不行那就是文件或路径问题。5.2 skill 触发了但执行跑偏有时候 skill 加载了但 agent 没按指令走。常见原因是指令写得太模糊agent 有自己的理解。比如写“运行测试”agent 可能只跑了部分测试或者用了错误的命令。解决办法是把指令写具体明确命令、明确判断标准。另一个原因是 skill 内容太长agent 读到后面忘了前面。这时候要精简把最重要的指令放前面次要的放后面或者移到 references 里。我一般把单个 skill 的正文控制在合理长度内超过就拆分。还有一种情况是 skill 之间互相干扰。比如两个 skill 都提到“运行测试”但要求的命令不一样。这就要检查是否有范围重叠把各自的适用场景写清楚。5.3 常见问题速查表问题现象可能原因排查方法解决方式skill 完全不触发目录位置错误确认 skill 在约定目录下移动到正确位置skill 完全不触发frontmatter 格式错误检查 YAML 缩进和字段名修正格式自动匹配不触发显式点名可以描述或触发词覆盖不足对比用户说法和触发词补充触发词放宽描述触发后不按指令执行指令模糊检查指令是否可判定改为具体、可验证的指令触发后执行到一半停下内容过长注意力分散检查 skill 正文长度精简内容拆分 skill多个 skill 冲突适用范围重叠对比各 skill 的适用场景明确边界划分范围脚本调用失败解释器或路径问题手动运行脚本看报错修正路径或换解释器5.4 几个我踩过的坑第一个坑是在 skill 里写太多背景知识。我一开始把 TDD 的历史、好处、各种变体都写进去了结果 agent 读了一堆背景真正执行的时候反而抓不住重点。后来我把背景全删了只留操作指令效果好很多。Skill 是给 agent 的执行手册不是给人看的科普文。第二个坑是触发词用了太生僻的说法。我写了一个 skill 专门处理数据库迁移触发词里用了“schema evolution”这种词结果日常对话里根本没人这么说skill 几乎没被触发过。后来改成“改表结构”“加字段”“数据库迁移”这些大白话命中率立刻上来了。第三个坑是忘了测试 skill 的边界情况。有个 skill 我测试的时候只测了正常路径上线后发现当用户的需求描述很简短时agent 会误触发。比如用户只说“看看这个”agent 也可能加载 skill。后来我在描述里加了“仅当用户明确提出代码变更需求时使用”误触发就少了。第四个坑是skill 更新后没通知团队。有次我改了一个 skill 的执行流程但没告诉其他人结果他们的 agent 行为突然变了排查了半天才发现是 skill 的问题。现在我改 skill 都会在团队频道里说一声重要的改动还会写进变更记录。6. 进阶玩法与扩展方向6.1 用 skill 承载团队规范Skill 最被低估的用法是把它当成团队规范的活文档。传统规范写在 Wiki 里没人看也没法强制执行。写成 skill 之后agent 每次干活都会按规范走规范从“建议”变成了“默认行为”。我见过一个团队把代码 review 的检查清单做成了 skill。Agent 在提交前会自动对照清单逐项检查比如“是否有未处理的 TODO”“是否有硬编码的密钥”“是否有超过 50 行的函数”。这些检查以前靠人肉 review现在 agent 先过一遍人只需要看 agent 标记出来的问题。效率提升很明显。6.2 skill 与外部工具的集成Skill 可以调用外部工具这让它的能力边界大大扩展。比如一个 skill 可以调用内部的 API 文档查询工具在写代码前先拉取最新的接口定义。也可以调用代码生成器根据数据库表结构自动生成 CRUD 代码。集成的关键是接口要稳定。外部工具的输出格式一变skill 就可能失效。所以我在做集成时会在 skill 里加一层校验确认工具返回的内容符合预期再继续。如果不符合就报错让用户介入而不是硬着头皮往下走。6.3 持续迭代的思路Skill 不是写完就完事的它需要跟着项目一起演进。我的做法是定期回顾哪些 skill 经常被触发但效果不好哪些 skill 几乎没被触发过哪些 skill 的指令已经和当前项目实践脱节了。回顾的时候我会看几个信号。如果某个 skill 触发后 agent 经常需要用户纠正说明指令有问题。如果某个 skill 从来没被触发过要么是描述有问题要么是这个 skill 根本不需要。如果某个 skill 的内容和项目现状对不上比如命令变了、目录结构变了就要及时更新。我个人的体会是skill 的价值不在于数量多而在于每个都真正被用起来、真正解决了问题。与其写十个半吊子 skill不如把两三个核心 skill 打磨到位。我现在项目里常驻的 skill 就四个TDD 流程、代码风格、提交检查、文档生成。这四个覆盖了日常开发的大部分场景用得很顺。最后分享一个小技巧如果你不确定某个流程该不该做成 skill先观察自己在一周内重复交代了多少次同样的事情。如果超过三次那就值得做成 skill。重复交代是最大的浪费而 skill 就是消除这种浪费的工具。
返回列表