<!-- title: 从零打造变更日志生成技能 -->

# 从零打造变更日志生成技能

本教程将带你从零创建一个完整的 Claude Code 自定义 Skill——`changelog`，它能扫描两次发布之间的 Git 历史，按 Keep a Changelog 规范自动生成或更新 `CHANGELOG.md`。通过这个真实、可运行的案例，你将掌握 Skill 的目录结构、frontmatter 配置、动态上下文注入、辅助文件分层、调用控制与迭代评测的完整方法论，学完即可迁移到任意自定义工作流。

## 一、适用人群与前置条件

**适用人群**：已经能在 Claude Code 里跑通基本对话与 `/` 命令、想把自己重复粘贴的"操作清单"固化成可复用能力的开发者。

**前置条件**：

- Claude Code v2.1.145 或更高版本（`claude --version` 可查，部分特性如 `/run` 系列要求此版本以上）。
- 一个本地 Git 仓库（带至少一个 tag 更佳，没有也能跑）。
- 了解 Markdown 基本语法，能看懂 YAML 前置元数据。
- 终端能执行 `git`、`mkdir`、`cat` 等基础命令。

无需任何编程框架——Skill 本质上是"一个文件夹 + 一个 `SKILL.md`"，这点是它最容易上手的特性。

## 二、先搞清楚：Skill 到底是什么

在 Claude Code 的体系里，**一个 Skill 就是一个文件夹**，文件夹里至少有一个 `SKILL.md` 作为入口。`SKILL.md` 由两部分组成：

1. **YAML frontmatter**（夹在两个 `---` 之间）：告诉 Claude 这个 Skill **做什么、什么时候该用它**。
2. **Markdown 正文**：Claude 在 Skill 被激活后遵循的具体指令。

关键的一点是**渐进式披露（Progressive Disclosure）**：Claude Code 在会话启动时只会把每个 Skill 的 `description` 字段加载进上下文（成本极低），而正文只有在 Claude 判断"这次任务跟它相关"时才会按需加载。这意味着你可以放心地堆砌大量参考文档——只要把它们放在辅助文件里，正文保持精简，平时就几乎不占 token。

另一个要记住的认知：**自定义命令已经并入 Skill 体系**。过去放在 `.claude/commands/deploy.md` 的文件，和放在 `.claude/skills/deploy/SKILL.md` 的 Skill，都会生成 `/deploy` 命令并等价工作。Skill 是更新的、功能更全的形态（支持辅助文件、frontmatter 控制调用方式、按需自动加载）。

## 三、分步实战：搭建 `changelog` Skill

### 第 1 步：决定 Skill 的"存放层级"

Skill 的存放位置决定了谁能用、用在哪：

| 层级 | 路径 | 作用范围 |
|------|------|----------|
| 企业级 | 托管设置（managed settings） | 组织内所有用户 |
| 个人级 | `~/.claude/skills/<skill-name>/SKILL.md` | 你的所有项目 |
| 项目级 | `.claude/skills/<skill-name>/SKILL.md` | 仅当前项目 |
| 插件级 | `<plugin>/skills/<skill-name>/SKILL.md` | 插件启用处 |

同名冲突时的优先级是 **企业级 > 个人级 > 项目级**；插件 Skill 用 `插件名:技能名` 命名空间，不会和别的层级冲突。此外，项目级还能"穿透"父目录——从子目录启动会话时，仓库根目录的 `.claude/skills/` 也会被发现；monorepo 的子包 `apps/web/.claude/skills/deploy/` 则会以带目录前缀的名字 `apps/web:deploy` 出现。

我们的 `changelog` 是个跨项目通用的能力，**放在个人级**最合适：

```bash
mkdir -p ~/.claude/skills/changelog
```

> **预期结果**：目录创建成功，无输出。后续所有文件都放在 `~/.claude/skills/changelog/` 下。

### 第 2 步：写入口文件 `SKILL.md`

把下面内容存为 `~/.claude/skills/changelog/SKILL.md`：

```markdown
---
description: Generates or updates CHANGELOG.md from git history between two refs. Use when the user wants to draft release notes, prepare a version bump, or summarize what changed since the last tag.
---

## Git history since the last tag

!`LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null); if [ -n "$LAST_TAG" ]; then echo "Ref range: $LAST_TAG..HEAD"; git log $LAST_TAG..HEAD --pretty=format:"- %s"; else echo "No previous tag found; showing last 30 commits"; git log -30 --pretty=format:"- %s"; fi`

## Instructions

You are generating release notes following the "Keep a Changelog" convention.

1. Read the commit list above.
2. Categorize each commit into Added / Changed / Fixed / Removed / Security using the rules in `references/category-rules.md`.
3. Merge duplicate or related commits into a single bullet.
4. Output the new version section using the format in `template.md`.
5. If `CHANGELOG.md` exists in the repo root, insert the new section near the top (below the header) using the Edit tool; otherwise create it from `template.md`.
6. Commits you cannot confidently classify go under "Changed" with a short note flagging the uncertainty.

Do NOT invent commits that are not in the list. Do NOT include merge commits. Keep bullets in the imperative-mood style of the source commits.
```

