ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Claude Code 40个Skill实战:SKILL.md配置与子agent分工指南

2026/9/26 8:34:54 拓冰建站 浏览量
Claude Code 40个Skill实战:SKILL.md配置与子agent分工指南 1. 从“装完就吃灰”说起40个Skill到底改变了什么我大概是在Claude Code刚火起来那阵子开始重度使用的。最开始那两个月我的用法特别朴素打开终端进项目目录敲一句“帮我看看这个报错”然后等它回。能用但也就那样——它像一个记性不错但没什么专长的实习生你问什么它答什么你不问它就不动。直到有一次我在一个前端项目里连续让它改了七遍样式每次都要重新解释“我们用的是Tailwind不是CSS Modules”“组件必须走design system里的Button”我才意识到问题不在模型在我自己我把一个可编程的Agent当成了聊天框在用。后来我开始系统性地往里面塞Skill。从最开始的三五个到后面稳定维持在四十个左右中间踩过的坑、删掉的废Skill、重写的SKILL.md加起来能写一本小册子。这篇就聊聊这四十个Skill是怎么组织的、SKILL.md的frontmatter到底该怎么写、子agent和主agent怎么分工、以及为什么我现在的结论是Skill不是插件是你给Agent写的“岗位说明书”。如果你现在还在“装了一堆Skill但感觉没啥用”的阶段或者你压根不知道SKILL.md里的frontmatter是干嘛的那这篇应该能帮你省下至少两周的试错时间。我会把每个关键决策背后的“为什么”讲清楚参数怎么算、目录怎么放、什么时候该拆子agent、什么时候纯属过度设计都会给到可直接抄的配置。2. Skill的本质不是插件是上下文注入器2.1 为什么“装完没感觉”是常态很多人第一次接触Skill脑子里对标的是VSCode插件或者Chrome扩展——装上就该有按钮、有面板、有可见的变化。但Skill的运行机制完全不是这个逻辑。一个Skill被触发时它做的事情是把一段预先写好的指令文本注入到当前对话的上下文里让模型在生成回复时“顺便”遵守这些约束。它不新增能力它改变的是模型的行为倾向。这就解释了一个特别常见的困惑为什么我装了某个“代码规范Skill”但模型还是写出了不符合规范的代码因为Skill的注入是有条件的——它需要被匹配到。匹配靠的是SKILL.md里frontmatter的description字段和当前对话的相关性。如果你的description写得太泛比如“帮助编写更好的代码”那它要么永远不触发要么到处乱触发两种情况都等于没用。我自己的经验是一个Skill的description写得越具体、越场景化它的触发准确率越高。比如“当用户要求新增React组件时强制使用函数式组件TypeScript项目内design system的Button”就比“React开发规范”强十倍。前者几乎不会误触发后者会在你聊任何前端话题时都跳出来刷存在感。2.2 SKILL.md的frontmatter三个字段决定生死SKILL.md的frontmatter看起来简单但每个字段都有讲究。我见过太多人把frontmatter当摆设随便填两行就往下写正文结果Skill要么不触发要么乱触发。下面是我实际在用的字段结构--- name: react-component-generator description: 当用户要求创建新的React组件、页面或UI模块时使用。强制使用函数式组件、TypeScript、项目内design system组件禁止使用内联样式和any类型。 version: 1.2.0 tags: [frontend, react, typescript] ---name字段看起来最不重要但其实它决定了你在对话里怎么引用这个Skill。我习惯用“领域-动作”的命名法比如react-component-generator、api-error-handler、sql-query-optimizer。这样在子agent配置里引用的时候一目了然不会出现“那个管数据库的Skill叫啥来着”的情况。description是真正的核心。我的写法是“触发条件强制约束禁止事项”三段式。触发条件要写得像if语句一样明确强制约束要具体到可执行禁止事项要列出最常见的错误做法。这三段缺一段Skill的效果就打对折。我实测下来description控制在80到150个字符之间触发最稳定太短了匹配不准太长了模型可能只抓到前半段。version和tags属于锦上添花。version在你迭代Skill的时候有用tags在Skill数量多了之后方便检索。但如果你只装三五个Skill这两个字段可以省。2.3 正文部分写“怎么做”而不是“是什么”frontmatter下面的正文很多人写成了一篇技术文档大段大段解释React的哲学、TypeScript的好处。这是典型的写错了方向。Skill的正文应该是操作指令不是知识科普。模型不需要你告诉它什么是函数式组件它需要你告诉它“在这个项目里新增组件必须放在src/components/下文件名用PascalCase必须导出defaultprops类型必须显式声明”。我现在的写法是分三块执行步骤、代码模板、检查清单。执行步骤用有序列表每一步都是一个可执行的动作。代码模板直接给一个完整的示例文件让模型照着改。检查清单是最后一道防线列出“提交前必须确认”的事项比如“没有使用any”“没有内联style”“import路径使用/别名”。注意Skill正文里不要写“你应该”“你可以考虑”这种软性表述。模型对“必须”“禁止”“强制”这类词的服从度明显更高。我做过对比测试同一个约束用“建议使用函数式组件”和“必须使用函数式组件”后者的遵守率高出将近四成。3. 四十个Skill的分层架构别让它们互相打架3.1 按“触发时机”分四层而不是按“功能”分我最初是按功能分类的前端Skill、后端Skill、数据库Skill、部署Skill。结果很快就乱了因为一个“新增API接口”的任务会同时触发前端、后端、数据库三个Skill它们各自往上下文里塞指令互相覆盖模型直接懵了。后来我改成按触发时机分层问题迎刃而解。四层分别是全局层永远生效不依赖具体任务。比如“代码注释用中文”“提交信息遵循Conventional Commits”“禁止在代码里留console.log”。这层我控制在5个以内多了会稀释注意力。领域层按技术栈触发。React、Node、Python、SQL各一个描述里写清楚“当任务涉及X技术栈时使用”。这层大概15个。任务层按具体动作触发。比如“新增组件”“写单元测试”“优化查询”“处理错误”。这层大概12个。项目层只对特定项目生效。比如某个老项目的“禁止使用可选链”“必须兼容IE11”。这层大概8个。分层的核心逻辑是同一时刻只让一层到两层的Skill生效。全局层永远在领域层按技术栈匹配任务层按动作匹配项目层按目录匹配。这样上下文里同时活跃的Skill不会超过四个模型能处理得过来。3.2 用目录结构做隐式分层Claude Code读取Skill的方式是扫描特定目录下的SKILL.md文件。我利用这个机制用目录结构做了隐式分层.claude/skills/ ├── global/ │ ├── commit-convention/SKILL.md │ ├── no-console-log/SKILL.md │ └── chinese-comments/SKILL.md ├── domain/ │ ├── react/SKILL.md │ ├── node/SKILL.md │ └── sql/SKILL.md ├── task/ │ ├── new-component/SKILL.md │ ├── unit-test/SKILL.md │ └── error-handler/SKILL.md └── project/ └── legacy-admin/ └── ie11-compat/SKILL.md这样做的好处是当我要临时禁用某一层的时候只需要把对应目录移走或者改个名。比如我在做原型验证的时候会把project/整个目录临时移走避免老项目的约束拖慢新项目的开发速度。3.3 冲突检测两个Skill说反话怎么办Skill之间打架是必然会发生的。我遇到过最典型的一次全局层有个“禁止使用any类型”任务层有个“快速原型开发”的Skill里写了“允许使用any以加快速度”。两个同时触发的时候模型的行为变得很不稳定有时候用any有时候不用。我的解决方法是加一个优先级声明。在frontmatter里加一个priority字段数值越大优先级越高。全局层默认100领域层默认80任务层默认60项目层默认40。当两个Skill的指令冲突时模型会倾向于遵守高优先级的那个。但这个机制不是硬性的所以我还会在低优先级的Skill里显式写“当与全局规范冲突时以全局规范为准”。提示与其事后检测冲突不如在写Skill的时候就约定好“全局层永远最高优先级”。这样你只需要保证全局层的Skill足够精简和正确剩下的层就算有冲突也不会出大问题。4. 子agent与主agent分工的边界在哪里4.1 主agent做决策子agent做执行主agent和子agent的关系我理解成“项目经理和外包团队”。主agent负责理解需求、拆解任务、决定调用哪个子agent、汇总结果。子agent负责在特定领域内深度执行它不需要知道全局只需要把手头的活干好。这个分工的关键在于子agent的上下文是独立的。主agent把任务描述和必要的上下文传给子agent子agent在自己的上下文里执行执行完把结果返回给主agent。这意味着子agent不会被主agent上下文里的其他信息干扰专注度更高。我实际用下来最适合拆子agent的场景有三类需要大量搜索的任务比如“在整个代码库里找出所有用了废弃API的地方”、需要独立验证的任务比如“写完之后让另一个agent检查一遍”、需要并行处理的任务比如“同时给五个文件加测试”。4.2 子agent的配置三个参数决定成败子agent的配置我一般只关注三个参数--- name: code-reviewer description: 当需要审查代码质量、检查潜在bug、验证规范遵守情况时使用。 model: claude-sonnet skills: [global/no-console-log, domain/react, task/unit-test] ---model参数决定用哪个模型。我的经验是执行类任务用快模型审查类任务用强模型。因为审查需要更强的推理能力来发现隐蔽问题而执行类任务更多是照着模板改快模型足够。skills参数决定子agent加载哪些Skill。这里有个容易踩的坑不要给子agent加载全局层的Skill。全局层的约束应该由主agent在传递任务时以文字形式带过去而不是让子agent自己去读。因为子agent的上下文窗口有限加载太多Skill会挤占执行任务的空间。description参数决定主agent什么时候调用这个子agent。写法和Skill的description一样触发条件要具体不要写“用于代码审查”这种泛泛的描述要写“当主agent完成代码生成后需要独立验证时使用”。4.3 一个实际的任务拆解案例我拿一个真实任务来演示给一个React项目新增一个“用户列表”页面包含搜索、分页、排序功能。主agent的思考过程是这样的首先识别出这是一个前端任务触发domain/react和task/new-component两个Skill。然后它把任务拆成四步生成组件骨架、实现搜索逻辑、实现分页逻辑、实现排序逻辑。接着它决定调用一个子agent来生成组件骨架因为这一步需要严格遵循design system的规范独立执行更不容易出错。搜索、分页、排序三步由主agent自己完成因为这三步之间有依赖关系放在同一个上下文里更容易保持一致。子agent收到任务后加载task/new-component和domain/react两个Skill生成骨架代码返回给主agent。主agent拿到骨架后在上面继续实现三个功能最后调用code-reviewer子agent做一遍检查。这个流程我跑了大概二十次每次都能稳定产出符合规范的代码。关键就在于子agent只做一件事主agent负责串联。5. 从零搭建四十个Skill的落地步骤5.1 第一步先写五个全局Skill别贪多新手最容易犯的错是一上来就写二十个Skill结果互相打架体验比不装还差。我的建议是第一周只写五个全局Skill而且这五个必须是“不依赖任何技术栈”的通用约束。我最初的五个全局Skill是commit-convention提交信息必须用Conventional Commits格式type用feat/fix/refactor/docs/test/chore。chinese-comments代码注释和文档用中文变量名和函数名用英文。no-console-log禁止在提交的代码里留console.log调试用logger。error-handling所有异步操作必须有try-catch或.catch错误必须被处理或向上抛。file-naming组件文件用PascalCase工具函数用camelCase常量用UPPER_SNAKE_CASE。这五个Skill我用了两周确认它们不会误触发、不会互相冲突之后才开始加领域层。5.2 第二步领域层按技术栈写一个技术栈一个领域层的Skill我建议一个技术栈只写一个把所有该技术栈的规范都塞进去。比如React的Skill里同时包含“用函数式组件”“用hooks不用class”“样式用Tailwind”“状态管理用zustand”这些约束。不要拆成四个Skill拆了之后触发时机很难对齐。写领域层Skill的时候description要写清楚“当任务涉及X技术栈时使用”。比如React的description我写的是“当任务涉及React组件开发、hooks使用、状态管理、样式处理时使用。强制使用函数式组件和TypeScript禁止class组件和any类型。”这里有个细节领域层的Skill不要写得太长。我实测下来单个SKILL.md的正文控制在500到800字之间效果最好。太短了约束不够太长了模型可能只记住前半段。如果某个技术栈的规范确实很多宁可拆成两个Skill也不要写一个两千字的巨型Skill。5.3 第三步任务层按动作写一个动作一个任务层的Skill是最容易写多的。我一开始写了三十多个后来砍到十二个。砍的标准是这个动作是否足够高频且是否有明确的执行步骤。低频动作不值得单独写Skill写在领域层里带一句就行。我保留的十二个任务层Skill包括新增组件、新增API接口、写单元测试、写集成测试、优化SQL查询、处理错误、重构函数、写文档、生成类型定义、处理表单、处理路由、处理权限。每个任务层Skill的正文结构都一样前置检查做之前要确认什么、执行步骤有序列表、代码模板一个完整示例、后置检查做完之后要验证什么。这个结构我用了大半年稳定可靠。5.4 第四步项目层按目录写一个项目一个项目层的Skill只对特定目录生效。实现方式是在description里写清楚目录路径比如“当操作legacy-admin/目录下的文件时使用”。但更可靠的方式是用Claude Code的目录级配置在项目根目录放一个.claude/skills/里面的Skill只对该项目生效。项目层Skill我一般只写两类兼容性约束比如“必须兼容IE11禁止使用可选链和空值合并”和业务约束比如“金额字段必须用Decimal类型禁止用float”。这两类约束在通用Skill里写不合适因为只对特定项目有效。5.5 第五步迭代而不是一次写完四十个Skill不是一天写完的。我的节奏是第一周五个全局第二周加三个领域第三周加五个任务第四周加两个项目。之后每个月回顾一次删掉三个月没触发过的Skill合并功能重叠的Skill重写触发不准的Skill。实操心得我有个习惯是在SKILL.md的frontmatter里加一个last_triggered字段手动记录最后一次触发的时间。虽然麻烦但能帮我识别哪些Skill是“僵尸Skill”。三个月没触发的要么是description写得太窄要么是这个场景根本不需要Skill。6. 常见问题与排查技巧实录6.1 Skill不触发先查description再查目录Skill不触发是最常见的问题。排查顺序我固定为三步第一步查description是否太泛或太窄太泛会导致匹配不准太窄会导致永远匹配不上。第二步查目录结构是否正确Claude Code只扫描特定目录放错位置等于没放。第三步查是否有同名Skill冲突两个Skill的name字段一样会导致其中一个被覆盖。我遇到过最隐蔽的一次是Skill的description里用了中文标点而模型的匹配逻辑对中文标点的处理有问题导致触发率极低。改成英文标点后恢复正常。这个坑我踩过一次之后就养成了“description里只用英文标点”的习惯。6.2 Skill乱触发加否定条件乱触发比不触发更烦人。我遇到过一个“代码优化”Skill在我聊任何代码话题时都跳出来导致模型总是想重构我的代码哪怕我只是在问一个语法问题。解决方法是在description里加否定条件“当用户明确要求优化代码时使用不要在用户只是询问语法或调试时触发。”否定条件的写法有讲究。不要写“不要在不相关的时候触发”要写具体的排除场景。比如“不要在用户询问API用法、语法细节、错误信息时触发”。越具体排除效果越好。6.3 子agent返回结果不符合预期检查上下文传递子agent返回的结果不符合预期九成是因为主agent传递的上下文不够。子agent的上下文是独立的它不知道主agent之前聊了什么。如果主agent只传了一句“帮我写个组件”子agent只能靠猜。我的做法是主agent在调用子agent时必须传递三样东西任务描述要做什么、约束条件必须遵守什么、参考示例照着哪个文件写。这三样缺一样子agent的产出质量就下降一截。6.4 性能问题Skill太多导致响应变慢Skill数量超过三十个之后我明显感觉到响应变慢了。排查后发现是每次对话都要扫描所有Skill的frontmatter做匹配Skill越多扫描越慢。解决方法是用目录分层把不常用的Skill放到单独的目录里需要的时候再临时启用。另一个优化点是合并低频Skill。我把五个“写文档”相关的Skill合并成了一个触发率没降但扫描负担小了很多。合并的原则是如果两个Skill的触发场景有超过一半的重叠就合并。问题现象最可能原因排查动作解决方式Skill完全不触发description太窄或目录错误检查description关键词和目录路径放宽description或移动目录Skill频繁误触发description太泛或缺否定条件检查触发场景是否具体加具体排除场景多个Skill互相冲突优先级未定义检查是否有指令矛盾加priority字段或显式声明优先级子agent产出质量差上下文传递不足检查主agent传递的参数补全任务描述、约束、示例响应明显变慢Skill数量过多统计活跃Skill数量合并低频Skill或分层加载6.5 一个我踩过的大坑Skill里的代码模板太旧有一次我写了一个“新增API接口”的Skill里面附了一个代码模板。那个模板是我半年前写的用的还是旧版的框架API。结果模型照着模板生成代码跑不起来。我排查了半天才发现是Skill里的模板过期了。从那以后我养成了一个习惯Skill里的代码模板必须和项目里的实际代码保持同步。每次框架升级或者规范调整第一件事就是更新相关Skill里的模板。我甚至在CI里加了一个检查如果Skill里的模板文件和项目里的示例文件差异过大就报警。7. 四十个Skill之后我的真实体会装到四十个Skill之后最大的变化不是我多了四十个功能而是我不再需要反复解释同一件事了。以前每开一个新对话我都要重新说一遍“用函数式组件”“注释写中文”“提交信息用Conventional Commits”。现在这些约束被固化在Skill里模型自动遵守。我的对话从“解释要求纠正”变成了“要求确认”效率提升是实打实的。但我也要泼一盆冷水Skill不是越多越好。我删掉的Skill至少有十五个有些是因为场景太低频有些是因为和其他Skill功能重叠有些是因为写得太复杂反而导致模型困惑。四十个是我目前找到的平衡点但你的平衡点可能不一样。关键是定期回顾把不用的删掉把不好用的重写。最后分享一个我最近在用的技巧给每个Skill写一个“反例”。在SKILL.md的末尾加一段“常见错误做法”列出三到五个模型容易犯的错。比如React组件的Skill里写“不要用index作为key”“不要在useEffect里直接改state”“不要用useMemo包一个简单计算”。这些反例比正面约束更能纠正模型的行为因为模型对“不要做什么”的记忆比“要做什么”更深刻。这个技巧我用了两个月Skill的遵守率从大概七成提升到了九成以上。如果你也在用Skill强烈建议试试。