ᕕ( ᐛ )ᕗ Jimyag's Blog

Claude Code 自定义 slash commands 和 skills 的比较

· 509 字 · 约 3 分钟

在 Claude Code 里,除了内置的 /help/compact 等命令,你可以用两种方式扩展能力:自定义 slash commands(传统方式)和 skills(当前推荐方式)。两者都能让你输入 /xxx 触发一段预设指令;区别在于结构、触发方式和可配置项。官方文档里,自定义 slash commands 已被并入 skills,旧方式继续兼容,但新能力都在 skills 上。

本文基于 Claude Code 官方文档Platform Agent Skills 文档 做对比说明。


官方对两者关系的说明

Claude Code 文档 明确写:

Custom slash commands have been merged into skills. A file at .claude/commands/review.md and a skill at .claude/skills/review/SKILL.md both create /review and work the same way. Your existing .claude/commands/ files keep working. Skills add optional features: a directory for supporting files, frontmatter to control whether you or Claude invokes them, and the ability for Claude to load them automatically when relevant.

也就是说:

  • .claude/commands/review.md.claude/skills/review/SKILL.md 都会暴露为 /review,触发后行为一致。
  • 已有 .claude/commands/ 下的文件无需迁移,会继续工作。
  • skills 在「同样能当斜线命令用」之外,多了:目录 + 附属文件、frontmatter 控制「谁调用」、以及 Claude 按描述自动选用。
  • 若同一名字同时存在 command 和 skill,skill 优先。

下面分别介绍两种方式的结构和用法,再给一个对比表和小结。


一、自定义 slash commands(传统方式)

是什么

把一个 markdown 文件放在指定目录下,文件名(去掉 .md)即斜线命令名。例如 .claude/commands/review.md 会得到 /review

存放位置

  • 项目级:.claude/commands/<name>.md,随项目提交,团队共享。
  • 个人级:~/.claude/commands/<name>.md,仅本机、所有项目可用。

子目录会变成命名空间,例如 commands/frontend/component.md 可能对应 /project:frontend:component(具体以文档为准)。

文件里写什么

纯 markdown:写你希望 Claude 在触发该命令时遵循的步骤、规范或提示。和普通说明文档一样,没有强制格式。

支持的占位符(与 skills 一致)

传统 commands 也支持与 skills 相同的 字符串替换

  • $ARGUMENTS:用户输入 /name 后面跟的那一整段文字。
  • $ARGUMENTS[N]$N:第 N 个参数(从 0 开始)。
  • ${CLAUDE_SESSION_ID}:当前会话 ID,便于做日志或隔离。

例如 /fix-issue 123 时,内容里的 $ARGUMENTS 会被替换成 123

如何触发

只能由用户主动输入 /name(或 /name 参数)。Claude 不会根据对话内容自动选这个「命令」来用;它就是一个你手动点的快捷指令。

小结(传统方式)

  • 一个文件搞定,学习成本低。
  • 只能手动触发,没有「按描述自动发现」。
  • 没有目录、附属文件,也没有「只让用户调 / 只让 Claude 调」的细粒度控制。

二、Skills(当前推荐方式)

是什么

Platform 文档 把 Agent Skills 定义为:把指令、元数据和可选资源(脚本、模板等)打包在一起的模块化能力,Claude 在认为与当前请求相关时会自动选用,你也可以继续用 /skill-name 手动触发。在 Claude Code 里,skills 以目录 + 入口文件的形式存在,并遵循 Agent Skills 开放规范,同时 Claude Code 在此基础上增加了调用控制、subagent、动态上下文等扩展。

存放位置

  • 企业级:由 managed settings 配置,全组织生效。
  • 个人级:~/.claude/skills/<skill-name>/SKILL.md,本机所有项目可用。
  • 项目级:.claude/skills/<skill-name>/SKILL.md,仅当前项目。
  • 插件:插件的 skills/<skill-name>/SKILL.md,在启用该插件的环境里可用,命名空间为 plugin-name:skill-name

同名时优先级:企业 > 个人 > 项目;若同一名字既有 .claude/commands/xxx.md 又有 .claude/skills/xxx/SKILL.md,以 skill 为准。

目录结构

每个 skill 是一个目录,入口固定为 SKILL.md,其余文件可选:

1
2
3
4
5
6
my-skill/
├── SKILL.md          # 必选,主说明与入口
├── reference.md      # 可选,详细参考(按需被读入)
├── examples.md       # 可选,示例
└── scripts/
    └── helper.py     # 可选,可被执行的脚本(执行结果进 context,脚本本体不占 context)