**这里有几个关键设计**，逐个拆解：

- **只写 `description`，没写 `name`**：官方模板里 `name` 是必填，但 Claude Code 实际允许省略——目录名 `changelog` 会自动成为命令名 `/changelog`。不过为保险起见，你也可以补上 `name: changelog`。
- **`description` 是"红娘"**：它**永远在上下文里**，是 Claude 判断"要不要自动触发这个 Skill"的唯一依据。务必写清楚**做什么 + 什么时候用**，并埋入用户会说的自然语言（"release notes""version bump""what changed"）。不要把实现细节塞进来。
- **`!\`命令\`` 是动态上下文注入**：这一行在 Claude 看到正文**之前**就被执行，输出原地替换掉这一行。于是指令到达时，当前仓库的真实 commit 列表已经内联好了——这正是 Skill 能"读懂实时数据"的根基。
- **正文精简、引用辅助文件**：`references/category-rules.md` 和 `template.md` 都是**按需加载**的，平时不进上下文。这就是渐进式披露的落地。

> **预期结果**：保存后无需重启——Claude Code 会监视 Skill 目录，`SKILL.md` 的改动在当前会话内即时生效（即"实时变更检测"）。

> **常见问题**：把 Skill 嵌套深了一层是最常见的错误。正确路径是 `~/.claude/skills/changelog/SKILL.md`，**不是** `~/.claude/skills/changelog/某文件夹/SKILL.md`。可用 `ls ~/.claude/skills/changelog/` 验证，应直接看到 `SKILL.md`。

### 第 3 步：添加辅助文件（分层加载）

创建目录与文件：

```bash
mkdir -p ~/.claude/skills/changelog/references
mkdir -p ~/.claude/skills/changelog/examples
```

`references/category-rules.md`（分类规则，详尽但平时不加载）：

```markdown
# Commit → Category Mapping

- **Added**: feat, add, new, create, introduce, support
- **Changed**: refactor, update, change, improve, migrate, bump (deps), rework
- **Fixed**: fix, bug, resolve, patch, correct, repair, handle (edge case)
- **Removed**: remove, delete, drop, strip (only when actually removed)
- **Security**: security, CVE, vulnerability, auth, leak, sanitize, escape

Conventional Commits prefixes (`feat:`, `fix:`, `chore:`, `docs:`) take priority
over keyword matching. A `chore:` that bumps deps counts as "Changed".

Uncertain commits → default to **Changed** and flag for review.
```

`template.md`（输出模板）：

```markdown
# Changelog

All notable changes to this project are documented here.
The format is based on [Keep a Changelog](https://keepachangelog.com/).

## [UNRELEASED]

### Added
-

### Changed
-

### Fixed
-
```

`examples/sample-output.md`（示例输出，让模型对齐格式）：

```markdown
## [1.2.0] - 2026-06-22

### Added
- Support for webhook signature verification

### Fixed
- Race condition in token refresh on slow networks
```

**设计意图**：把"规则"和"模板"从 `SKILL.md` 剥离出去。`SKILL.md` 一旦加载就**跨轮常驻上下文**，每多一行都是持续 token 成本；而分类规则、示例这种"查完就走"的资料放进辅助文件，只有 Claude 真正需要时才读一次。这是控制 Skill 长期成本的核心技巧。

### 第 4 步：控制"谁来触发"——调用控制

`changelog` 这种 Skill，你通常想**主动**调用（敲 `/changelog`），而不是让 Claude 在你聊到一半时擅自触发。官方 frontmatter 提供两个开关：

- `disable-model-invocation: true`：禁止 Claude 自动触发，只能手动 `/changelog` 调用。
- `context: fork`：让 Skill 在**子代理（subagent）**里执行，主对话上下文不被污染，适合会产生大量中间输出的任务。

给我们的 Skill 加上手动调用倾向。修改 frontmatter：

```markdown
---
name: changelog
description: Generates or updates CHANGELOG.md from git history between two refs. Use when the user wants to draft release notes, prepare a version bump, or summarize what changed since the last tag.
disable-model-invocation: true
---
```

