智能编码进化论

给AI配工具箱:Skills技能实战

约 22 分钟驭光者首发于微信公众号「羲和Lab」

CLAUDE.md是岗位说明书,Skills是工具箱——按需加载、动态注入、子代理执行全攻略

阅读时长约12分钟 | 教程型 | 智能编码进化论 04/10


导读

前两篇我们搞定了两件事:用CLAUDE.md给AI写岗位说明书,用结构化任务输入让AI听懂指令。但有个问题越来越明显——CLAUDE.md越写越长。

API规范、部署流程、代码审查清单、测试模板……全塞进CLAUDE.md里,每次会话不管用不用到都要加载。就像给新员工一本500页的手册让他全背下来,效率不高。

Skills就是解决方案。它是按需加载的"工具箱"——用的时候拿出来,不用的时候不占地方。本章讲清楚:Skills和CLAUDE.md怎么分工、怎么从零创建一个Skill、高级玩法有哪些、踩了坑怎么排查。

一、Skills是什么:工具箱 vs 岗位说明书

CLAUDE.md和Skills的分工

先看一个关键区别:

维度CLAUDE.mdSkills
加载时机每次会话,自动加载按需加载,用到才读
类比岗位说明书(入职必读)工具箱(干活时再拿)
适合内容"永远遵守"的规则参考资料、可复用流程
上下文成本每次都在用的时候才消耗
触发方式自动用户输入/名称 或AI自动匹配

一句话总结:CLAUDE.md放"必须知道"的,Skills放"用到才知道"的。

举个具体例子。你在CLAUDE.md里写"使用RESTful API设计规范"——这是规则,每次都要遵守。但API的具体endpoint列表、请求参数格式、错误码对照表——这些是参考资料,只在写API时才需要。参考资料放到Skill里,写API时输入 /api-guide 加载,平时不占上下文。

经验法则:该写进Skills的三个信号

如果你遇到以下三种情况之一,说明这段内容该从CLAUDE.md迁移到Skills了:

信号一:同一段提示词反复粘贴。 你发现自己每次都要复制一段"代码审查清单"粘贴给AI——把它变成Skill。

信号二:CLAUDE.md超过200行。 Anthropic在Claude Code文档中建议CLAUDE.md控制在200行以内。超出的部分,按主题拆成多个Skills。

信号三:内容只在特定场景使用。 部署流程只在发版时用,数据库schema只在写查询时用——这些都不需要每次加载。

Skills的两种类型

Skills分两类,用法和设计思路不同:

Reference Skills(参考型):提供知识,AI在工作中参考。像一本工具书。

---
name: api-conventions
description: API设计规范和endpoint格式参考
---

## API规范
- URL使用kebab-case:/user-profiles
- 响应格式:{ code: 0, data: {...} }
- 错误码:40001=参数错误,50001=服务异常
- 分页:?page=1&pageSize=20

Action Skills(动作型):触发具体任务,像按流程操作的SOP。

---
name: deploy
description: 部署应用到生产环境
context: fork
disable-model-invocation: true
---

## 部署流程
1. 运行测试套件
2. 构建项目
3. 推送到部署目标
4. 验证部署结果

关键区别:Reference Skills适合让AI自动匹配加载(你提到API,AI自动查规范);Action Skills适合手动触发(你输入 /deploy,按步骤执行)。

四层作用域

Skills的存放位置决定谁能用:

位置路径适用范围
企业级managed settings全公司所有人
个人级~/.claude/skills/<名称>/SKILL.md你所有的项目
项目级.claude/skills/<名称>/SKILL.md仅当前项目
插件级<plugin>/skills/<名称>/SKILL.md启用插件的项目

优先级:企业级 > 个人级 > 项目级。同名Skill,高优先级的覆盖低优先级的。

最常用的是项目级——跟着代码仓库走,团队共享。比如项目的API规范、部署流程、测试模板,放在 .claude/skills/ 目录下,提交到git,所有团队成员都能用。

