# 36 · 斜杠命令（Slash Commands）：一个 `/` 调出 Claude 的所有快捷动作

> 📚 **系列导航**：上一篇 [35 控制与模式](35-modes-and-control.md) 教你怎么在会话里给 Claude 收紧或放开缰绳（权限模式、`/model`、`/effort` 这些开关）。这一篇把视角拉回到那个你每天都在敲、却未必真摸透的入口——**斜杠命令**。打一个 `/`，从切模型、清上下文到你自己刻的一键流程，全在这一个菜单里。我带你把内置的那批认全，再教你刻几个自己的。

很多人刚用 Claude Code 那阵，都干过一件挺蠢的事。

每次想清空对话重开，都老老实实做这么一套：先 `Ctrl+C` 退出 `claude`，再在终端重新敲 `claude` 启动，等它重新加载一遍项目、读一遍 `CLAUDE.md`——前前后后小十秒。**这么连着干上一两周**，心里还觉得「重启嘛，本来就该这样」。直到翻官方文档，撞见一个 `/clear` 命令，一句话写着「开一段空上下文的新对话」。这才发现：**原来在会话里打三个字符就行，那两周的重启全是白费功夫。**

更打脸的是后面。`/compact` 能把长对话压缩了接着聊、`/model` 能不重启直接换模型、`/init` 能一键生成 `CLAUDE.md`……**全是要么之前手动硬来、要么压根不知道能干的事**。这些命令一直就躺在那个 `/` 菜单里，打个斜杠就全列出来了，却一个都没翻过。

说这段糗事是想让你别走弯路：**斜杠命令不是「高级玩法」，它是 Claude Code 最基础的控制面板**。你在会话里想干的绝大多数「元操作」——不是让它写代码，而是调教它本身——入口都在这一个 `/`。这一篇先把内置的那批给你认全，再教你把那些天天手打的提示，刻成你自己的一键命令。

**看完这一篇，你会拿到：**

- 一句话说清斜杠命令是什么、为什么它只在消息开头才算数
- 一张「按使用场景分组」的内置命令清单（`/help`、`/clear`、`/compact`、`/init`、`/model`、`/agents`、`/mcp`、`/memory` 等），不用背、按需查
- 自己写一个斜杠命令的完整步骤：`.claude/commands/` 下扔个 markdown、加 frontmatter、用 `$ARGUMENTS` 传参
- 一招进阶玩法：让命令在发给 Claude 前自己把 `git diff` 这类「现场数据」填进去
- 命名空间是怎么回事，为什么插件带的命令永远不会跟你的撞名
- 斜杠命令和 Skill 到底什么关系（一句话：slash command 就是 Skill 的「主动喊」用法，详见第 26 篇）
- 一个能照着跑、给了预期输出的实战：5 分钟刻一个带参数的 `/explain` 命令并验证

---

## 01 先搞懂：斜杠命令到底是个啥，凭什么只在开头算数

先给结论：**斜杠命令就是你在 Claude 会话里打的「控制指令」——不是说给 Claude 听让它干活，而是直接命令 Claude Code 这个程序本身**：切模型、清上下文、跑个流程、开个面板。

你回想前面三十多篇，跟 Claude 打交道一直分两种话。一种是**正经需求**：「帮我把这个函数重构一下」「这段报错咋回事」——这是说给模型听的。另一种是**元操作**：「把对话清了重开」「换成更省的模型」「生成一份项目说明」——这些不该靠跟模型「聊」，而该有个**直接的开关**。斜杠命令就是这批开关的统一入口。

**类比：电视遥控器上那排印好的按钮。** 你看电视，调台、调音量、切信源、开菜单——不会冲着电视喊「请帮我把声音调大」，你按遥控器上对应的那颗按钮。**每颗按钮干一件确定的事，按下去立刻生效，不用解释、不会理解错**。斜杠命令就是 Claude Code 的这排按钮：`/clear` 是清屏键、`/model` 是切信源键、`/help` 是那颗菜单键——打下去执行的是程序写死的固定动作，跟「求模型帮忙」是两码事。

官方对它的定位讲得很干脆：

> 命令从会话内部控制 Claude Code。它们提供了一种快速切换模型、管理权限、清除上下文、运行工作流等的方法。

