<!-- title: 造脚手架Skill一句话秒出API四件套 -->

# 造脚手架Skill一句话秒出API四件套

## 概述

本教程带你从零造一个名为 `endpoint-scaffold` 的 Claude Code Skill：输入一句 `POST /users 创建用户`，它自动产出路由、处理器、单元测试、接口文档四个文件——也就是后端开发最重复的"四件套"。在这个过程中，你会真正吃透 Skills 的三个核心机制：**渐进式披露**（薄入口 + 引用文件）、**命名参数**（`$method`、`$path`、`$desc`）、**动态上下文注入**（`!`命令``）。适合已经用过 Claude Code、想从"复制粘贴提示词"升级到"封装可复用工程资产"的开发者。

## 前置条件

- 已安装 Claude Code v2.1.196 或更高（命名参数替换与 `${CLAUDE_PROJECT_DIR}` 需要该版本）
- 一个可写入的工作目录，建议是已有的 Node/Express 或 Python/FastAPI 项目，方便立即验证产物
- 了解基本的 shell 与 Markdown 语法
- 会用 `/permissions`、`/model` 等基础命令

核心概念速记：一个 Skill 就是一个目录，入口是 `SKILL.md`。它有两种 YAML 块之外的内容——frontmatter（告诉 Claude"何时用、能用什么工具"）和正文（告诉 Claude"怎么做"）。与 `CLAUDE.md` 最大的区别是：**Skill 正文只在被调用时才加载**，长期参考材料几乎零成本。

## 步骤一：先想清楚 Skill 的"骨架"，再动笔

很多人写 Skill 的第一步是打开 `SKILL.md` 开始堆文字，这是反模式。先在纸上画清楚三件事：

1. **触发时机**：用户说什么话、在什么文件上工作时，这个 Skill 该出场？
2. **输入参数**：调用时需要喂几个值？分别叫什么？
3. **产出物**：会生成或修改哪些文件？哪些是固定模板，哪些需要 Claude 按上下文填充？

对本 Skill 而言，三个答案很清晰：

- 触发：用户说"加个接口""新建一个 endpoint""生成 CRUD"
- 参数：HTTP 方法、路径、用途描述（共三个）
- 产出：`routes/<name>.js`、`handlers/<name>.js`、`tests/<name>.test.js`、`docs/<name>.md`

这一步决定了后续所有设计。把第三项里"固定不变的部分"抽成模板文件，"需要动态填充的部分"留给参数——这就是渐进式披露的雏形。

## 步骤二：搭目录结构

Skills 存放位置决定作用域。个人级放 `~/.claude/skills/`，项目级放 `.claude/skills/`。脚手架类工具强绑定项目，建议放项目级，跟着代码一起进版本库、被团队共享。

```bash
mkdir -p .claude/skills/endpoint-scaffold/templates
mkdir -p .claude/skills/endpoint-scaffold/examples
```

最终结构：

```
.claude/skills/endpoint-scaffold/
├── SKILL.md                 # 薄入口：导航 + 流程
├── templates/
│   ├── route.tpl            # 路由声明模板
│   ├── handler.tpl          # 处理器函数模板
│   ├── test.tpl             # 单测模板
│   └── doc.tpl              # 接口文档模板
└── examples/
    └── one-liner-to-files.md # 一句话→四文件的对照样例
```

**预期结果**：Claude Code 监视这些目录，文件改动在当前会话内即时生效，无需重启。若新建的是会话启动时并不存在的顶层目录，才需要重启一次。

**常见问题**：把模板塞进 `SKILL.md` 而不是单独文件——结果正文膨胀到几百行，每次调用都把模板原文灌进上下文，token 成本飙升。记住官方建议：**`SKILL.md` 控制在 500 行以内**，详情挪到引用文件。

## 步骤三：写模板文件（先写"死"的部分）

模板是"骨架"，用占位符标记"活肉"。占位符命名要和参数一一对应，这里统一用 `{{METHOD}}`、`{{PATH}}`、`{{DESC}}`、`{{NAME}}`（由路径派生）。注意：`{{...}}` 是给 Claude 看的"提示性占位"，真正的参数替换靠步骤四的 `$method` 机制。