Skills的设计哲学是一切皆文件——用文件系统管理,用Git追踪变更。你的Skills和代码一样,可以review、可以回滚、可以随项目演进。判断放哪一级的标准很简单:换了项目还用吗?用→个人级,不用→项目级。 包含个人偏好或本地路径的Skill放个人级,团队通用的才提交到git。

按需加载:上下文成本的精算

Skills的上下文消耗机制很精细:

会话开始时:只加载Skill的名称和描述(description),每个Skill的描述限制1536字符。这些描述帮助AI判断什么时候该用哪个Skill。

调用时:加载完整的SKILL.md内容到对话中。

不调用时:只消耗描述的token,完整内容不加载。

终极省资源:设置 disable-model-invocation: true,连描述都不加载,直到你手动 /skill-name 触发。上下文成本降为零。

官方建议:CLAUDE.md保持在200行以内。 超出的参考内容和流程,按主题拆到Skills中。Skills的SKILL.md本身也不宜过长,社区实践建议控制在500行以内——太长的部分拆到支持文件中。

二、实战:从零创建一个Skill

创建第一个Skill:变更摘要

目标:创建一个Skill,自动总结git未提交的变更,标记风险点。

第一步:创建目录

mkdir -p ~/.claude/skills/summarize-changes

个人级目录,所有项目通用。项目级则用 .claude/skills/summarize-changes。

第二步:编写SKILL.md

---
description: 总结未提交的变更并标记风险点。当用户问"改了什么""帮我写commit message""review一下diff"时自动触发。
---

## 当前变更

!`git diff HEAD`

## 指令

总结以上变更,2-3个要点,然后列出发现的风险(缺失的错误处理、硬编码值、需要更新的测试)。
如果没有未提交变更,直接说"没有未提交的变更"。

第三步:测试

启动Claude Code,做个小改动,然后:

我改了什么?

AI会自动匹配到这个Skill(因为你的问题匹配了description中的"改了什么"),加载内容并给出总结。或者直接输入:

/summarize-changes

frontmatter配置详解

SKILL.md的frontmatter字段不多,但每个都有实际用途:

---
name: deploy                    # 显示名称,默认用目录名
description: 部署到生产环境        # AI用这个判断什么时候加载
when_to_use: 当用户说"发布""部署""上线"时触发  # 补充触发条件
argument-hint: [环境名]          # 自动补全时的参数提示
arguments: env                  # 命名参数,内容中用 $env 引用
disable-model-invocation: true  # 禁止AI自动触发,只能手动 /deploy
user-invocable: false           # 对用户隐藏,只有AI能触发
allowed-tools: Read Bash Grep   # 预授权工具,执行时不弹确认
model: sonnet                   # 临时切换模型(可用 sonnet/opus/haiku)
effort: high                    # 临时切换努力程度
context: fork                   # 在子代理中执行
---

按使用频率排序:

字段必要性用途
description推荐AI判断何时加载的核心依据
disable-model-invocation按需只想手动触发时设为true
allowed-tools按需预授权工具,减少确认弹窗
context按需需要隔离执行时设为fork
arguments按需需要传参时使用
name可选默认用目录名,一般不需要

动态上下文注入:!语法

这是Skills最强大的特性之一。在SKILL.md中,用 !`命令` 语法,Claude Code会在加载Skill前先执行命令,把输出结果注入到内容中。

---
description: 代码审查清单
---

## 当前分支的变更文件
!`git diff --name-only HEAD`

## 审查指令
对以上每个文件,检查:
- 是否有未处理的TODO
- 是否有硬编码的配置值
- 是否缺少错误处理

当AI加载这个Skill时,git diff --name-only HEAD 的输出会替换 !`...` 这行。AI看到的是实际的文件列表,不是命令本身。

常用注入命令:

!`git diff HEAD`                  # 当前变更
!`git log --oneline -5`           # 最近提交
!`cat package.json | jq .scripts` # npm scripts
!`find src -name "*.test.*" | wc -l`  # 测试文件数量
!`git branch --show-current`      # 当前分支名

(以上命令适用于Unix/macOS环境,Windows用户使用WSL或等效命令替换)

