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.pydone.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 命令,允许用户编辑任务标题和优先级:

  1. 告诉 Claude “添加一个 edit 命令”
  2. Claude 自动匹配 adding-cli-command Skill
  3. 读取现有命令文件了解约定
  4. 创建 commands/edit.py,遵循 Skill 中定义的模式
  5. __init__.py 中注册命令
  6. 运行测试验证功能

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 命令:

  1. 调度 code-reviewer Subagent → 审查 clear.py,返回问题报告(6 个严重问题、4 个警告)
  2. 主 Agent 修复 → 根据审查报告修改代码(使用 display 方法、正确的 Flag 格式、退出码等)
  3. 调度 test-generator-runner Subagent → 为修复后的 clear.py 生成测试
  4. 运行测试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 字段

除了 namedescription,Claude Code 中的 Skills 还支持:

字段说明
allowed-tools预批准的工具列表
model指定使用的模型
disable-model-invocation禁止模型自动触发
user-invocable是否允许用户手动触发
argument-hint参数提示
contextfork 表示在 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 两种触发方式

课程资料