这里有个**新手最容易栽的点**，官方专门强调过——**斜杠命令只在消息的开头才被识别**：

> 命令仅在消息开头被识别。命令名称之后的文本作为参数传递给它。

说白了：你得让 `/` 当这条消息的**第一个字符**，它才被当成命令。如果你写「帮我看看 /clear 是干嘛的」，这个 `/clear` 在句子中间，**不会被执行**，只会被当成普通文字发给 Claude。这个设计是有道理的——否则你跟 Claude 讨论命令本身时，一提到 `/clear` 对话就被清了，那不乱套了。**记住：命令打头，后面跟的全是参数。**

落到你真实会遇到的几个瞬间，体会一下这排「按钮」啥时候按：

- **聊着聊着发现模型不够强**——不用退出重开，打 `/model` 当场换上更强的，对话不断。
- **一个任务干完了，想换个全新的活儿**——打 `/clear` 把台面擦干净，旧对话还能 `/resume` 找回来。
- **刚 clone 了个陌生项目，想让 Claude 先懂它**——打 `/init`，它读一遍代码、给你吐一份 `CLAUDE.md`。

这几件事的共同点：**都不是「让 Claude 写代码」，而是「调教 Claude Code 本身」**——这正是斜杠命令的主场。

那怎么知道有哪些命令可用？最省事的办法——**在会话里打一个 `/`**，菜单立刻弹出来，列出你当前能用的全部命令；接着再多打几个字母，它会实时筛选。官方原话：

> 输入 `/` 查看你可用的每个命令，或输入 `/` 后跟字母进行筛选。

> 💡 一句话总结：斜杠命令是 Claude Code 的「控制按钮排」——管的是程序本身（切模型、清上下文、跑流程），不是给模型派活；**它只在消息开头才算数，打一个 `/` 就能看到全部可用命令**。

---

## 02 内置命令清单：不用背，按「你在干哪一步」来查

内置命令有几十个，**真要一个个背，纯属跟自己过不去**。Claude Code 官方文档自己也是按「一次会话的典型流程」来组织的——你处在哪一步，自然就该用哪几个。我把最常用的按这个思路理成几组，**对着「你现在想干啥」找那一行就行**。

先说清楚一件事：这几十个里，**绝大多数是「内置命令」**（行为写死在 CLI 里，按下去执行固定逻辑），还有一小撮在文档里标着 **Skill**——那是「捆绑 Skill」，本质是给 Claude 的一份提示，让它用自己的工具去编排完成（比如 `/code-review`、`/debug`）。另有更少的几个标着 **Workflow**——那是多 subagent 并行的动态流程（如 `/batch`、`/deep-research`），调用体验一样，底层更复杂，这里知道有这回事即可。**三种你都用 `/` 加名字调，用起来没区别**，差别只在底层怎么实现——这个细节第 26 篇讲 Skill 时拆过，这里不展开。

### 第一组：刚进一个项目，搭场子用的

| 命令 | 干啥的 | 你啥时候用 |
|------|--------|-----------|
| `/init` | 给项目生成一份起步的 `CLAUDE.md` | 第一次在某个仓库里开工（详见第 12 篇） |
| `/memory` | 编辑 `CLAUDE.md` 记忆文件、管自动记忆 | `/init` 之后想细调那份说明（详见第 25 篇） |
| `/mcp` | 管 MCP server 连接和授权 | 要接外部服务时（详见第 22 篇） |
| `/agents` | 管子代理（subagent）配置 | 要配专项小弟时（详见第 23 篇） |
| `/permissions` | 管「允许 / 询问 / 拒绝」的权限规则 | 想定好它动手前问不问你（详见第 20 篇） |

这一组进新项目时基本是**固定套路**：先 `/init` 让它读一遍代码、吐一份 `CLAUDE.md` 草稿，再 `/memory` 进去把它瞎猜错的几条改对。**省得从零手写那份说明**——这套流程头一回用的时候，是真有点惊喜。

### 第二组：干活干到一半，调状态用的