> **说明**：对 `changelog` 这种"生成一段相对长的文档"的任务，`context: fork` 也很值得加——它在独立子代理里跑，跑完只把结果摘要交回主线，避免几十条 commit 的解析过程刷屏。但加了 `fork` 后子代理**看不到**主会话历史，需要的话要把必要上下文写进正文或用动态注入喂给它。本例所有数据都来自 `git log`，所以加 `context: fork` 是安全的。

反过来看，参考类 Skill（比如"本仓库 API 设计规范"）就**不要**加 `disable-model-invocation`——你要的就是让 Claude 在写代码时自动想起它。

### 第 5 步：实测两种触发方式

进入任意一个有提交历史的 Git 仓库，启动 `claude`。

**方式 A：手动直接调用**

```
/changelog
```

**方式 B：让 Claude 自动识别**（前提：你没设 `disable-model-invocation: true`，或临时想验证 description 写得好不好）

```
帮我把自上个版本以来的改动整理成发布说明
```

> **预期结果**：Claude 先读取 SKILL.md、执行其中的 `git log` 注入拿到 commit 列表，按需读取分类规则和模板，然后把结果写入或更新仓库根目录的 `CHANGELOG.md`，最后给你一段新增内容的摘要。

> **常见问题**：
> - **Skill 没触发**：八成是 `description` 写得太泛或没包含用户会说的词。重写描述，加入具体场景短语；用 `/help` 或会话内观察 Claude 是否"读到"了这个 Skill。
> - **description 被截断**：description 上限 1024 字符，过长的会被截断导致后半部分触发词丢失。精简到关键场景即可。
> - **改了文件没生效**：仅当你**新建**了一个会话启动时不存在的顶层 `skills` 目录时才需要重启；编辑已有 `SKILL.md` 无需重启。

### 第 6 步：用 Evals 闭环打磨

Skill 写完不算完，要靠评测来保证"换个仓库、换批 commit 还能稳定产出"。Claude Code 的 `skill-creator` 内置了评测能力。核心思路是准备几组"输入→期望输出"的样例，跑 Skill、对比结果、迭代 description 与规则。

一个最小评测集可以这样组织（放仓库或临时目录）：

```text
evals/
├── case-1-feat-fix.txt      # 输入：模拟的 commit 列表
├── case-1-expected.md       # 期望：分类后的输出
├── case-2-mixed.txt
└── case-2-expected.md
```

评测关注三件事：

1. **触发准确性**：描述相似但不同义的请求（比如"帮我写提交信息" vs "帮我整理发布说明"）会不会被错误触发或漏触发。
2. **分类正确率**：`fix:` 是否稳定落到 Fixed，`chore(deps): bump` 是否落到 Changed。
3. **格式一致性**：是否始终遵循 `template.md`，日期、版本号占位是否被正确替换。

每轮迭代只改一个变量（改 description、或改分类规则、或改正文指令），再跑评测——这是把 Skill 从"能用"推向"可靠"的唯一路径。

## 四、实战案例：完整可运行的 `changelog` Skill

把前面所有片段拼起来，最终目录长这样：

```text
~/.claude/skills/changelog/
├── SKILL.md                    # 入口：description + 动态注入 + 精简指令
├── template.md                 # CHANGELOG 骨架模板
├── references/
│   └── category-rules.md       # commit→分类映射（按需加载）
└── examples/
    └── sample-output.md        # 期望输出样例（按需加载）
```

在真实仓库里走一遍：

```bash
# 1. 进项目
cd ~/projects/my-api
git tag v1.1.0   # 假设上个发布点

# 2. 期间有若干提交
git commit -m "feat: add webhook signature verification"
git commit -m "fix: token refresh race on slow networks"
git commit -m "chore(deps): bump express to 4.19"

# 3. 生成发布说明
claude
> /changelog
```

Claude 会执行动态注入拿到三条 commit，按 Conventional Commits 前缀分类，输出并写入 `CHANGELOG.md`：

```markdown
## [1.2.0] - 2026-06-22

### Added
- Support for webhook signature verification

### Fixed
- Race condition in token refresh on slow networks

### Changed
- Bump express to 4.19
```

如果仓库里已有 `CHANGELOG.md`，Skill 会把这段插到顶部 `## [Unreleased]` 之下；没有则按 `template.md` 新建。整个过程不需要你复制粘贴任何 commit 信息。

## 五、工作流程全景图