`templates/route.tpl`：

```js
// Auto-scaffolded by endpoint-scaffold skill
import { {{NAME}}Handler } from '../handlers/{{NAME}}.js';

router.{{METHOD_LOWER}}('{{PATH}}', {{NAME}}Handler);
```

`templates/handler.tpl`：

```js
// {{DESC}}
export async function {{NAME}}Handler(req, res) {
  try {
    // TODO: implement business logic for {{METHOD}} {{PATH}}
    res.status(501).json({ error: 'not implemented' });
  } catch (err) {
    res.status(500).json({ error: String(err) });
  }
}
```

`templates/test.tpl`：

```js
import { describe, it, expect } from 'vitest';
// import { {{NAME}}Handler } from '../handlers/{{NAME}}';

describe('{{METHOD}} {{PATH}}', () => {
  it('should {{DESC}}', async () => {
    // TODO: wire up request mock and assert response
    expect(true).toBe(true);
  });
});
```

`templates/doc.tpl`：

```markdown
# {{METHOD}} {{PATH}}

{{DESC}}

## Request
TODO

## Response
TODO
```

**预期结果**：四个 `.tpl` 文件躺在 `templates/`，它们本身不会自动加载进上下文——这正是渐进式披露的好处。只有 `SKILL.md` 在被调用时进入对话，模板文件是 Claude "按需读取"的资料。

## 步骤四：写 SKILL.md——把三股力量拧到一起

这是全教程的核心。一份 `SKILL.md` 同时调度命名参数、动态注入、模板引用三种能力。

`.claude/skills/endpoint-scaffold/SKILL.md`：

```markdown
---
name: endpoint-scaffold
description: Scaffold a complete API endpoint (route + handler + unit test + API doc) from a one-line spec. Use when the user asks to add/create a new endpoint, generate CRUD scaffolding, or build out a new route with tests and docs.
when_to_use: triggers on phrases like "加个接口", "新建 endpoint", "生成 CRUD", "scaffold a route", "add an API"
argument-hint: [METHOD path description...]
arguments: [method, path, desc]
allowed-tools: Read, Write, Edit, Glob, Bash(ls *), Bash(test *)
---

## Current request
Scaffold the endpoint: **$method $path** — $desc

## Project context (auto-detected)
- Stack hint: !`cat package.json 2>/dev/null | grep -E '"(express|fastify|koa|next|vitest|jest)"' || echo "no package.json or unknown stack"`
- Existing routes: !`ls src/routes 2>/dev/null || ls routes 2>/dev/null || echo "no routes dir yet"`

## Your task
Produce the "四件套" (four files) for the endpoint above.

1. Derive `{{NAME}}` from `$path`: take the last non-param segment, drop a trailing `/:id`, convert to camelCase (e.g. `/api/users/:id` → `users`; `/api/orders/:id/items` → `orderItems`).
2. Lowercase `$method` for the router call (`{{METHOD_LOWER}}`).
3. Read each template file and fill the placeholders, then write the result:
   - templates/route.tpl   → src/routes/{{NAME}}.js
   - templates/handler.tpl → src/handlers/{{NAME}}.js
   - templates/test.tpl    → tests/{{NAME}}.test.js
   - templates/doc.tpl     → docs/{{NAME}}.md
4. If `src/routes/index.js` (or equivalent registry) exists, append a registration import for the new route.
5. Print a one-line summary: which files were created and a suggested next command.

Keep generated code minimal and idiomatic to the detected stack. When the stack is unknown, default to plain Express-style handlers and note the assumption in the doc file.

## Resources
- For one worked example of input→output, read [examples/one-liner-to-files.md](examples/one-liner-to-files.md)
- Templates live in [templates/](templates/) — read them on demand, do not assume their contents.
```

逐行拆解这股力量的来源：

**命名参数**：frontmatter 的 `arguments: [method, path, desc]` 把 `/endpoint-scaffold POST /users 创建用户` 拆成三段，正文里 `$method`→`POST`、`$path`→`/users`、`$desc`→`创建用户`。多词描述要用引号包裹，`/endpoint-scaffold POST /users "create a guest user"` 才能把第三段当整体。