| 命令 | 干啥的 | 你啥时候用 |
|------|--------|-----------|
| `/model` | 切换模型，并存成新会话的默认 | 想换更强或更省的模型 |
| `/clear` | 开一段空上下文的新对话（旧的还能 `/resume` 找回） | 换个全新任务，台面收拾干净 |
| `/compact` | 把当前对话压缩成摘要，腾出上下文接着聊 | 对话太长、工作台快塞满（详见第 19 篇） |
| `/context` | 把当前上下文占用画成一张彩色网格 | 想看「我的工作台都被谁占了」 |
| `/plan` | 直接进 plan 模式 | 大改动前先让它出方案不动手 |

`/clear` 和 `/compact` 这俩**最容易混**，开头那段栽的坑就是没分清「清空」和「压缩」。一句话切：**换个不相干的新活儿用 `/clear`（台面全擦掉重开），同一个任务但聊太长了用 `/compact`（把草稿纸整理成一页要点接着干）**。第 19 篇专门拆过这对，这里你记住「换任务 clear、续任务 compact」就够。

### 第三组：活儿要交出去之前，检查用的

| 命令 | 干啥的 |
|------|--------|
| `/diff` | 开一个交互式 diff 查看器，看未提交的改动 |
| `/review` | 在当前会话里审一个 PR |
| `/security-review` | 专门扫当前分支改动的安全漏洞 |
| `/code-review` | 审 diff 找 bug 和可简化处，能加 `--fix` 直接改 |

### 第四组：杂项里你早晚会用到的几个

| 命令 | 干啥的 |
|------|--------|
| `/help` | 显示帮助和可用命令 |
| `/config` | 打开设置界面，调主题、模型、输出样式等 |
| `/doctor` | 体检你的安装和配置，按 `f` 让它自动修 |
| `/resume` | 按 ID 或名字恢复一段旧对话，或开选择器 |
| `/skills` | 列出当前可用的全部 Skill |
| `/rewind` | 把对话和 / 或代码回退到某个检查点（下一篇主角） |

> **注意：不是每个命令对每个人都显示。** 官方说得明白——「可用性取决于你的平台、套餐和环境」。比如 `/desktop` 只在 macOS 和 Windows 上、且用 Claude 订阅登录时才出现，`/upgrade` 只在 Pro 和 Max 套餐上才有。**你打 `/` 看到的那张菜单，就是你这台机器、这个账号此刻真正能用的全集**——以它为准，别拿别人截图里的命令较真。

这四组我没给全（官方那张总表有几十行），但**覆盖了你日常九成的场景**。剩下的，临时想干啥，打个 `/` 加几个字母筛一下，比翻文档实在得多。

> 💡 一句话总结：内置命令别硬背，**按「你在哪一步」分组查**——搭场子（`/init` `/memory` `/mcp` `/agents`）、干活中（`/model` `/clear` `/compact` `/context`）、交付前（`/diff` `/review` `/code-review`）、杂项（`/help` `/doctor` `/resume`）；菜单是你这台机器的真实全集，打 `/` 即见。

---

## 03 自己刻一个命令：`.claude/commands/` 下扔个 markdown 就行

内置命令认全了，**真正让斜杠命令好用的，是你能自己造**。

为啥要自己造？想想你日常跟 Claude 打交道里那些「重复劳动」——每次让它提交代码都叮嘱同一套规矩、每次审 PR 都打同一段开场白、每次解释代码都强调「说人话别堆术语」。**同一段提示打第五遍的时候，就是信号：该把它刻成一个命令了。**

**类比：给遥控器编一个「学习键」。** 好点的万能遥控器上有颗「学习键」——你把一串常用操作（开机→切到 HDMI2→音量调到 15）录进去，以后按一下这颗键，整串动作自动跑完，不用再一颗颗按。自定义斜杠命令就是这颗学习键：**你把一段反复要敲的提示「录」成一个命令，以后打一下命令名，那段提示自动发出去。**

怎么造？**简单到你可能不信——在 `.claude/commands/` 目录下扔一个 markdown 文件，文件名就是命令名**。官方文档写得很清楚：

> `.claude/commands/deploy.md` 中的文件……会创建 `/deploy`。

也就是说，你建一个 `.claude/commands/commit.md`，里面写上你那套提交规矩，**它就自动变成了 `/commit` 命令**。文件名（去掉 `.md` 后缀）就是你打的命令名，零配置。

举个最朴素的例子。你新建 `.claude/commands/review.md`，里面写：

