本教程带你从零构建一个提交信息生成 Skill(commit-message generator)——它会读取你暂存的代码变更,自动产出符合 Conventional Commits 规范的提交信息草稿。借此案例,你将完整掌握 Claude Code Skill 的核心机制:SKILL.md 的 YAML frontmatter、渐进式披露(progressive disclosure)、脚本封装与触发调试。适合已能基本使用 Claude Code、想封装第一条自定义能力的中级读者。
claude --version 可正常输出)feat: / fix: / docs: 等)很多人把 Skill、Slash 命令、MCP、CLAUDE.md 混为一谈。先花一分钟厘清边界,后面才不会选错工具:
| 能力载体 | 本质 | 加载时机 | 适合场景 |
|---|---|---|---|
| CLAUDE.md | 静态上下文/规则 | 每次会话全量注入 | 团队规范、编码风格、常驻约束 |
| Slash 命令 | 一段提示词的快捷方式 | 用户主动输入 /xxx |
固定流程的提示词复用 |
| MCP 服务器 | 外部工具/数据源协议 | 显式连接后可调用 | 接入数据库、API、第三方系统 |
| Skill | 文件系统能力包 | Claude 按语义自动判断是否加载 | 可复用的、有步骤的专业工作流 |
关键差异:CLAUDE.md 是"总在场"的背景,而 Skill 是"按需登场"的专家。Skill 的精髓在于 progressive disclosure——平时只把一段 description 摆在货架上,Claude 判断"现在需要这位专家"时,才把整本"操作手册"加载进上下文。这正是它比把所有规则塞进 CLAUDE.md 更省 Token、更精准的原因。
一句话记忆:CLAUDE.md 是公司的《员工手册》,Skill 是你随叫随到的「外包专家」,Slash 命令是你按下的「快捷按钮」,MCP 是接进系统的「外接设备」。
选择第一个实战 Skill 有三个标准:高频、自包含、可验证。提交信息生成完美命中:
git diff,不依赖任何外部 API,离线可跑更重要的是,它能完整覆盖一个 Skill 的所有要素:需要脚本提取 diff、需要参考资料记录 type 列表、需要正文指导 Claude 如何组织语言、需要 frontmatter 让 Claude 在合适时机自动触发——麻雀虽小,五脏俱全。
Skill 可以放在两个位置:
~/.claude/skills/<skill-name>/SKILL.md——所有项目可用.claude/skills/<skill-name>/SKILL.md——仅当前仓库可用我们做的是一个通用工具,放用户级最合适。先建目录:
mkdir -p ~/.claude/skills/commit-message/scripts
mkdir -p ~/.claude/skills/commit-message/references
最终目录结构如下:
~/.claude/skills/commit-message/
├── SKILL.md # 入口文件(必需)
├── scripts/
│ └── staged-diff.sh # 提取暂存区差异的脚本
└── references/
└── conventional-commits.md # 规范速查(按需加载)
常见问题:目录名必须和 frontmatter 里的
name字段一致,且只能是小写字母、数字、连字符(kebab-case),最长 64 字符。写成commit_message或CommitMessage都会导致加载失败。
SKILL.md 顶部是一段 YAML frontmatter,用 --- 包裹。其中只有两个字段是必填且决定生死的:name 和 description。
---
name: commit-message
description: 生成符合 Conventional Commits 规范的 Git 提交信息。当用户准备提交代码、
询问"该怎么写 commit message"、"帮我写提交信息"、暂存了变更想总结改动,
或者在提交前想确保信息规范时使用。读取暂存区的 git diff,产出可直接复制的
提交信息草稿,包含 type、scope、subject 与可选的 body。
---
这里有一个反直觉但至关重要的设计:description 的写法直接决定 Skill 能否被触发。Claude 不会看到你的正文,它只看这段描述来决定"要不要请这位专家出场"。所以好的 description 必须同时回答两个问题:
写 description 的三条经验法则:
常见问题:把
description写成"一个关于提交的工具"这种废话——Claude 永远不知道何时该调用它。务必具体到"什么场景 + 产出什么"。
frontmatter 之下就是 Markdown 正文。正文要精简——官方建议控制在 500 行以内。原则是:让 Claude 一眼读懂工作流,细节丢给脚本和参考资料。
# 提交信息生成
## 何时使用
用户准备 `git commit`、询问如何写提交信息、或希望总结暂存的改动时。
## 工作流程
1. 运行 `scripts/staged-diff.sh` 获取当前暂存区的变更摘要
2. 如果暂存区为空,提示用户先 `git add`,不要自行 add
3. 分析变更,判断本次提交的主导 type(参考 `references/conventional-commits.md`)
4. 产出提交信息,格式:`<type>(<scope>): <subject>`
5. 把信息展示给用户,**只生成草稿,绝不自动执行 commit**
## 输出规范
- subject 用祈使句、现在时,首字母小写,结尾不加句号,不超过 50 字符
- 当改动跨多个不相关模块时,建议拆分为多条提交信息而非一条大杂烩
- body 只在有非显而易见的背景时才写,每行不超过 72 字符
## 重要约束
- **只读 git diff,只生成建议**:任何 `git commit`、`git push` 都必须由用户确认后手动执行
- 不要为了凑 type 而强行归类;实在无法判断就用 `chore`
注意最后那条"重要约束"——这与"不要自动 commit"的工程纪律完全一致。Skill 的正文里要明确写死这类护栏,避免 Claude 自作主张。
常见问题:把所有 Conventional Commits 的细则全塞进正文——会让 SKILL.md 臃肿、每次加载都烧 Token。正确做法是把完整规范放进
references/,正文里只留"按需查阅"的指引。这就是渐进式披露。
Skill 里的脚本分两种风格,要按复杂度选择:
```bash 代码块写命令。适合 1~3 行的简单逻辑。scripts/,正文里用路径引用。适合多步骤、可复用、需要单独测试的逻辑。提取暂存区差异是典型的"分离脚本"场景——它有健壮性处理(空暂存区、二进制文件),值得独立成文件。新建 scripts/staged-diff.sh:
#!/usr/bin/env bash
# 提取暂存区的变更摘要,供提交信息生成使用
set -euo pipefail
# 确认处于 git 仓库
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "ERROR: 当前目录不是 git 仓库" >&2
exit 1
fi
# 获取暂存区变更的文件名清单(带状态码)
staged_files=$(git diff --cached --name-status)
if [ -z "$staged_files" ]; then
echo "NOTICE: 暂存区为空,请先 git add 需要提交的文件。"
exit 0
fi
echo "===== 暂存文件清单 ====="
echo "$staged_files"
echo ""
echo "===== 变更统计 ====="
git diff --cached --stat
echo ""
echo "===== 实际差异(截断超长内容)====="
git diff --cached | head -200
赋可执行权限(这一步常被遗漏,会导致 Skill 调用时脚本报权限错误):
chmod +x ~/.claude/skills/commit-message/scripts/staged-diff.sh
单独测试脚本,确认能跑:
cd ~/your-project
git add some-file.py
bash ~/.claude/skills/commit-message/scripts/staged-diff.sh
预期结果:依次输出文件清单、变更统计、实际差异内容三段。若暂存区为空,则输出提示并正常退出。
references/conventional-commits.md 是 Skill 的"工具书",平时不加载,只有 Claude 需要判定 type 时才翻开。内容保持速查风格:
# Conventional Commits 速查
## type 取值
- feat: 新功能(用户可感知)
- fix: Bug 修复
- docs: 仅文档变更
- style: 代码格式(不影响逻辑:空格、分号等)
- refactor: 既非新增功能也非修 Bug 的重构
- perf: 提升性能的改动
- test: 增加/修改测试
- build: 构建系统或外部依赖(webpack、npm 等)
- ci: CI 配置文件与脚本
- chore: 杂项(不修改 src 或测试的其他改动)
- revert: 回退某次提交
## 格式
<type>(<scope>): <subject>
<空行>
<body>
<空行>
<footer>
## 示例
feat(auth): add OAuth2 login flow
fix(api): handle null pointer in user lookup
docs: update README installation steps
这套"正文 → 脚本 → 参考资料"的三层结构,就是渐进式披露的标准落地形态。Claude 每次只加载它当前真正需要的层。
Skill 无需显式安装——放到正确目录即生效。验证它是否被识别:
claude # 启动交互式会话
进入会话后,输入一句自然语言触发:
我刚改了登录模块,帮我看看暂存了什么、该怎么写提交信息
预期结果:Claude 识别到"提交信息"意图,自动加载 commit-message Skill,运行脚本、给出类似下面的草稿:
feat(auth): add remember-me checkbox to login form
- persist session token when checkbox is checked
- clear token on explicit logout
如果没触发,可以用 /skills 命令查看已加载的 Skill 列表,确认 commit-message 是否在册、description 是否被正确解析。
Skill "装了却不触发"是新手最常踩的坑,根因 90% 在 description。排查清单:
cat -A SKILL.md | head -5 检查是否有隐藏的 Tab 字符——YAML 只认空格。"git 工具" 改成带场景的 "生成 Conventional Commits 提交信息,当用户准备 commit……"。git rev-parse 式的低级错误,但确实常发生。一个调试小技巧:临时把 description 改得极简极宽(如 "处理任何与 git 提交相关的事"),先确认能触发,再逐步收窄到精准范围。
Skill 跑通后,三条进阶路径:
.claude/skills/commit-message/ 整个目录提交到仓库,队友 pull 后即生效;或封装成插件通过 marketplace 分发PreToolUse 拦截真实的 git commit,强制要求提交信息先过 Skill 校验假设你在 ~/demo 仓库刚改完一个 API 的空指针处理:
cd ~/demo
# 修复 bug
sed -i 's/return user.name/return user?.name ?? "anonymous"/' api/user.py
git add api/user.py
启动 Claude Code,说一句"帮我把这次改动整理成提交信息"。你将看到完整的自动流程:
commit-message Skillscripts/staged-diff.sh → 拿到 diffreferences/conventional-commits.md → 判定为 fix最终你会拿到一条可直接复用的信息:
fix(api): guard against null user in name lookup
整个过程没有外部 API、没有密钥、完全离线,且 Claude 始终只扮演"建议者"——git commit 这一步始终留给你手动执行。
flowchart TD
A[用户在会话中说话] --> B{Claude 扫描所有 Skill 的 description}
B -->|语义匹配| C[自动加载 commit-message 的 SKILL.md 正文]
B -->|不匹配| Z[不加载任何 Skill]
C --> D[按正文工作流执行]
D --> E[运行 scripts/staged-diff.sh 提取 diff]
E --> F{需要判定 type?}
F -->|是| G[按需加载 references/conventional-commits.md]
F -->|否| H[直接生成]
G --> H
H --> I[产出提交信息草稿]
I --> J[展示给用户,等待确认]
J --> K[用户手动执行 git commit]
这张图揭示了渐进式披露的两层"按需":第一层,description 不命中则整个 Skill 不加载;第二层,正文加载后,references 仍只在需要时才被翻开。Token 始终花在刀刃上。
| 维度 | 评估 |
|---|---|
| 适合训练营类型 | Claude Code 入门到进阶营、AI 工程化实战营、开发者效率提升营 |
| 学员基础 | 能独立用 Git、用过 Claude Code 基本对话 |
| 教学时长 | 讲授 45 分钟 + 动手实操 60 分钟,合计约 2 课时 |
| 交付物 | 一个可运行的用户级 Skill,及一份可提交到团队的 Skill 目录 |
| 难度 | ⭐⭐⭐(中等偏低),适合作为"Skill 三件套"教学的首个落地案例 |
本案例特别适合作为训练营里"从使用者到构建者"的转折点——学员第一次亲手把一段重复劳动封装成 Claude 能自动调用的能力,这种正反馈往往成为持续探索 Agent 工程的起点。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