```mermaid
flowchart TD
    A[会话启动] --> B[加载所有 Skill 的 description 进上下文]
    B --> C{用户请求 / 自动判断}
    C -->|匹配 description| D[加载该 Skill 的 SKILL.md 正文]
    C -->|/skill-name 手动调用| D
    D --> E[执行动态注入 !\`命令\`]
    E --> F{正文是否引用辅助文件?}
    F -->|是| G[按需读取 references/ template/ examples/]
    F -->|否| H[仅用正文+注入数据]
    G --> H
    H --> I[执行指令 生成/编辑结果]
    I --> J{context: fork?}
    J -->|是| K[在子代理执行 摘要回主线]
    J -->|否| L[在主上下文执行]
    K --> M[输出 CHANGELOG 更新]
    L --> M
```

这张图串起了本教程所有概念：description 常驻、正文按需、动态注入先于正文执行、辅助文件分层、调用控制决定执行位置。

## 六、本教程的方法论提炼

虽然案例是"变更日志生成"，但你要带走的是这套**通用四步法**，套到任何自定义 Skill 上都成立：

1. **先定层级与触发意图**：放个人还是项目？让 Claude 自动触发还是手动 `/` 调用？想清楚再动 `disable-model-invocation` 和 `context: fork`。
2. **description 当"广告位"**：永远在线，决定被发现概率。写"做什么 + 何时用 + 用户原话"，拒绝实现细节。
3. **正文精简 + 动态注入**：能从环境实时拿的数据（git、文件、命令输出）一律用 `!\`命令\`` 注入，别让模型靠猜。正文只留决策与编排逻辑。
4. **重资料下沉到辅助文件**：规则、模板、示例进 `references/`、`examples/`，按需加载。这控制的是 Skill 的长期 token 成本。

## 七、延伸阅读

- **官方 Skill 文档**：`code.claude.com/docs/en/skills` —— frontmatter 字段、调用控制、动态注入的权威来源。
- **Anthropic Skills 开放仓库**：`github.com/anthropics/skills` —— 含 `template/` 起步模板和大量真实 Skill 范例（docx/pdf/pptx 等生产级实现）。
- **Agent Skills 开放标准**：`agentskills.io` —— Skill 跨工具（Claude Code / OpenClaw / Codex CLI / Cursor）互通的规范基础。
- **skill-creator 内置技能**：直接在 Claude Code 里跑 `/skill-creator`，可以脚手架新 Skill、优化 description、跑评测并做方差分析。

## 八、训练营适用性评估

| 维度 | 评估 |
|------|------|
| 适合的训练营类型 | Claude Code 进阶实战营、DevOps 自动化提效营、AI 辅助研发训练营 |
| 学员基础要求 | 能独立用 Git，了解 Markdown/YAML，跑通过至少一次 Claude Code 会话 |
| 建议教学时长 | 2.5–3 小时（含动手：45 分钟概念 + 90 分钟搭建 + 30 分钟评测迭代 + 答疑） |
| 动手产出 | 每人一个可运行的个人级 Skill，当场在真实仓库跑出 CHANGELOG |
| 进阶衔接 | 可无缝衔接"Plugin 打包分发""Subagent 编排""Hooks 动态注入"等高阶主题 |

本教程刻意把案例选在"文档生成"这一与前序代码扫描类 Skill 不同的品类，目的是让学员理解：Skill 的威力不在某个垂直场景，而在"指令 + 动态数据 + 分层文件 + 调用控制"这套可迁移的骨架。掌握了它，下一个 Skill 你该造什么，答案就在你自己每天重复粘贴的那段操作清单里。

## 参考来源

1. [Extend Claude with skills — Claude Code Docs](https://code.claude.com/docs/en/skills) — 官方 Skill 完整文档，含 frontmatter 参考、动态注入、调用控制、层级优先级等权威说明。
2. [anthropics/skills — GitHub](https://github.com/anthropics/skills) — Anthropic 官方 Skill 仓库，提供 `template/` 起步模板及 docx/pdf/pptx 等生产级 Skill 实现参考。
3. [Where Are Claude Skills Stored? Paths for Mac, Windows, Linux — Agensi](https://www.agensi.io/learn/where-are-claude-skills-stored) — 个人级/项目级 Skill 存放路径与常见嵌套错误排查指南。
4. [Progressive Disclosure in AI Agent Skill Design — Towards AI](https://pub.towardsai.net/progressive-disclosure-in-ai-agent-skill-design-b49309b4bc07) — 把 UX 的渐进式披露原则应用到 SKILL.md 结构设计的实践方法。
5. [Core Concepts and Progressive Disclosure — anthropics/claude-cookbooks (DeepWiki)](https://deepwiki.com/anthropics/claude-cookbooks/4.1-core-concepts-and-progressive-disclosure) — Skill 的发现、加载与渐进式披露架构的底层机制解析。

> [!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 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