**动态上下文注入**：`!`cat package.json ...`` 在正文送达 Claude **之前**执行，命令输出原地替换占位符。Claude 看到的不是命令本身，而是真实的项目栈与已有路由——这正是脚手架能"自适应"的原因。多行命令用 ` ```! ` 围栏。

**模板引用**：结尾的"Resources"列出支持文件，并写明何时该读。Claude 不会预读 `templates/`，只在执行到第 3 步时按需 `Read`，把占位符成本降到最低。

**allowed-tools**：预授权 `Read/Write/Edit/Glob` 与受限的 `Bash(ls *)`、`Bash(test *)`，省去逐次确认；但不放开任意 `Bash`，避免 Skill 自我授权执行危险命令。项目级 Skill 的 `allowed-tools` 在你接受 workspace trust 对话框后才生效——这是反恶意 Skill 的护栏。

**预期结果**：保存后无需重启，输入 `/endpoint-scaffold` 应能在补全菜单看到该 Skill，`argument-hint` 提示 `[METHOD path description...]`。

**常见问题与解决**：

| 现象 | 原因 | 解决 |
|---|---|---|
| 菜单里看不到 Skill | 目录名拼错或 `SKILL.md` 不在根 | 确认路径为 `.claude/skills/endpoint-scaffold/SKILL.md` |
| `$desc` 只取到第一个词 | 未加引号 | 多词参数整体加引号 |
| Skill 触发但栈识别错误 | `!` 命令输出为空 | 手动检查探测命令能否在项目根跑通 |
| Skill 不被自动触发 | description 不含触发短语 | 把 `when_to_use` 写满真实触发句 |

## 步骤五：补一个对照样例，让 Claude "照着抄"

`examples/one-liner-to-files.md` 是渐进式披露的另一关键：给 Claude 一个明确的输入→输出映射，减少自由发挥导致的跑偏。

```markdown
# Input
/endpoint-scaffold POST /api/orders 创建订单

# Derived
NAME = orders
METHOD_LOWER = post

# Output files
- src/routes/orders.js
- src/handlers/orders.js
- tests/orders.test.js
- docs/orders.md

# Sample handler (filled)
export async function ordersHandler(req, res) {
  try {
    res.status(501).json({ error: 'not implemented' });
  } catch (err) {
    res.status(500).json({ error: String(err) });
  }
}
```

有了这份样例，Claude 遇到边界情况（如路径带 `/:id`）会更倾向遵循既有派生规则，而非自己发明。

## 步骤六：跑通第一刀

在项目根目录启动 Claude Code：

```bash
claude
```

两种调用方式都试一次：

```
/endpoint-scaffold POST /users 注册新用户
```

或者用自然语言触发（验证 description 是否生效）：

```
帮我加个接口：GET /products 列出所有商品，要带测试和文档
```

**预期结果**：Claude 先读取模板，按派生规则填充占位符，写出四个文件，并在 `src/routes` 注册新路由，最后给出一行总结。整个过程应可逆——若不满意，删掉生成的文件即可。

验证生成的测试能跑：

```bash
npx vitest run tests/users.test.js
```

## 步骤七：用对照基线迭代

Skill 能触发，不等于它做对了。官方推荐的检验法是**带基线对照**：收集 3–5 条真实请求，分别在"启用 Skill"和"禁用 Skill"的新会话里跑，比较产物。为什么要新会话？因为编写 Skill 时残留的上下文会掩盖正文写得不够好的缺陷。

若触发准确率不稳，优先改 `description` 与 `when_to_use`；若触发准但产物差，改正文步骤或补 `examples/`。更系统的方式是装官方插件：

```
/plugin install skill-creator@claude-plugins-official
```

它会为每个测试用例在隔离子代理里跑、记录 token 与耗时、生成 `benchmark.json`，支持两个 Skill 版本的盲测 A/B——改动是否真的是改进，用数据说话。

## 实战案例：从 1 个接口到 N 个接口

假设要给一个电商后端快速铺底。按下面顺序喂同一句式：

```
/endpoint-scaffold POST   /api/orders         创建订单
/endpoint-scaffold GET    /api/orders/:id     查询订单详情
/endpoint-scaffold PATCH  /api/orders/:id     更新订单状态
/endpoint-scaffold DELETE /api/orders/:id     取消订单
/endpoint-scaffold GET    /api/products       商品列表
```

每次 `!`ls src/routes`` 注入的"已有路由"清单会随轮次增长，Claude 能据此决定是否需要新建注册条目还是复用现有 `orders` 文件。一轮下来你拿到 20 个文件（5 组四件套），每个 handler 都是可编译的 501 占位实现，测试是可运行的红绿骨架。接下来把精力集中到业务逻辑即可——这正是脚手架类 Skill 的价值：**把"从零搭壳"的时间压缩到接近零**。

进阶可叠加的能力：在正文里加 `ultrathink` 触发更深推理，处理复杂派生；或加 `context: fork` 让 Skill 在隔离子代理里执行，避免污染主会话上下文——后者适合那些需要大段探索的生成任务。但要记住官方警告：`context: fork` 只适合"有明确任务的 Skill"，纯参考类 Skill 放进子代理会因没有可执行任务而无功而返。

## 工作流程全景

```mermaid
flowchart TD
    A["用户输入<br/>/endpoint-scaffold POST /users 注册新用户"] --> B{"Claude Code<br/>匹配 description/when_to_use"}
    B -->|命中| C["frontmatter 解析<br/>arguments: method path desc"]
    C --> D["动态注入预执行<br/>!`cat package.json` → 真实栈<br/>!`ls src/routes` → 已有路由"]
    D --> E["SKILL.md 正文进入会话<br/>模板文件尚未加载"]
    E --> F["Claude 执行步骤1-2<br/>派生 NAME / METHOD_LOWER"]
    F --> G["按需 Read templates/*.tpl<br/>渐进式披露: 只读需要的文件"]
    G --> H["Write 四件套<br/>route/handler/test/doc"]
    H --> I["注册路由 + 输出总结"]
    I --> J["基线对照迭代<br/>skill-creator 跑 benchmark.json"]
    B -->|未命中| K["降级为普通对话<br/>或检查 description 触发短语"]