```markdown
请审查我当前未提交的改动，重点看三件事：
1. 有没有缺失的错误处理
2. 有没有写死的配置值（端口、密钥、路径）
3. 有没有该补而没补的测试

用中文逐条列出，每条标明在哪个文件。
```

存好之后，你在会话里打 `/review`，**Claude 收到的就是上面这整段提示**——等于你把那段话一字不差地敲了一遍，但你只打了七个字符。

这里有个**关于「放哪」的关键区分**，跟前面讲 MCP、Skill 时一脉相承：

| 放哪 | 命令作用范围 | 进 git 吗 |
|------|------------|----------|
| **项目级** `.claude/commands/` | 仅当前这个项目 | 进，**全队拉下来都能用** |
| **个人级** `~/.claude/commands/` | 你的所有项目 | 不进，**你私人的** |

逻辑跟 Skill 完全一致：**这命令是这个项目专属、还想让协作者也用的**（比如本项目的发版流程），放项目级并提交进版本库；**只有你自己、跨项目通用的**（比如你个人的解释代码习惯），放个人级 `~/.claude/commands/`。`~/.claude/commands/` 里常年躺着几个跨项目的小命令，换到哪个项目都在，这点比每个项目重配省心多了。

> 💡 一句话总结：自定义命令就是「把反复打的提示录成一键」——**在 `.claude/commands/` 下放个 markdown，文件名即命令名，零配置**；放项目级全队共享、放 `~/.claude/commands/` 个人跨项目通用。

---

## 04 给命令加料：前置配置（frontmatter）和 `$ARGUMENTS` 传参

上一节那个 `/review` 已经能用了，但它有个明显的局限：**内容写死，不能传参**。你没法告诉它「就审 `src/auth.ts` 这一个文件」——它每次都审全部改动。要让命令灵活起来，得加两样东西：**前置配置（frontmatter）** 和 **参数占位符**。

### 用 `$ARGUMENTS` 接住你传的参数

先解决传参。Claude Code 提供了一个占位符 `$ARGUMENTS`——**命令名后面你打的所有内容，都会替换到这个占位符的位置**。官方文档给的例子最直观：

```markdown
Fix GitHub issue $ARGUMENTS following our coding standards.

1. Read the issue description
2. Understand the requirements
3. Implement the fix
```

官方原话解释它的效果：

> 当你运行 `/fix-issue 123` 时，Claude 收到「Fix GitHub issue 123 following our coding standards...」

看明白了吗？你打 `/fix-issue 123`，那个 `123` 就被塞进了 `$ARGUMENTS` 的位置。**一个命令模板，参数随你换**——这才是命令真正好用的地方。

> 还有个贴心的兜底：官方说，**如果你传了参数、但命令里压根没写 `$ARGUMENTS`**，Claude Code 会把 `ARGUMENTS: <你的输入>` 自动追加到命令内容末尾，「以便 Claude 仍然看到你输入的内容」。所以就算你忘了写占位符，参数也不会凭空丢掉。

### 想传好几个参数？用 `$0` `$1` 按位置取

要是一个命令得传多个参数怎么办？比如「把 `SearchBar` 组件从 `React` 迁到 `Vue`」，这里有三个独立的值。官方提供了**按位置取参**的写法——`$ARGUMENTS[N]`，或者更短的 `$N`（都从 0 开始数）：

```markdown
Migrate the $0 component from $1 to $2.
Preserve all existing behavior and tests.
```

你运行 `/migrate-component SearchBar React Vue`，`$0` 就是 `SearchBar`、`$1` 是 `React`、`$2` 是 `Vue`。**注意一个坑**：官方说这些按位置取的参数走的是「shell 风格的引用」——所以**多个词的值要用引号包起来**才算一个参数。比如 `/my-cmd "hello world" second`，`$0` 才是完整的 `hello world`，否则会被空格拆开。（而 `$ARGUMENTS` 不受影响，它永远是你输入的那整串原文。）

### 用 frontmatter 控制命令的行为

光能传参还不够。你那个 `/deploy`、`/commit` 命令是带副作用的——**你肯定不希望 Claude「看你代码像写好了」就自作主张帮你部署**。这就要靠 frontmatter 来管。

frontmatter 就是写在文件开头两道 `---` 之间的一块 YAML 配置（这个概念第 26 篇讲 `SKILL.md` 时见过，**自定义命令文件支持完全相同的 frontmatter**）。最该知道的两个字段：

