目标:讲清 slash command 的本质(预定义 prompt 模板)、内置命令一览、自定义命令格式(frontmatter + $ARGUMENTS + 内联 shell)、四个命令来源及优先级链、安全模型。这是 C 面(Markdown 提示词)的第二个核心子系统。 受众:专业程序员。本机版本
2.1.220。
8.1 本质定义
slash command 是什么
slash command 是一个带名字的 prompt 模板。 本质和你在聊天框里打一段 prompt 没区别,区别只在于它是预定义的、可复用的、权限受控的。
bash
/foo bar
│
▼
runtime 找到名叫 "foo" 的命令文件
│
▼
把 "bar" 填入 $ARGUMENTS 占位符
│
▼
把整段 prompt 注入 agent 的 system prompt
│
▼
agent 按 prompt 里的指令执行
和普通 prompt 的区别
| 维度 | 普通聊天 | Slash Command |
|---|---|---|
| 定义 | 临时打字 | 文件预存,持久复用 |
| 共享 | 一人一次 | 文件可提交 git,团队共享 |
| 权限 | 全局 rules | allowed-tools 精确白名单 |
| 参数 | 手动描述 | $ARGUMENTS 结构化传参 |
| 上下文 | 静态 | ! 内联 shell 动态注入 |
和 Skills 的区别
Skill 是"按需加载的专项能力包",slash command 是"命名的 prompt 模板"。简单说:Skill 是一个带工具和知识的子系统,slash command 是一段预设好的指令。详见 Ch10。
8.2 内置命令
Claude Code 内置了一批 slash command,编译进二进制,永远存在。从二进制 strings 验证的非完整列表:
会话管理
| 命令 | 作用 |
|---|---|
/clear |
清空会话上下文,释放 token |
/compact |
压缩上下文(自动摘要历史,保留关键信息) |
/clear 是唯一能把 footer badges 清除的操作:"At most 5 badges render; the oldest is displaced by newer matches and /clear removes them."
当 autocompact 反复失败时,系统会提示:"Autocompact is thrashing: the context refilled to the limit within 3 turns of the previous compact, 3 times in a row. Try reading in smaller chunks, or use /clear to start fresh."
模型
| 命令 | 作用 |
|---|---|
/model |
切换模型 |
当模型过载时:"Opus is experiencing high load, please use /model to switch to Sonnet"
帮助/诊断
| 命令 | 作用 |
|---|---|
/help |
列出所有可用命令 |
/doctor |
系统诊断 + 自动修复 |
项目
| 命令 | 作用 |
|---|---|
/init |
创建项目的 CLAUDE.md 文件 |
/terminal-setup |
终端配置 |
代码审查
| 命令 | 作用 |
|---|---|
/review |
本地代码审查(当前 diff) |
/code-review |
PR 审查(插件提供) |
工作流
| 命令 | 作用 |
|---|---|
/loop |
定时循环执行命令 |
导入导出
| 命令 | 作用 |
|---|---|
/import-to-claude-code |
从其他 AI 编码工具导入配置 |
/memories/export |
导出记忆 |
记忆
| 命令 | 作用 |
|---|---|
/memory |
手动编辑记忆文件(详见 Ch7) |
8.3 自定义命令格式
一个自定义命令文件 = YAML 前置元数据 + Markdown 正文。
完整示例
来自 claude-code 官方仓库 plugins/commit-commands/commands/commit.md:
markdown
---
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*)
description: Create a git commit
---
## Context
- Current git status: !`git status`
- Current git diff (staged and unstaged changes): !`git diff HEAD`
- Current branch: !`git branch --show-current`
- Recent commits: !`git log --oneline -10`
## Your task
Based on the above changes, create a single git commit.
You have the capability to call multiple tools in a single response.
Stage and create the commit using a single message.
Do not use any other tools or do anything else.
Do not send any other text or messages besides these tool calls.
拆解:
yaml
┌───────────────────────────────────────────┐
│ 自定义 Slash Command 结构 │
│ │
│ --- (YAML frontmatter) │
│ description: 一行描述,/help 里显示的 │
│ allowed-tools: 工具白名单(可选但推荐) │
│ argument-hint: 参数提示(可选) │
│ --- │
│ │
│ (Markdown body) │
│ agent 收到的完整 prompt │
│ │
│ 特殊语法: │
│ $ARGUMENTS 用户传的参数 │
│ !`shell cmd` 内联 shell,提前执行 │
└───────────────────────────────────────────┘
frontmatter 字段
| 字段 | 必填 | 作用 |
|---|---|---|
description |
是 | /help 列出命令时显示的说明文字 |
allowed-tools |
否 | 权限白名单------命令只能调用这些工具 |
argument-hint |
否 | 参数提示,如 argument-hint: <PR number> |
allowed-tools 详解
支持三种模式匹配:
scss
# Bash 工具 + 子命令 glob
Bash(git add:*), Bash(git status:*), Bash(git commit:*)
# MCP 工具
mcp__github_inline_comment__create_inline_comment
# Bash 脚本
Bash(./scripts/gh.sh:*)
* 是 glob 通配符。Bash(git add:*) 允许 git add .、git add --patch 等所有 git add 变体,但不允许 git push。
注意与 settings.json 权限规则的语法差异 :
allowed-toolsfrontmatter 用冒号分隔工具和子命令(Bash(git add:*)),而 settings.json 的permissions.allow用空格(Bash(git *))------两者是不同的匹配系统,前者约束单个命令的可用工具,后者是全局权限白名单。
$ARGUMENTS 占位符
你把 /foo hello world 敲下去:
$ARGUMENTS→"hello world"(完整字符串)$ARGUMENTS[0]→"hello"(按位置取)$ARGUMENTS[1]→"world"
内联 shell:`!`` 语法
格式:``!`command```
执行时机:在 agent 看到 prompt 之前。 runtime 先执行 shell 命令、拿到 stdout 输出、替换掉 ``!`...``` 块,然后把替换后的文本喂给 agent。
lua
你写的:
- Current git status: !`git status`
runtime 替换后 agent 读到的:
- Current git status: On branch main, nothing to commit, working tree clean
agent 根本不知道这个内容来自 shell 命令。
安全注意
allowed-tools 管的是 agent 的工具调用,不管 ! 内联 shell。 ! 中的命令在 agent 看到 prompt 之前 就已经由 runtime 直接执行完了,不经过 agent 的工具协议。因此 ! 是比 allowed-tools 更底层的特权操作。
8.4 命令来源与优先级
四个来源
bash
优先级从低到高:
① 内置 (Built-in)
│ 编译进二进制,永远存在
│ 如 /clear, /model, /help, /init
│
② User 自定义 (~/.claude/commands/)
│ 本机所有项目共用
│
③ Project 自定义 (./.claude/commands/)
│ 项目级,可提交 git,团队共享
│
④ Plugin 提供 (plugin/commands/)
插件安装时注册,安装即生效
同名覆盖规则
getCommandsByMaxPriority 函数保证:同名命令只保留优先级最高的版本。低优先级的被静默跳过:
bash
Skipping plugin command <name> ← 二进制中确认的日志
举例:如果项目 .claude/commands/commit.md 定义了 /commit,而插件 commit-commands 也提供了一个 /commit,项目级的胜出,插件版被跳过。
当前本机状态
bash
~/.claude/commands/ ← ✅ 有一份演示命令 (git-log.md)
./.claude/commands/ ← ❌ 无
plugins/ ← ❌ 未安装
发现机制
命令文件放在上述约定路径下即自动发现。不需要任何注册配置。路径即契约。
/help 列出的是 isAdvertisedSlashCommand 为 true 的命令------内置命令和自定义命令都会在上面显示。
8.5 安全模型
三层控制
csharp
┌─────────────────────────────────────────┐
│ ① allowed-tools frontmatter │
│ ├─ 限 agent 能调什么工具 │
│ └─ 精确到子命令级: Bash(git add:*) │
│ │
│ ② 禁用内联 shell (!) │
│ ├─ "Disable inline shell execution │
│ │ in skills and custom slash │
│ │ commands from user, project, or │
│ │ plugin sources." │
│ └─ 命令 prompt 保留,! 替换为占位符 │
│ │
│ ③ disableSlashCommands (全局封锁) │
│ ├─ 禁用所有自定义命令 │
│ └─ prompt 替换为占位符 │
│ │
│ ④ 沙箱 (sandbox) │
│ └─ "By default, your command will be │
│ run in a sandbox. This sandbox │
│ controls which directories and │
│ network hosts commands may access." │
└─────────────────────────────────────────┘
核心认知
allowed-tools是 agent 层的安全------agent 调工具时要检查!内联 shell 是 runtime 层的------特权更高,agent 不可见- 禁用设置是全局开关------一击关闭所有自定义命令
8.6 命令生命周期
bash
① 文件放在约定路径
~/.claude/commands/*.md
./.claude/commands/*.md
plugin/commands/*.md
│
▼
② 启动时 runtime 扫描所有路径
│
▼
③ 按优先级去重(同名取最高)
getCommandsByMaxPriority
│
▼
④ 用户敲 /command_name [args]
│
▼
⑤ runtime 执行内联 shell (!`...`)
→ 替换 $ARGUMENTS
→ 得到最终 prompt
│
▼
⑥ prompt 注入 agent
│
▼
⑦ agent 按指令执行
受 allowed-tools 约束
8.7 与 Skills 的关系
skill 和 slash command 共享一些基础设施(二进制中有 "Skill/command model" 字符串),但层次不同:
| Slash Command | Skill | |
|---|---|---|
| 定位 | 命名的 prompt 模板 | 按需加载的专项能力包 |
| 触发 | 用户手动 /command |
系统按需自动加载 |
| 范围 | 一段指令 | 可含工具、知识、工作流 |
| 复杂度 | 一个 Markdown 文件 | 一个目录(SKILL.md + 附件) |
| 章节 | 本章 | Ch10 |
简单类比:slash command 是快捷键,skill 是插件。
8.8 关键认知
-
slash command 是 prompt 模板,不是程序。 它只负责把一段预设文本注入给 agent,agent 自己决定怎么做。
-
路径即契约。
.claude/commands/*.md放进去就生效,不需要"注册"。 -
优先级 = 控制力。 项目覆盖用户,插件覆盖项目。团队可以统一标准,个人可以选择覆盖。
-
!和allowed-tools是不同层的安全。 前者是 runtime 层(在 agent 之前执行),后者是 agent 层(agent 调工具时检查)。理解这个区别才能正确设计命令的安全边界。 -
小命令大作用。 一个 10 行的 commit.md 能省掉每次手打
git add+git commit的重复劳动------slash command 的价值不在复杂,在消除重复。