```

## 延伸阅读

- 官方 Skills 完整文档（frontmatter 全字段、子代理执行、动态注入规范）：`code.claude.com/docs/en/skills`
- Agent Skills 开放标准（Claude Code Skills 遵循的跨工具规范）与 skill-creator 评测工作流：`agentskills.io`
- 5 个可直接套用的 SKILL.md 示例与安全控制写法：`fp8.co/articles/Claude-Code-Skills-Complete-Developer-Guide`

## 训练营适用性评估

- **适合类型**：后端工程训练营、全栈速成营、AI 辅助研发企业内训。学员需有基础 Web 框架经验，能在 Claude Code 里跑通一个真实项目。
- **不适合类型**：零基础编程营（会卡在"为什么这样派生 NAME"上）、纯前端营（路由/处理器概念生疏）。
- **教学时长**：约 90 分钟。30 分钟讲透三个核心机制（渐进式披露、命名参数、动态注入），40 分钟动手造 Skill 并跑通第一刀，20 分钟做基线对照与 description 调优。
- **可裁剪**：时间紧时砍掉步骤七（基线评测），把重点压在步骤三到六；进阶班可追加 `context: fork` 子代理执行与 `disallowed-tools` 自主护栏两个扩展点。

## 参考来源

1. [Extend Claude with skills — Claude Code Docs](https://code.claude.com/docs/en/skills) — 官方权威文档，frontmatter 字段、字符串替换、动态注入、支持文件、子代理执行与 skill-creator 评测机制的完整规范来源
2. [How to Build Claude Code Skills: 5 Examples (2026)](https://fp8.co/articles/Claude-Code-Skills-Complete-Developer-Guide) — SKILL.md 规范、安全控制与可直接套用的五个实战示例
3. [Create-Skill — Scaffolding Claude Code Skills](https://juri.dev/notes/create-skill-scaffolding-claude-code-skills/) — Skills 作为可复用提示模块的设计哲学与目录约定
4. [Project Scaffolding Skill for Claude Code](https://github.com/hmohamed01/Claude-Code-Scaffolding-Skill) — 一个真实的脚手架 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)
