Claude Code 有两种可复用的斜杠调用工作流机制:commands 和 skills。用户视角看起来差不多——都用 /名称 调用。区别在于你能配置什么。
Commands 是纯 markdown 文件。把 review.md 放到 .claude/commands/,/review 就可用了。没有 frontmatter,没有配置。文件内容变成 prompt。
Skills 是 .claude/skills/ 下命名目录中的 SKILL.md 文件。它们支持 YAML frontmatter,有三个 commands 没有的能力:context: fork(隔离执行)、allowed-tools(工具限制)、argument-hint(参数提示)。
如果你需要这三个中的任何一个,你需要 skill。如果不需要,command 更简单也够用。
决策标准
| 需求 | 机制 |
|---|---|
| 简单 prompt,无特殊配置 | Command |
| 隔离执行(大量输出) | Skill,context: fork |
| 工具限制(阻止破坏性操作) | Skill,allowed-tools |
| 提示必填参数 | Skill,argument-hint |
| 快速、低输出操作 | Command(fork 有额外延迟) |
三个真实工作流说明区别:
- /lint — 跑 linter,报告结果。简单、快速。→ Command。
- /deep-review — 大规模代码库分析,产出 20,000+ token。需要隔离以免输出塞满主会话。→ Skill,
context: fork。 - /migrate-db — 生成数据库迁移 SQL 文件。不能执行它们。→ Skill,
allowed-tools: Read, Write, Edit(没有 Bash)。
全做 commands 意味着 /deep-review 污染你的会话、/migrate-db 可能执行 DROP TABLE。全做 skills 意味着 /lint 为一个 2 秒操作承担 fork 开销。
为什么 allowed-tools 比指令重要
一个迁移 skill 的 SKILL.md 说:“只生成迁移文件,不要执行任何命令。“测试时,skill 执行了一个 Bash 命令删了一张测试数据库表。
这不是 bug。没有 frontmatter 中的 allowed-tools,skill 继承了包括 Bash 在内的所有工具。“不要执行”这条指令是概率性的——模型认为执行会有帮助就覆盖了指令。
allowed-tools: Read, Write, Edit 是确定性的。Bash 在物理上不可用。模型无法执行任何东西因为工具在它的环境中不存在。更强的措辞(“绝对永远不要执行”)也改变不了这点——它仍然是和模型判断竞争的概率性指令。
核心设计原则:frontmatter 给保证,指令给引导。
范围:项目 vs 用户
和 CLAUDE.md 一样的模式:
| 位置 | 范围 | 通过 git 共享? |
|---|---|---|
.claude/commands/ | 项目 | 是 |
.claude/skills/ | 项目 | 是 |
~/.claude/commands/ | 用户 | 否 |
~/.claude/skills/ | 用户 | 否 |
团队关键工作流属于项目范围。把 /deploy-check 放在 ~/.claude/commands/ 的开发者在自己机器上用着挺好——新团队成员不会有。
个人实验性工作流属于用户范围。想要团队 /review skill 的安全聚焦变体的开发者,创建 ~/.claude/skills/security-review/SKILL.md 用不同的名字。个人变体和团队 skill 共存,不修改团队的。
不要过度 fork
context: fork 在子代理上下文中运行 skill。主会话只得到一个摘要。这对大量输出的操作是理想的(代码库扫描、头脑风暴、安全审计),30,000+ token 的输出会污染对话。
不适合:
- 快速操作 — 2 秒的
/lint或/format不需要 fork 开销。额外延迟和工作量不成比例。 - 直接编辑 — 带
context: fork的/quick-fixskill 在子代理中应用修复。主会话看不到文件变化,开发者得手动验证发生了什么。用户需要看到的编辑属于主上下文。
规则:输出大且主会话只需要摘要时 fork。操作快或用户需要看到确切变化时留在主上下文。
CI 集成
Skills 和 CLI 标志组合用于非交互式 CI 流水线:
claude -p '/ci-review' --output-format json --json-schema '{...}'
Skill 提供可复用配置(工具限制、隔离)。CLI 标志提供 CI 特定行为(非交互模式、结构化输出格式)。把所有东西放在 -p prompt 里的话就失去了可复用性——审查逻辑需要在每个 CI 脚本中重复。
完整项目配置示例
一个项目需要:通用 TypeScript 标准、团队共享的 API 测试工作流、只读安全扫描、以及个人开发者工作流。
| 需求 | 机制 | 位置 |
|---|---|---|
| TypeScript 标准(始终加载) | CLAUDE.md | .claude/CLAUDE.md |
| API 测试工作流(需要 Bash) | Command | .claude/commands/api-test.md |
| 安全扫描(只读 + 隔离) | Skill | .claude/skills/security-scan/SKILL.md |
| 个人实验 | Skill 或 Command | ~/.claude/skills/ 或 ~/.claude/commands/ |
每种机制服务其预期目的。标准始终加载。简单工作流用 commands。配置化工作流用 skills。个人的用用户范围。
一句话总结: Commands 是即发即忘的 prompt;skills 是配置化工作流——需要隔离、工具限制或参数提示时用 skills,不需要时用 commands。