文档建议 SKILL.md 正文控制在 500 行以内,把大块参考放到单独文件,并在 SKILL.md 里用链接指向,这样 Claude 只在需要时加载,节省 context(即 progressive disclosure)。

SKILL.md 的组成

  1. YAML frontmatter(在首行 --- 之间):元数据和配置。
  2. Markdown 正文:给 Claude 的步骤、规范、示例等,和传统 command 的写法类似。

必填/推荐字段(来自 frontmatter 说明):

  • name:可选,斜线命令名(小写、数字、连字符,最多 64 字符);不写则用目录名。
  • description:推荐。一句话说明「做什么、什么时候用」。Claude 用它在对话中判断是否自动加载该 skill;写得好,自动触发才准。

其他常用字段(skills 独有或更细):

  • disable-model-invocation:设为 true 时,只有用户能通过 /name 触发,Claude 不会自动选用。适合部署、发消息等有副作用的操作。
  • user-invocable:设为 false 时,不在 / 菜单里展示,只有 Claude 能根据描述选用。适合「背景知识」类 skill。
  • allowed-tools:该 skill 激活时,Claude 可用哪些工具(如 Read, Grep),无需每次再问你。
  • context:设为 fork 时,该 skill 在独立 subagent 里执行,不共享主对话历史。
  • agent:当 context: fork 时,指定用哪种 agent 类型(如 Explore、Plan)。
  • argument-hint:在自动补全里显示的参数提示,如 [issue-number]

占位符和传统 commands 一致:$ARGUMENTS$N${CLAUDE_SESSION_ID} 等;skills 还支持用 `!command` 在送入 Claude 前先执行 shell 命令,把输出注入到内容里(动态上下文注入)。

如何触发

  • 用户:输入 /skill-name/skill-name 参数,和传统 slash command 一样。
  • Claude:根据当前对话和每个 skill 的 description,在认为相关时自动加载对应 SKILL.md(及按需加载其中引用的其他文件)。
    若设置了 disable-model-invocation: true,则 Claude 不会自动选用,仅支持手动 /name

加载方式与 context 占用

Skill 最佳实践Overview 里说明:

  • 启动时:只把各 skill 的 name + description 放进系统提示,占用很少(约每 skill 百来个 token)。
  • 被触发时:才通过 bash 读取对应 SKILL.md 内容进 context。
  • 附属文件:仅在 SKILL.md 里引用到、且 Claude 决定需要时才读入;脚本是执行,执行结果进 context,脚本代码本身可以不进。

这样可以在安装很多 skills 的前提下,尽量少占 context,只加载「当前相关」的那一部分。

小结(skills)

  • 既能像传统 command 一样手动 /name,也能被 Claude 按描述自动选用。
  • 支持目录 + 多文件、渐进式加载,适合复杂流程和大量参考文档。
  • 通过 frontmatter 可细粒度控制「谁调用、在什么环境跑、能用哪些工具」。

三、总体对比表

维度 自定义 slash commands(传统) skills
存放位置 .claude/commands/<name>.md .claude/skills/<name>/SKILL.md
结构 单个 markdown 文件 目录 + SKILL.md + 可选 reference/scripts 等
触发方式 仅用户输入 /name 用户可 /name,Claude 也可按 description 自动选用
调用控制 无(等价于「只能用户调」) disable-model-invocationuser-invocable
附属资源 多文件、按需加载,脚本可执行而不占 context
高级能力 subagent(context: fork)、工具限制、动态注入 `!command`
占位符 $ARGUMENTS$N${CLAUDE_SESSION_ID} 同上,另可 `!command` 预执行并注入输出
学习成本 需理解 name/description 与 frontmatter,相对高
官方态度 兼容保留 推荐,因支持附属文件和更细配置

四、该怎么选

  • 只想要一个固定流程、永远自己手动点:用传统 .claude/commands/xxx.md 即可,一个文件、改起来简单。
  • 希望 Claude 在对话里自动用上这段能力:必须用 skill,并写好 description(说明「做什么、在什么情境下用」),这样 Claude 才会在合适的时候自动加载。
  • 需要多文件、模板、脚本或大段参考:用 skill 的目录结构 + 渐进式加载,避免单文件过长、context 浪费。
  • 有部署、发消息等敏感操作,不想让 Claude 自动执行:用 skill 并设 disable-model-invocation: true,只保留手动 /name
  • 想统一体验、后续可能加自动触发或 subagent:直接建 skill,和传统 command 同名的 skill 会覆盖 command。

参考链接:

#Claude Code #Slash Commands #Skills