```markdown
---
description: 把当前改动暂存并提交
disable-model-invocation: true
---

把当前改动提交，commit 信息用中文、前缀按 feat/fix/docs：

1. 先跑测试套件
2. git add 改动
3. 用规范的中文信息提交
```

- **`description`**：一句话说明这命令干啥。Claude 靠它判断「要不要自动用这个命令」，所以**建议都写上**。
- **`disable-model-invocation: true`**：设成 `true`，**这个命令就只有你能手动喊，Claude 不会自动触发它**。带副作用、你想亲手掐时机的活儿（部署、提交、发消息），都该加这一条。

这就引出一个你必须搞清的认知，省得它「擅自行动」吓你一跳——**你的自定义命令默认是「你和 Claude 都能调」的**。你打 `/commit` 是手动调；但因为你写了 `description`，Claude 在它觉得对得上的时候，**也可能自己调**。这正是斜杠命令和 Skill 是「一回事」的体现（详见第 26 篇）——**怕它自动乱动手，就加 `disable-model-invocation: true` 锁成纯手动**。`/commit` 这类命令第一条就该是它，不然有几次它真会差点替你把没看完的改动提交了。

| 你想要的效果 | 加什么 frontmatter |
|------------|------------------|
| 命令带副作用、只许我亲手喊 | `disable-model-invocation: true` |
| 让 Claude 知道这命令何时该用 | 写好 `description` |
| 限制它处于活动时能用哪些工具不用每次问 | `allowed-tools: Bash(git add *) Bash(git commit *)` |

> 💡 一句话总结：`$ARGUMENTS` 接住命令名后的全部输入、`$0`/`$1` 按位置取（多词值要加引号）；frontmatter 里 **`description` 让 Claude 知道何时用、`disable-model-invocation: true` 锁成纯手动**——带副作用的命令务必加后者。

---

## 05 进阶一招：让命令自带「现场数据」

到这儿你的命令已经能传参了，但还有个更狠的招——**让命令在发给 Claude 之前，自己先把现场数据填进去**。这招叫**动态上下文注入（dynamic context injection）**，是自定义命令文件最被低估的一个能力。

先说它解决什么。你那个 `/review` 命令，里头写的是「请审查我当前未提交的改动」——但 Claude 拿到这句话，**还得自己去跑一遍 `git diff` 才知道你改了啥**。能不能在它读到命令之前，就把 diff 直接塞好？能。

**写法是在命令里写 `` !`命令` ``** ——一个感叹号加反引号包住一条 shell 命令。官方文档讲得很清楚：

> `` !`<command>` `` 语法在将内容发送给 Claude 之前运行 shell 命令。命令输出替换占位符，因此 Claude 接收实际数据，而不是命令本身。

举个例子，把 `/review` 升级一下。你在 `.claude/commands/review.md` 里这么写：

```markdown
## 当前改动

!`git diff HEAD`

## 说明

审查上面这段改动，重点看缺失的错误处理、写死的配置值、该补的测试。用中文逐条列出。
```

那行 `` !`git diff HEAD` `` 会发生什么？官方说的执行顺序是这样的：

1. Claude Code 先把 `git diff HEAD` 跑了
2. 把这条命令的**输出**替换到那一行
3. Claude 看到的，是**已经填好你此刻真实 diff 的完整提示**

也就是说，**Claude 拿到手的不是「去跑个 diff」，而是「这是用户的改动：……（真实内容），请审查」**。这是预处理，不是 Claude 自己执行的——它只看到最终填好的结果。给那个 `/review` 加上这一行之后，明显能感觉它「上来就进入状态」，不用再绕一圈先查改动了。

几个**用之前得知道的细节**，免得踩坑：

