最近有个团队负责人来找我,说他用 Claude Code 写业务代码时遇到一个很憋屈的问题:明明同一个项目,上午刚告诉它技术栈是 React + TypeScript、测试用 Vitest、提交信息要按 Conventional Commits 写,下午换个会话再问,它又变回一套通用回答。这其实是很多重度使用者的共同痛点——每次新开对话都在给 AI 做“入职培训”,而它永远记不住。后来我把这些项目约束和常用流程整理成了 Claude Code Skills,情况才有了质的变化:AI 的输出风格稳定了,代码审查清单、测试模板这些重复劳动也省了一大截。这篇文章我想把你把 Skills 的完整用法讲透,从它解决什么问题、文件怎么写、到怎么调试触发机制,全是实操经验。如果你每天要花大量时间向编程助手解释项目背景,或者想让 AI 真正贴合团队的做事方式,这篇指南基本可以当一本手册来翻阅。
1. 为什么需要 Skills:先回答“这玩意到底解决什么问题”
1.1 每次开新会话,都在重复做“入职培训”
用 Claude Code 写过一段时间的人应该都有这种体验:对话一开始,先花几分钟把项目背景、技术栈、目录结构、代码风格交代一遍,然后才敢让它干活。遇到大项目,这份“口头简历”甚至要写几百字,占掉的上下文窗口够聊几十轮问题。我以前也这么干,后来才发现一个更隐蔽的坑——不同会话里你交代的措辞不可能完全一样,AI 的理解也就跟着飘。同一个需求,上午说“请按团队规范生成组件”,下午说“帮我把这个页面写出来”,结果往往差得挺多。
这背后的原因不复杂:通用模型的知识是平均值,它没有你团队的编码习惯,也不知道这个仓库里的隐含约定。你把规则口述一遍,它能听懂一部分,但那些话挂在对话上下文里既不持久也不稳定。最典型的场景就是代码审查:你说“重点看性能和安全性”,它可能只挑出几处命名不规范的小问题。问题不在模型能力,而在于它缺少一份可复用的判断依据。Skills 解决的正是这个“每次都要重新培训”的痛点。
1.2 Skills 是把“口头交代”变成“岗位说明书”
所以我一直习惯把 Skills 类比成“岗位说明书”而不是“对话技巧”。临时交代是口头的、一次性的、说完就忘;技能文件是写下来的、可维护的、放进仓库就能跟着代码走。我常用一张表来解释两者的差异:
| 对比项 | 临时交代 | Skills 技能文件 |
|---|---|---|
| 保存位置 | 当前对话上下文,随会话消失 | 项目或用户级目录,持久存在 |
| 生命周期 | 会话结束即失效 | 跨会话、跨项目持续可用 |
| 稳定性 | 措辞一变,结果就变 | 同一份流程,稳定输出 |
| 维护方式 | 每次重新描述 | 改一次文件,全局生效 |
这个转变的本质,是把“每次重新培训实习生”变成“给老员工一本操作手册”。AI 还是那个 AI,但它能做事的标准变了:它不再是靠猜来理解你的偏好,而是按你定义好的流程执行。尤其在团队协作场景里,技能文件可以被所有成员共享,大家用同一套标准让 AI 干活,输出的一致性会好很多。
1.3 哪些场景适合沉淀成技能,哪些不适合
技能不是万能药,选错场景反而增加维护负担。我的判断标准很简单:高频、规则明确、结果可预期。
适合沉淀成技能的场景包括:团队编码规范约束、测试用例生成流程、代码审查清单、新项目初始化、文档模板、命令速查等。这些任务的共性是需要反复执行,而且你心里早就有一套稳定的做法,只是每次都要重新教给 AI。
不适合的场景我也踩过:一次性任务、每次需求都大幅变化的工作流、依赖大量实时外部数据的操作。如果一个流程三个月才用一次、每次调用时目标都不一样,把它做成技能就是在给自己找事。技能文件同样需要维护,过时的规则比没有规则更麻烦——AI 会严格按照过时的描述,输出你已经不需要的东西。
2. 拆解一个技能文件:学会看结构,就会写内容
2.1 技能文件放哪里:项目级与用户级
Claude Code Skills 的基本单位是一个目录,里面必须有一个 SKILL.md 文件。按作用范围有两种放法。
- 项目级:放在项目根目录的
.claude/skills/<技能名>/SKILL.md。技能会跟代码仓库一起提交,团队成员 clone 下来后就能自动使用。团队共享的技能基本都放这里。 - 用户级:放在用户目录下的
.claude/skills/<技能名>/SKILL.md。适合跨项目复用,比如你自己的代码风格偏好、通用的 Git 操作流程。
技能名建议用短横线命名(kebab-case),比如code-review、test-generator、project-init。命名越接近日常口头说法越好,因为后续调试触发时,你会直接用这些名字跟 AI 对话。目录里不一定只放一个文件,技能内容一长,可以建一个references/子目录放详细参考资料,让主文件保持精简。AI 需要时再去参考资料里找细节,这样能减少不必要的上下文占用。
2.2 frontmatter 是触发开关,description 要往细了写
每个 SKILL.md 的开头都有一段 YAML frontmatter,它是整个技能的控制信息。尤其是description字段,直接决定 AI 什么时候加载这个技能。我常用的一个样例长这样:
--- name: frontend-code-review description: 当用户要求审查前端代码、评估 MR 或提交质量、检查组件性能与安全问题、希望按团队规范输出问题时使用。输出包含问题清单、严重级别和修改建议,不适用于解释代码逻辑。 ---很多人会把 description 随便写一句“处理代码审查”,但这样效果很差。前面的字段里我刻意把三样东西写全了:动作词(审查、评估、检查)、对象(前端代码、组件、提交质量)和输出承诺(问题清单、严重级别、修改建议)。为什么要这样?因为触发机制看的是语义匹配,描述写得越贴近真实对话的措辞,命中率越高。
再补充一个缩小误触发的技巧:如果某个技能的描述跟其他技能重叠,可以在 description 末尾加一句“不用于……”的排除场景。比如代码审查技能里写上“不适用于解释代码逻辑”,就能显著减少无关请求的误触发。
2.3 正文内容:一份技能文件的标准骨架
frontmatter 写完后,正文才真正决定技能干活的质量。我试过好几种写法,最稳的是四段式结构:
- 角色与目标:用一两句话说清楚 AI 要以什么身份、达成什么结果。比如“以资深前端工程师身份,按团队规范审查代码并输出可执行建议”。
- 使用前提:列出需要用户提供的输入,比如代码路径、Git diff、项目类型;如果输入缺失,要求 AI 主动询问而不是瞎猜。
- 执行步骤:编号列出核心动作,每步配简短示例,让 AI 有明确的执行顺序。
- 约束边界:写清楚不能做什么、输出格式是什么、什么情况下可以提前终止。
这套骨架最有用的一点,是把模糊的“帮我看看代码”变成可执行的“先读文件,再按顺序做三步检查,最后按固定模板输出”。我见过不少技能文件写成了提示词大杂烩,内容没有结构化,AI 执行时经常跑偏。
这里还有一句重要的安全提醒:技能文件可能随仓库分发到全体成员手里,所以不要把内网地址、真实证书路径、私有化命名或敏感凭据写进正文。你要固化的是做法和标准,不是给个人专用的环境信息。
3. 三个高频技能,直接照着改就能用
3.1 代码审查技能:让 AI 按团队规范帮你把关
先看一个我目前用最频繁的技能:前端代码审查。完整技能文件大致如下。
--- name: frontend-code-review description: 当用户要求审查前端代码、评估 MR 或提交质量、检查组件性能与安全问题、希望按团队规范输出问题时使用。输出分级问题清单,不用于解释代码逻辑。 --- # 前端代码审查 ## 角色与目标 以资深前端工程师身份,审查用户提供的代码或改动,输出可执行的分级问题清单。 ## 使用前提 - 需要用户提供代码片段、文件路径或 Git diff。 - 如果只有路径,先读取相关文件再审查;如果缺少改动范围,先在仓库中定位改动内容。 ## 执行步骤 1. 确定审查范围,读取对应代码。 2. 按顺序检查以下方面: - 安全:潜在 XSS、敏感信息泄露、危险的第三方调用。 - 性能:高频重渲染、重复计算、不合理的大数据遍历。 - 可维护性:命名是否清晰、组件职责是否单一、逻辑复杂度。 3. 输出问题清单,每条包含:位置、严重级别(P0/P1/P2)、问题说明、修改建议。 4. 若问题超过 10 条,优先列出 P0 和 P1,其余合并说明。 ## 约束边界 - 只输出建议,不直接修改代码文件。 - 不讨论与本次审查范围无关的业务逻辑。逐段看几个关键设计。第一步先“确定审查范围”而不是上来就挑刺,是为了避免 AI 在用户只给一个文件路径时把整个项目翻个底朝天。审查顺序固定为安全、性能、可维护性,是刻意安排的优先级,因为人工 review 最怕把时间花在命名这种小事上,漏掉真正致命的问题。超 10 条先列 P0/P1 也是从团队协作角度补的,AI 一口气输出二十多条建议时,成员反而不知道先改哪个。最后“只输出建议,不修改文件”这条边界,是为了防止 AI 在审查场景里顺手改代码,造成你不知情的变更。
3.2 测试生成技能:把“写测试”变成固定流水线
测试生成是另一个高频场景。默认状态下的 AI 脚本往往测试名随意、断言太弱、边界缺失,手工修改成本很高。我在技能里强制规定了完整流程:
--- name: test-generator description: 当用户要求为模块、组件或函数编写测试用例,或要求补充单测覆盖时使用。按团队测试规范生成 describe/test 结构,包含正常、边界、异常三类场景。 --- # 测试用例生成 ## 角色与目标 以测试工程师身份,为指定代码生成结构清晰、断言有效的测试用例。 ## 使用前提 - 需要知道被测对象:文件路径或函数名。 - 缺少测试框架时,询问用户使用 Vitest、Jest 还是其他框架,不自行猜测。 ## 执行步骤 1. 读取源码,识别公开接口、导出函数与核心逻辑分支。 2. 列出需要覆盖的行为清单:正常路径、边界条件、异常输入。 3. 按团队约定生成 describe/test 结构,测试描述使用“应当……”句式。 4. 断言优先使用行为匹配方式,避免脆弱的快照断言。 5. 输出测试文件位置与运行方式说明。 ## 约束边界 - 不为内部工具函数生成无意义测试。 - 不修改被测源码。这个技能里最关键的是第 1 步“读取源码再列行为清单”。默认写法看到函数名就猜测试逻辑,代码一复杂就容易生成一堆无效用例。第 2 步把三类场景固定下来,才能保证覆盖不是象征性的一两行断言。用过一段时间后,团队反馈测试质量提升明显,至少“测试写了等于没写”的情况少了很多。
3.3 项目初始化技能:新项目少踩 80% 的坑
新项目启动最烦的,是 AI 默认生成一套通用配置,跟团队标准完全对不上。我在项目里用project-init技能,把初始化流程固化下来,核心内容如下:
--- name: project-init description: 当需要初始化一个新的前端项目、配置工程化基建、搭建目录结构或生成本地开发配置时使用。按团队标准生成配置,不自行添加未确认的依赖。 --- # 项目初始化 ## 角色与目标 以工程化负责人身份,按团队标准完成新项目脚手架搭建与配置写入。 ## 使用前提 - 向用户确认:项目类型(应用或库)、包管理器(npm/pnpm/yarn)、是否需要初始化 Git。 - 如果用户描述不完整,先确认再执行,不猜测。 ## 执行步骤 1. 按确认结果选择对应模板。 2. 生成项目目录结构,包含 src、tests、config 等约定目录。 3. 写入 ESLint、Prettier、TypeScript 等配置文件,内容来自团队规范。 4. 添加最小可运行示例与 npm scripts。 5. 校验命令可运行,并给出启动说明。 ## 约束边界 - 不得安装用户未确认的依赖。 - 不得跳过目录结构中的团队约定。 - 初始化完成后不自动提交 Git。这个技能的“先确认再执行”是核心。初始化流程在不同场景下差异很大,如果 AI 猜错包管理器,后面整个配置链都会出问题。加了这个前提后,项目初始化的一把过率高出不少。通用版本建议放在用户级目录,项目特殊的扩展规则再放到项目级目录覆盖或补充。
4. 触发、优先级与协作:实测后的调优经验
4.1 触发机制不是单纯的关键词匹配
我刚开始用 Skills 时,以为触发就是“对话里含某个关键词就调用”,实际用下来完全不是这样。按我的理解,系统会根据当前对话的语义去匹配你写的 description,有点像语义搜索引擎,只有描述与用户意图足够接近时才会激活。这就带来两个问题:描述太窄,用户话术一变就不触发;描述太宽,无关对话也会触发。
所以我给每个技能都准备了一组“测试咒语”。以代码审查技能为例,我会分别输入“审查下这段代码”“帮我 review 一下这个 MR”“检查一下组件有没有安全问题”,观察哪个能触发、哪个漏掉,然后针对性调整 description。这个办法不需要额外工具,就是在对话里多试几句。实测下来,描述里同时包含动作词、对象词和输出词,比单放一个名词要容易命中得多。
4.2 多技能并存时的冲突处理
技能一多,冲突就来了。最常见的问题是code-review和security-review这类技能描述相似,用户一句“检查一下这段代码”,两个技能同时处于可激活状态,AI 只能选一个或者直接混乱。我处理冲突的办法有三个:
- 差异化描述:不同技能写清适用场景,比如代码审查侧重“提交前质量检查、可维护性、性能”,安全审查侧重“安全漏洞、隐私泄漏、攻击面”。
- 添加排除句:在 code-review 的 description 末尾写“不用于独立的安全专项审计,如需安全审计请使用安全审查技能”。
- 合并同类项:如果两个技能本质是同一件事的不同阶段,直接合并成一个,用步骤分支区分,而不是拆成两个文件。
别指望靠目录位置或文件命名来决定优先级,真正管用的是 description 的边界设计。边界越清晰,AI 选错的概率越低。
4.3 Skills 与 CLAUDE.md 的分工:别把两件事混在一起
Claude Code 里还有一个全局指令文件 CLAUDE.md,很多人会疑惑它和 Skills 的关系。我的实践经验是:CLAUDE.md 放“无论做什么都适用的偏好”,Skills 放“特定任务才需要的流程”。
举例来说,“永远使用 TypeScript”“提交信息遵循 Conventional Commits”“不要在注释里写中文”属于全局偏好,放 CLAUDE.md 合适。而“代码审查的具体检查清单”“测试用例生成模板”“项目初始化步骤”是任务型流程,属于 Skills。两者是互补关系,不是替代关系。
踩过的坑是:有一段时间我把大量全局规则写进 CLAUDE.md,AI 每次响应都要背上沉重的前置条件,连简单问答都显得啰嗦。反过来,如果只有 Skills 而 CLAUDE.md 为空,AI 又会丢失基本信息。现在我的做法是 CLAUDE.md 保持精简,只写跨任务的偏好,把“怎么做”交给技能文件。
5. 常见问题与排查技巧实录
5.1 高频问题速查表
整理一份我经常遇到的排查速查表,按“现象—可能原因—解决办法”展开:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 技能一直没有触发 | description 太窄,缺动作词或场景词 | 在描述中补充同义短语、输出承诺和排除句 |
| 无关对话也触发技能 | description 太宽泛 | 增加“不用于……”排除场景,缩小适用边界 |
| 触发的是另一个技能 | 两个技能描述相似,语义重叠 | 重构两个技能的适用场景,明确分工 |
| 技能触发了但输出不像技能内容 | 正文步骤不够明确,或与用户输入格式冲突 | 检查 SKILL.md 是否采用“步骤 + 示例”结构 |
| 修改技能文件后测试没变化 | 会话级缓存或没有重启会话 | 重开一个新会话再测,确认文件路径拼写正确 |
| 团队 clone 后看不到技能 | 技能放在了用户级目录 | 把团队共享技能挪到项目级.claude/skills/ |
这张表看起来简单,但每一条都是真实处理过的。最容易被忽略的是最后一条,有人把技能写在自己电脑的用户目录里,推到项目里团队成员当然用不上。团队协作场景下,技能文件写进仓库和写进本地目录,效果完全是两回事。
5.2 两个让我印象深刻的调试现场
第一次是给某项目配代码审查技能,我写了特别长的 description,把所有能想到的触发词都堆进去,结果反而频繁误触发——“解释一下这段代码逻辑”这种纯解释类请求也会启动审查流程。后来把描述改成“输出包含分级问题清单……不用于解释代码逻辑”,误触发立刻少了很多。这让我明白触发优化不是堆关键词,而是定义边界。
第二次是测试生成技能在某仓库里怎么都不生效,排查一圈才发现用户级目录和项目级目录各有一个同名技能,项目级的加载顺序把我的版本覆盖了。处理方式是把两个技能合并,统一放到项目级目录,并给技能名加了项目前缀。这件事之后,我每次新建技能都会先查一遍有没有同名冲突。
写到最后,分享一个我坚持的小习惯:在每个技能文件的末尾加一段“变更记录”,写上修改日期和原因。技能文件跟代码一样会持续演化,团队规范一变,AI 的行为就必须跟着变,没有维护记录的技能过几个月自己都看不懂当初为什么写那条规则。很多人问我“到底需要多少个技能”,我的回答一直是从两个开始——一个解决最高频的重复劳动,一个覆盖最常犯的规范问题,跑顺了再继续加。做技能这件事,门槛不高,难在坚持迭代。把一次次对话里沉淀出的经验,一点一点固化成 AI 的工作习惯,这才是让它真正成为你专属专家的捷径。