进阶:多行命令用 ```! 语法:

```!
# 检查项目健康度
echo "=== 测试覆盖率 ==="
npm run test:coverage --silent 2>/dev/null | tail -5
echo "=== 未提交文件 ==="
git status --short
echo "=== 依赖安全 ==="
npm audit --production 2>/dev/null | head -3
```

支持文件:让Skill更强大

复杂的Skill不应该把所有内容塞进一个SKILL.md。用目录结构组织:

code-review/
├── SKILL.md              # 主指令(必选)
├── checklist.md          # 审查清单
├── examples/
│   └── good-pr.md        # 优秀PR示例
└── scripts/
    └── validate.sh       # 校验脚本

在SKILL.md中引用这些文件:

## 审查流程
按 [checklist.md](checklist.md) 逐项检查。
参考 [good-pr.md](examples/good-pr.md) 了解优秀PR的标准。

AI会在需要时读取这些文件,不调用时不加载。

参数传递:让Skill更灵活

定义参数,让Skill适配不同场景:

---
name: create-test
description: 为指定文件生成测试
arguments: file pattern
---

为 $file 生成测试文件。
测试模式:$pattern

重点覆盖边缘条件。遵循项目中已有测试的风格。
运行测试确认通过。

调用:

/create-test src/auth/login.ts edge-cases

$file 被替换为 src/auth/login.ts,$pattern 被替换为 edge-cases。

也可以用位置参数 $0、$1,或统一的 $ARGUMENTS。

三、进阶:Skills的组合拳

context:fork——在子代理中隔离执行

有些任务不需要污染主会话的上下文。比如代码审查——AI需要读很多文件来评估质量,但结论只需要一个报告。

---
name: security-audit
description: 安全审计
context: fork
---

对当前项目进行安全审计:
1. 检查所有API端点是否有输入验证
2. 检查是否有SQL注入风险
3. 检查敏感信息是否硬编码
4. 检查依赖是否有已知漏洞
输出一份审计报告,按风险等级排序。

context: fork 让Skill在独立的子代理上下文中执行。你的主会话上下文不会因为大量文件读取而消耗。执行完毕后,只有最终报告回到主会话。

调用控制:谁有权触发

三种调用模式,对应不同场景:

配置用户触发AI触发适用场景
默认可以可以通用型Skill
disable-model-invocation: true可以不行你想精确控制时机的Skill
user-invocable: false不行可以AI内部使用的参考知识

大多数Skill用默认配置就行。只有两种情况需要调整:

你不想AI自动触发的:比如 /deploy——部署是严肃操作,应该由你明确触发。设 disable-model-invocation: true。

你想对用户隐藏的:比如内部编码规范的参考知识,用户不需要知道它的存在,AI在相关场景自动加载。设 user-invocable: false。

组合模式:Skills与其他功能的化学反应

Skills不是孤立的,它和Claude Code的其他扩展组件可以组合出强大的工作流:

Skills + MCP:MCP提供外部连接,Skills定义使用方式。比如MCP连上了数据库,Skill描述了查询规范和表结构,AI就能写出高质量的SQL。

Skills + Subagent:一个Skill启动多个Subagent并行工作。比如 /audit Skill同时启动安全审查、性能检查、代码风格审查三个子代理。

CLAUDE.md + Skills:CLAUDE.md放"必须遵守"的核心规则,Skills放"用到才查"的详细参考。比如CLAUDE.md写"遵循API规范",Skill放完整的API endpoint列表。

组合示例:

CLAUDE.md(永远加载):
  "使用 TypeScript strict 模式,测试覆盖率 > 80%"

Skills/api-guide.md(写API时加载):
  "完整endpoint列表、请求格式、错误码对照表"

Skills/deploy.md(发版时手动触发):
  "部署流程、环境配置、回滚方案"

实战案例:项目级的完整Skill配置

假设你有一个Express + TypeScript项目,下面是一套实用的Skill配置:

Skill 1:API参考(.claude/skills/api-reference/SKILL.md)

---
description: 项目API设计参考,包含endpoint格式、认证方式、错误码
---

## Endpoint格式
!`grep -r "router\." src/routes/ --include="*.ts" | head -20`

## 错误码
参考 [error-codes.md](error-codes.md)

Skill 2:代码审查(.claude/skills/code-review/SKILL.md)

---
description: 代码审查清单
disable-model-invocation: true
allowed-tools: Read Grep Bash
---

## 变更文件
!`git diff --name-only HEAD`

按 [checklist.md](checklist.md) 审查以上文件的变更。

Skill 3:测试生成(.claude/skills/create-test/SKILL.md)

---
description: 为指定模块生成测试
arguments: module
---

为 $module 生成测试。
参考项目中已有测试的风格:!`find src -name "*.test.ts" | head -1`

三个Skill覆盖了API开发、代码审查、测试编写的日常场景。CLAUDE.md只放核心规则(TypeScript strict、测试覆盖率要求),剩下的按需加载。

四、避坑指南

坑一:Skill写好了但AI不触发

你创建了一个Skill,问AI相关问题,但它没用那个Skill。

排查路径(按顺序检查):

  1. description是否匹配? AI根据description判断是否加载。你说"review一下代码",但description写的是"部署流程"——匹配不上。
  2. Skill是否出现在列表中? 输入 / 看自动补全列表,找不到说明路径错误。
  3. 是否设了 disable-model-invocation: true? 设了这个,AI永远不会自动触发。
  4. 直接手动调用试试:输入 /skill-name,能触发说明Skill本身没问题,是description不够准确。

坑二:Skill触发太频繁

你问个无关的问题,AI也加载了某个Skill。

解法:把description写得更具体。从"代码审查"改成"对git diff中的变更进行代码审查,检查代码质量和潜在风险"。越具体,误触发的概率越低。

如果还是太频繁,直接设 disable-model-invocation: true,改为手动触发。

坑三:Skill描述被截断

Skill的description有1536字符的限制。超出的部分会被截断,AI看不到完整描述。

解法:把最关键的信息放前面。description的第一句话就应该说明"这个Skill干什么、什么时候用"。细节放到 when_to_use 字段或正文中。

坑四:!命令执行失败

动态注入的命令报错,Skill加载失败。

常见原因:命令依赖的环境在Skill加载时不存在(比如需要特定的shell环境变量)。解法:用绝对路径,或在命令中加入错误处理。

坑五:context:fork后拿不到主会话的上下文

设了 context: fork,但Skill里引用了主会话中的对话内容。

原因:fork 是完全隔离的子代理上下文,看不到主会话的历史。解法:所有需要的信息都在SKILL.md正文中自包含。用 ! 语法注入实时数据,不要依赖对话历史。

结语

前三篇我们搭好了基础框架:CLAUDE.md给AI定规矩,结构化输入让AI听懂话,Plan Mode让AI先想后做。这篇是第一块扩展组件——Skills让你的AI从"懂规则"进化到"有工具"。

五个关键要点:

Skills是按需加载的工具箱——用的时候才拿,不用的时候不占地方。

!语法是杀手特性——动态注入实时数据,让Skill的指令基于当前状态而非静态文本。

frontmatter控制行为——description决定触发时机,context控制执行方式,allowed-tools减少确认弹窗。

组合使用威力最大——Skills + MCP + Subagent,让AI拥有"知道怎么用工具"的超能力。

CLAUDE.md保持在200行——超出的内容按主题拆到Skills中。

下一篇,我们给AI接外线——MCP外部集成实战。如果说Skills是给AI配了内部工具箱,MCP就是给它接通了外部电话线,让它能和数据库、API、云服务直接对话。

互动话题

你的项目里,哪些重复性的提示词或流程可以封装成Skill?是部署流程、代码审查清单,还是API参考文档?来评论区分享你的Skill设计思路。


智能编码进化论 | 第4篇/共10篇

上一篇:像带实习生一样带AI:任务与工作流

下一篇:给AI接外线:MCP外部集成实战


本文内容仅供学习交流,所述方法需结合实际场景灵活运用。 AI工具输出结果仅供参考,关键业务决策请结合人工判断。

本文由AI辅助创作,经人工审核编辑后发布。

本文首发于微信公众号「羲和Lab」,公众号内可留言交流

阅读公众号原文