- **感叹号得在行首、或紧跟空白后**才生效。要是写成 `KEY=!`cmd`` 这种紧贴在别的字符后面，它就被当成普通文字，命令不会跑。
- **多行命令**别用内联写法，改用 ` ```! ` 开头的围栏代码块（里面一行一条命令）。
- 这能力**能被关掉**：设置里有个 `disableSkillShellExecution`，设成 `true` 后这些命令一律不执行、替换成英文提示 `[shell command execution disabled by policy]`。在团队的托管设置里它最有用——**防止有人在共享仓库的命令里塞个乱跑的 shell 命令**。

顺带一个自动补全的小贴士：frontmatter 里加一行 `argument-hint`（比如 `argument-hint: [issue-number]`），你打命令名时自动补全会提示「这命令该传啥参数」。命令多了之后，这点提示能帮你少翻文档。

> 💡 一句话总结：`` !`命令` `` 能让斜杠命令**在发给 Claude 前先把现场数据（如 `git diff`）填进去**，Claude 拿到的是真实数据而非「去跑个命令」；感叹号要在行首、多行用 ` ```! ` 块、团队可用 `disableSkillShellExecution` 一键禁掉。

---

## 06 命名空间：为什么插件带的命令永远不撞名

自己造命令多了、再装几个插件（每个插件也带一堆命令），一个现实问题就来了：**会不会撞名？** 比如你写了个 `/review`，装的某个插件里也有个 `/review`，打下去到底跑哪个？

先说会撞的那种和不会撞的那种，**关键看命令从哪来**。

### 你自己的命令之间：靠优先级定胜负

如果是你自己的 `.claude/commands/` 文件和 `.claude/skills/` 里的 Skill 同名——官方给了明确规则：

> 如果 skill 和命令共享相同的名称，skill 优先。

也就是说，你有个 `.claude/commands/deploy.md`，又有个 `.claude/skills/deploy/SKILL.md`，**打 `/deploy` 走的是那个 Skill**。记住这条「同名 Skill 赢」就行，平时你也很少会故意造俩同名的。

### 插件带的命令：靠命名空间，根本不会撞

插件的处理方式更彻底——**它压根不跟你抢名字**。官方原话：

> 插件 skills 使用 `plugin-name:skill-name` 命名空间，因此它们不能与其他级别冲突。

**类比：手机通讯录里给同名的人加公司前缀。** 你通讯录里有俩「张伟」，你会怎么存？多半备注成「张伟（红杉）」「张伟（高瓴）」——加个前缀，俩人就再也不会混。命名空间干的就是这事：插件 `my-plugin` 里那个 `review`，在你这儿叫 **`/my-plugin:review`**，前面那截插件名就是「公司前缀」。所以哪怕你自己也有个 `/review`，俩命令一个带前缀一个不带，**井水不犯河水**。

这就是为什么前面第 24 篇讲插件时说「插件 Skill 永远不会跟你的撞名」——**靠的就是这套 `插件名:命令名` 的命名空间**。装多个插件、每个都带 `review`，它们分别是 `/plugin-a:review`、`/plugin-b:review`，各喊各的。

还有一类带「双下划线」的命令你可能撞见：**MCP server 暴露的提示**。官方说它们用 `/mcp__<server>__<prompt>` 这种格式，从连上的 server 动态发现。看到一个 `/mcp__github__xxx` 别懵——那是某个 MCP server 自带的命令（详见第 22 篇）。

> 💡 一句话总结：自己的命令同名时**「Skill 赢过 command」**；插件命令靠 **`插件名:命令名` 命名空间**，天生不撞；MCP server 的命令是 `/mcp__<server>__<prompt>` 格式——三种来源，认前缀就不会乱。

---

## 07 斜杠命令和 Skill：到底什么关系，一句话理清

学到这儿你可能犯嘀咕了：**斜杠命令、Skill，这俩听着怎么这么像？我刚在 `.claude/commands/` 写的东西，跟第 26 篇在 `.claude/skills/` 写的 `SKILL.md`，到底啥区别？**

这是个**好问题，也是新手最容易绕进去的一个结**。一句话给你解开：

> **自定义斜杠命令，已经被官方合并进了 Skill 体系。** 你的 `.claude/commands/` 文件照样能用，但 Skill 是「升级版」——多了能带配套文件、能由 Claude 自动触发、描述先进上下文而长文档调用时才加载（而非全量预载）这几样本事。

官方那句原话很直接：

> 自定义命令已合并到 skills 中。`.claude/commands/deploy.md` 中的文件和 `.claude/skills/deploy/SKILL.md` 中的 skill 都会创建 `/deploy` 并以相同的方式工作。

