Skills 与 Claude Code
之前我们在 Claude AI 和 Claude API 中使用 Skills。这节课转到 Claude Code,用 Skills 构建代码生成、审查和测试工作流,并设置配备 Skills 的 Subagents。
CLAUDE.md vs Skills
在 Claude Code 中,有两种方式提供项目上下文:
| 机制 | 加载方式 | 适用场景 |
|---|---|---|
| CLAUDE.md | 每次对话始终加载 | 通用项目信息:技术栈、架构、约定 |
| Skills | 按需加载(名称+描述始终在上下文中) | 特定工作流:添加命令、生成测试、代码审查 |
关键区别:如果某些信息只在特定任务中需要,放在 Skill 里比放在 CLAUDE.md 更节省上下文空间。
示例项目:CLI Todo App
课程使用一个 Python 命令行任务管理应用作为示例:
- 框架:Typer(CLI)、Rich(终端显示)
- 数据存储:JSON 文件
- 依赖管理:uv
- 项目结构:
src/task/
├── commands/
│ ├── __init__.py # 命令注册
│ ├── add.py # 添加任务
│ ├── done.py # 完成任务
│ └── list.py # 列出任务
├── models.py # Priority、Task 数据模型
├── storage.py # 序列化/反序列化逻辑
├── display.py # 终端显示格式
└── constants.py
CLAUDE.md 中记录了技术栈、架构和数据模型,确保 Claude 在每次对话中都了解项目基本信息。
项目级 Skills
Skills 存放在 .claude/skills/ 目录下,每个 Skill 一个文件夹:
.claude/skills/
├── adding-cli-command/
│ └── SKILL.md
├── generating-cli-tests/
│ └── SKILL.md
└── reviewing-cli-command/
└── SKILL.md
也可以在用户主目录的
.claude/skills/下创建全局 Skills,但本课只使用项目级 Skills。
注意:创建新 Skill 后需要重启 Claude Code 才能识别。用 /skills 命令可以查看已加载的 Skills 及其 Token 占用。
Skill 一:添加 CLI 命令
adding-cli-command 定义了添加新命令的完整工作流:
目录结构:新命令文件放在 commands/ 目录下,与 add.py、done.py 同级。
命令注册:在 commands/__init__.py 中注册,遵循固定格式。
编码约定:
- 使用
Annotated类型注解(更现代的 Typer 风格) - 使用
display.success()和display.info()显示输出 - Flag 使用 shorthand + 长名称 + help 文本
- 破坏性操作(如删除)需要确认提示
- Docstring、退出码、常量引用等约定
为什么不放在 CLAUDE.md? 这些约定只在添加命令时需要。放在 Skill 中,仅在匹配任务时加载,不浪费日常对话的上下文空间。
Skill 二:生成 CLI 测试
generating-cli-tests 定义了 pytest 测试生成工作流:
Fixture 定义:
- 临时存储(
tmp_storage) - 示例数据(
sample_tasks) - 每次测试运行时自动初始化
测试结构:Arrange → Act → Assert 模式
按命令类型分场景:
- 读取命令:验证列表展示、过滤
- 添加命令:验证创建、参数处理
- 修改命令:验证编辑、状态变更
- 删除命令:验证确认提示、硬删除/软删除
边界用例:无效输入、空状态、确认取消、ID 不存在
运行方式:uv run pytest,支持 verbose 模式和指定文件
Skill 三:审查 CLI 命令
reviewing-cli-command 是一个验证型 Skill——像评估工具一样检查其他 Skill 的产出:
审查清单:
- 文件位置是否正确
- 装饰器使用是否正确
- 命令注册是否符合规范
- 类型注解是否使用
Annotated - 参数/Flag 格式
- 错误处理和输出方式
- Docstring 和退出码
输出格式:结构化报告,包含问题列表、警告、建议修复
正反示例:提供正确写法和常见错误对比,帮助 Claude 准确判断
实战:添加 Edit 命令
用 Skills 添加一个 edit 命令,允许用户编辑任务标题和优先级:
- 告诉 Claude “添加一个 edit 命令”
- Claude 自动匹配
adding-cli-commandSkill - 读取现有命令文件了解约定
- 创建
commands/edit.py,遵循 Skill 中定义的模式 - 在
__init__.py中注册命令 - 运行测试验证功能
Subagents:隔离上下文的专业任务
直接在主 Agent 中运行测试和审查会:
- 占用大量上下文窗口
- 在大型项目中耗时耗资源
更好的方式是使用 Subagents——每个 Subagent 有独立的上下文窗口,专注于特定任务,完成后将结果返回主 Agent。
创建 Subagent
使用 /agents 命令创建,选择手动配置:
code-reviewer:
---
name: code-reviewer
description: "Reviews code for quality, security, and convention compliance. Use when user asks to review, check, or verify code"
tools: Bash, Glob, Grep, Read
model: inherit
color: purple
skills: reviewing-cli-command
---
Prompt 中定义通用的代码审查规则:代码质量检查、Python 规范、CLI 命令规范、输出格式。Agent 本身保持通用,通过 Skills 注入特定领域知识。
test-generator-runner:
---
name: test-generator-runner
description: "Generates and runs tests. Use when user asks to test, run tests, or generate tests"
tools: Bash, Glob, Grep, Read, Edit, Write
model: inherit
color: yellow
skills: generating-cli-tests
---
注意这个 Subagent 需要 Edit 和 Write 工具,因为它要创建和修改测试文件。
Subagents 与 Skills 的关键区别
Subagents 不继承 Skills
主 Agent 的 Skills 不会自动传递给 Subagent。必须在 Subagent 定义中用 skills 字段显式指定。
SKILL.md 完整加载
与主 Agent 的渐进式披露不同,Subagent 被调度时会加载完整的 SKILL.md。如果 Skill 引用了其他文件(如 /references、/assets),这些不会自动加载,但 SKILL.md 本身会一次性全部加载。
可以给一个 Subagent 多个 Skills
skills: reviewing-cli-command, reviewing-sql-queries
两种 Skills + Subagents 模式
模式一:自定义 Subagent + Skills(本课演示)
在 Subagent 定义中指定 skills 字段。Skill 同时对主 Agent 和 Subagent 可用,根据调度方式决定在哪个上下文中运行。
模式二:Skill 自带 Subagent(context: fork)
在 SKILL.md 的 frontmatter 中指定:
---
name: deep-research
description: Research a topic thoroughly
context: fork
agent: Explore
---
context: fork 让 Skill 始终在隔离的 Subagent 中运行。agent 字段指定使用哪个 Subagent(内置或自定义)。不指定 agent 时默认使用内置的 General-Purpose Subagent。
实战:审查 + 测试工作流
假设有人提交了一个不符合规范的 clear.py 命令:
- 调度 code-reviewer Subagent → 审查
clear.py,返回问题报告(6 个严重问题、4 个警告) - 主 Agent 修复 → 根据审查报告修改代码(使用
display方法、正确的 Flag 格式、退出码等) - 调度 test-generator-runner Subagent → 为修复后的
clear.py生成测试 - 运行测试 →
uv run pytest -v确认全部通过
主 Agent 只需协调和执行修复,审查和测试的上下文开销由 Subagents 承担。
Skills 调用方式
在 Claude Code 中,Skills 有两种触发方式:
| 方式 | 说明 |
|---|---|
| Model-invoked(模型触发) | Claude 根据用户请求自动匹配 Skill 描述并加载 |
| User-invoked(用户触发) | 用户输入 /skill-name 手动触发,如 /adding-cli-command |
可以通过 frontmatter 控制行为:
disable-model-invocation: true— 禁止自动触发,只能手动user-invocable: false— 禁止手动触发,只能自动
Skills 与 Slash Commands 的合并
Claude Code 早期有独立的 Slash Commands 功能(.claude/commands/ 目录)。现在 Slash Commands 已合并到 Skills 中——.claude/commands/review.md 和 .claude/skills/review/SKILL.md 功能等价,但 Skills 提供额外的目录结构和 frontmatter 控制能力。
SKILL.md 额外的 Frontmatter 字段
除了 name 和 description,Claude Code 中的 Skills 还支持:
| 字段 | 说明 |
|---|---|
| allowed-tools | 预批准的工具列表 |
| model | 指定使用的模型 |
| disable-model-invocation | 禁止模型自动触发 |
| user-invocable | 是否允许用户手动触发 |
| argument-hint | 参数提示 |
| context | fork 表示在 Subagent 中运行 |
| agent | 指定运行的 Subagent |
关键要点
- CLAUDE.md 放通用项目信息,Skills 放特定工作流——按需加载,节省上下文
- Skills 存放在
.claude/skills/目录,创建后需重启 Claude Code - 三种互补的 Skill:生成(adding)、测试(testing)、审查(reviewing)
- Subagents 不继承 Skills,必须在定义中显式指定
- Subagent 调度时 SKILL.md 完整加载,不是渐进式披露
- 两种模式:自定义 Subagent + Skills,或 Skill 自带
context: fork - Skills 支持 Model-invoked 和 User-invoked 两种触发方式