所以这俩**根本不是对立的两个东西**，而是同一个能力的两种写法。换个角度说：**「斜杠命令」更像是一种「调用方式」（你打 `/` 主动喊），而 Skill 是那个被喊的「本体」**。第 26 篇那张表已经把 Skill、slash 命令、Subagent 的定位讲透了，这里我只补一张**「同一件事，两种写法怎么选」**的对照：

| 你的需求 | 用老式命令（`.claude/commands/xx.md`） | 用 Skill（`.claude/skills/xx/SKILL.md`） |
|---------|-----------------------------------|--------------------------------------|
| 就一段提示，纯手动喊 | ✅ 够了，最省事 | 也行，但杀鸡用牛刀 |
| 想带模板 / 脚本 / 示例文件 | ❌ 带不了 | ✅ 它是个目录，能装一堆配套文件 |
| 想让 Claude「该用时自动调」 | 写了 `description` 也能，但 Skill 是为这个设计的 | ✅ 主场 |
| 想塞长篇参考资料又不占上下文 | ❌ 无法配套附属文件（模板/脚本/长文档） | ✅ 支持附属文件目录，长文档在 SKILL.md 里按需引用、调用时不自动全量加载 |

**一条经验法则：** 就一段提示、自己手动喊一下的小活儿（像那个 `/review`），**老式 `.claude/commands/` 一个 markdown 最省事，别折腾**；一旦你发现「想给它配个模板」「想塞份长文档但别占上下文」「想让它自己判断该不该用」——**就该升级成 Skill**（怎么写见第 26、27 篇，懒得手写就用第 28 篇的 skill-creator）。

说白了，**你这一篇学的「自定义斜杠命令」，就是 Skill 体系最轻量的那个入口**。先用它把「一键提示」这件事玩顺，需要更多本事了，平滑升级到 Skill 就行——官方文档明确说「你现有的文件继续工作」，`.claude/commands/` 是被正式支持的写法，没有被废弃的意思。

> 💡 一句话总结：自定义斜杠命令**已经合并进 Skill 体系**——老式 `.claude/commands/` 是最轻量入口（纯一段提示、手动喊），需要配套文件 / 自动触发 / 渐进式披露时就升级成 Skill；**两者创建同名命令、用法完全一致**。

---

## 08 动手：5 分钟刻一个带参数的 `/explain` 命令

光看不练记不住。下面带你从零刻一个**真正能用、还能传参**的斜杠命令——一个「用大白话解释代码 / 报错」的 `/explain`。全程不依赖任何复杂环境，一个空目录就能跑通。

**第一步：建命令目录**（Mac / Linux）

在你随便一个项目目录下（没有就 `mkdir` 一个空的进去），创建 `.claude/commands/` 文件夹：

```bash
mkdir -p .claude/commands
```

Windows 用户：在项目根目录下手动新建 `.claude\commands\` 这两层文件夹即可。

**预期**：项目下多了 `.claude/commands/` 这个空目录。

**第二步：写命令文件**

用你顺手的编辑器，把下面内容存成 `.claude/commands/explain.md`：

```markdown
---
description: 用大白话解释一段代码或一个报错。当用户想搞懂某段代码或某个报错时使用。
---

请用初学者能懂的大白话，解释下面这个东西：

$ARGUMENTS

要求：
1. 先一句话说它整体在干啥
2. 再逐行 / 逐段拆开说清楚
3. 如果是报错，指出最可能的原因和怎么改
4. 少堆术语，能用生活类比就用
```

**注意两处**：开头 `---` 框起来的是 frontmatter，那句 `description` 让 Claude 知道这命令干啥；正文里那个 `$ARGUMENTS`，就是用来接住你待会儿传进去的代码 / 报错。

**预期**：`.claude/commands/` 里有了一个 `explain.md`。

**第三步：启动 Claude，确认命令已被识别**

```bash
claude
```

进去后**先打一个 `/`**（光打斜杠，别回车），看弹出的菜单：

**预期**：菜单里能看到 `/explain`，旁边是你写的那句 description。**看到它在菜单里 = 命令已被正确加载。** 如果没看到，多半是文件没存对地方——确认它在 `.claude/commands/explain.md`，不是别的路径。

**第四步：带参数喊它**

现在真正用它——打命令名，后面跟上你想解释的东西（这串会被塞进 `$ARGUMENTS`）：

```text
/explain print(sum([1,2,3]) / len([1,2,3]))
```

**预期**：Claude 收到的是你那段完整提示、其中 `$ARGUMENTS` 已被换成 `print(sum([1,2,3]) / len([1,2,3]))`。它会按你写的四步来——先一句话说整体（算这三个数的平均值）、再逐段拆、术语少、能类比就类比。**你只打了命令名加一段代码，那整套「解释要求」自动生效了，这就是 `$ARGUMENTS` 的威力。**

**第五步：换个参数再来一次**

同一个命令，换成解释报错：

```text
/explain ZeroDivisionError: division by zero
```

**预期**：同样触发 `/explain`，但这次 `$ARGUMENTS` 变成了那条报错，Claude 会按第 3 条要求重点说「最可能的原因和怎么改」（除数为 0 了）。**一个模板，参数随你换——这正是自定义命令比手打提示强的地方。**

跑通这五步，你就把自定义斜杠命令最核心的三件事——**「文件名即命令名」「frontmatter 加 description」「`$ARGUMENTS` 传参」**——亲手验证了一遍。以后想刻任何命令，本质都是这套流程，无非换个文件名、换段提示、按需加 frontmatter 字段。

> 💡 一句话总结：刻命令就三步——**`.claude/commands/` 下放个 markdown（文件名即命令名）、加 `description`、用 `$ARGUMENTS` 留参数位**；打 `/` 看它进菜单没，再带不同参数喊两次，亲手验证比记十条文档都实在。

---

## 09 小结

这一篇把斜杠命令从「你每天敲、但没摸透的入口」给你掀开看了——**它是 Claude Code 的控制面板，从内置的几十个开关到你自己刻的一键流程，全在一个 `/` 后面**。

把核心要点串起来回顾：

| 你想搞清的事 | 答案 | 关键点 |
|------------|------|--------|
| 斜杠命令是什么 | Claude Code 的控制指令 | 管程序本身，不是派活；只在消息开头算数 |
| 内置命令怎么记 | 按使用场景分组查 | 搭场子 / 干活中 / 交付前 / 杂项；打 `/` 即见真实全集 |
| 怎么自己造命令 | `.claude/commands/` 放 markdown | 文件名即命令名；项目级共享 / 个人级跨项目 |
| 怎么给命令传参 | `$ARGUMENTS` / `$0` `$1` | 命令名后的输入自动替换；多词值要加引号 |
| 怎么让命令带现场数据 | `` !`命令` `` 动态注入 | 发给 Claude 前先填好 `git diff` 等真实输出 |
| 怎么控制命令行为 | frontmatter | `description` 告知何时用、`disable-model-invocation` 锁手动 |
| 命令会不会撞名 | 三种来源各有规则 | Skill 赢 command、插件靠命名空间、MCP 走 `/mcp__` 前缀 |
| 和 Skill 啥关系 | 已合并进 Skill 体系 | 命令是最轻量入口，需要更多本事就升级成 Skill |

**你现在应该能：** 打一个 `/` 就看懂那张菜单、按「你在哪一步」找到该用的内置命令；把自己反复打的提示刻成一个 `.claude/commands/` 下的命令，用 `$ARGUMENTS` 让它接参数、用 frontmatter 管它的行为；分得清命令同名时谁赢、插件命令为啥不撞；并且想明白了斜杠命令和 Skill 本就是一回事——**前者是后者最轻量的入口，玩顺了随时能往上升级**。

回头看开头那两周的「重启大法」——**说到底就是没翻过那个 `/` 菜单**。这一篇之后，但凡你想对 Claude Code 本身做点啥，第一反应该是先打个斜杠看看有没有现成的开关；没有，就花两分钟刻一个。**这点习惯，能帮你省下那一大把白费的时间。**

---

下一篇 **37「检查点（Checkpoints）」**——这一篇末尾那个 `/rewind` 我只一笔带过，下一篇专门拆它。Claude 改了一通代码，方向跑偏了怎么办？**总不能每次都靠手动 `git reset` 或者干瞪眼。** 下一篇教你用 Claude Code 内置的检查点机制，像打游戏存档读档一样，把代码和对话一起「倒带」回某个干净的状态。想想看：要是每改几步就自动有个「存档点」，你试错的胆子是不是能大不少？
