☰
Claude Code Slash Commands:从提问者到指令设计师的AI编程进阶
2026/10/17 11:12:19 网站建设 项目流程

从去年开始用 Claude Code 做日常开发,我逐渐发现一个现象:同一批人用同一个模型,产出效率却能差出好几倍。差距不在谁的英文指令写得好,而在有没有把“一次性提问”变成“可复用的指令”。这篇文章想聊的,就是 Claude Code 的 Slash Commands——从在输入框里敲一句话等回复的“提问者”,变成用自定义命令批量解决重复问题的“指令设计师”。如果你已经用了一段时间 Claude Code,却还停留在手动描述每一轮任务的阶段,这篇文章应该能帮你换个思路。

我不会只列命令清单。重点讲清楚三件事:Slash Commands 的底层机制是什么,设计一个高质量自定义命令要遵循哪些原则,以及我在真实项目中踩过的坑和验证方法。文章里所有命令都是可以复制后改改就能用的,尽量让不同基础的读者都能跟上。

1. 从“帮我想”到“帮我做”:Slash Commands 到底改变了什么

1.1 提问式协作的上限在哪里

最早用 Claude Code,我的典型操作是:“帮我看下这段代码有什么问题”“帮我修一下登录页的 bug”“帮我写个单元测试”。听起来没什么问题,但用久了你会发现三个痛点。

第一,每次都在重新解释背景。代码审查要看 diff、技术债要扫描 TODO、提交信息要符合规范——这些任务的背景和规则每次都一样,但每次都要在对话里重新描述一遍。第二,输出不稳定。“审查代码”这个请求,模型可能这次输出 10 条建议,下次输出 3 条,再下次给出的是完全不同的格式。不是模型变笨了,而是输入里没有给它任何“输出契约”。第三,上下文被垃圾对话占满。为了让模型理解任务,你不断补充说明,模型又不断反问,真正相关的代码内容还没来得及读,上下文窗口倒先被来回的澄清对话挤占了。

这三个痛点的根源,是把太多“决策负担”交给了模型。你在聊天框里说“帮我审查”,模型就得自己决定:审查范围是什么?按什么标准审查?输出成什么样算合格?它一自由发挥,质量就飘忽不定。

1.2 指令的本质:把决策前置的工作流

Slash Command 说白了,就是把一段设计好的 Prompt 封装成一个斜杠开头的命令。你在输入框敲/review,AI 收到的并不是“review”这一个词,而是一整套包含角色设定、任务步骤、约束条件和输出格式的完整指令。

我习惯把它类比成菜谱。提问者做的事情是给厨师打电话:“帮我炒个菜”,然后全靠厨师临场发挥。而指令设计师做的事情,是把食材、火候、调味料的比例、出锅时间全部写进菜谱,厨师只要照着执行,出品就稳定。Slash Commands 就是那张菜谱。

有一点很关键:写命令的过程,本质上是在预判模型会在哪些环节犯错,然后提前把这些坑堵住。比如你知道模型默认爱啰嗦,就在命令里写“输出不超过 300 字”;你知道它容易忽略边界条件,就在命令里写“必须检查空指针和超时场景”。这一层思考,是提问者模式天然缺失的。

1.3 蜕变的三个阶段

以我自己的经验,“指令设计师”不是一步到位的,通常经过三个阶段。

阶段一:减少打字量。把常用的长 Prompt 存成命令,比如写一个/tomorrow命令,内容是“列出我昨天没做完的事,结合今天的 git 改动给计划”。这时候你还只是在省打字。

阶段二:开始设计约束。你会给命令加角色、加输出格式、加“不要做什么”。比如审查命令里明确写“忽略纯格式调整”,提交信息命令里写“如果改动同时包含多个类型,优先选择影响最大的类型”。这时候你已经在控制输出了。

阶段三:命令之间组合。配合 CLAUDE.md 全局规则、hook 钩子、子命令目录,把单个命令串成一条工作流。比如/review/security和/review/perf分别处理不同维度的审查,再配合/init在项目里建立上下文。到这个阶段,你才算真正完成了从提问者到设计者的转变。

2. 命令文件不是配置文件:拆解 Slash Command 的结构

2.1 存放位置与命名规则

Claude Code 的自定义命令,本质上就是一个 Markdown 文件,不需要任何额外注册。这是它和传统 IDE 宏命令最不一样的地方:命令即文件。

命令放在两类目录下:

  • 项目级:.claude/commands/,只对当前项目生效
  • 用户级:~/.claude/commands/,对当前用户的所有项目生效

文件名就是命令名。比如我在.claude/commands/review.md里写命令,触发方式就是/review。目录层级还支持命名空间,review/security.md会被识别成/review/security。等你积累了十几个命令,命名空间的价值就出来了——/review负责总览,/review/security专门做安全审查,结构清晰,不会挤在一起。

两个小建议。第一,命令名用动词开头,/commit比/commit-msg-generator好记,/audit比/todo-scan-v2好记。第二,不要用空格和特殊字符,文件名里的空格虽然在技术上能识别,但触发的时候容易出错,也别问我怎么知道的。

2.2 Frontmatter:命令的名片与权限边界

每个命令文件开头有一段 YAML Frontmatter,它不是摆设,而是控制命令行为的关键元信息。

--- description: 审查当前分支的代码改动,按严重程度输出问题清单 argument-hint: [base-branch] allowed-tools: Bash, Read, Grep ---
  • description是必须写的。你敲/help时,它出现在命令列表里;你用模糊匹配时,它也负责让 AI 判断该不该用这个命令。描述写得越具体,命令被正确调用的概率越高。
  • argument-hint是给使用者的提示。它告诉用户这个命令接收什么参数,避免让别人对着命令发呆:“我该传什么进去?”
  • allowed-tools是我强烈建议你关注的一个字段。它限制 AI 在执行这个命令时能调用哪些工具。比如审查类的命令,我会只允许Bash(跑 git diff)、Read(读文件)和Grep(搜索),不给Edit和Write。否则审查的过程中,模型可能“顺手”帮你改几行代码——它对自己的改动还特别自信。

2.3 正文结构:角色、步骤、输出契约

Frontmatter 下面是正文。我写下来最好的结构,是固定的四段式:角色定义 → 任务范围 → 执行步骤 → 输出格式。

--- description: 解释指定文件的核心逻辑 argument-hint: <file> --- 你是一名负责梳理代码架构的工程师。请阅读 @$1 ,先用 200 字以内解释它在整个项目中的职责,然后列出它的外部依赖:调用过哪些函数、读取了哪些配置、被谁调用。不要粘贴代码内容,直接说结论。

这个例子里有两个机制需要解释。

@$1里的$1是位置参数,表示用户输入的第一个参数。比如执行/explain src/utils/date.ts,$1就是src/utils/date.ts。前面的@是一个特殊前缀,作用是让 AI 去读取指定文件的内容。所以@$1连起来的意思就是:读取用户指定的文件,然后分析它。

对于多参数,$ARGUMENTS会把用户输入的整段内容一字不差地拼进命令。这个很好用,但也容易踩坑,后面第 5 部分专门说。

2.4 为什么命令要放在 Git 仓库里

既然命令就是 Markdown 文件,它天然可以被版本管理。我第一次把.claude/commands/目录纳入 Git 时,才发现这层价值:命令是可以被 review 的。团队成员可以看你的命令,指出哪里写得含糊,哪里约束不够。命令库会逐渐演进成团队的“AI 协作规范”。

有人会问:“那我直接在对话里把命令说得详细一点行不行?”行,但有两个区别。第一,对话里的指令是一次性的,下次还得重新说;命令是持久化的,一次写好多处受益。第二,对话里的指令会随着用户情绪和表达能力波动,命令文件是固定的,团队所有人生效的是同样一套标准。这也是“指令设计师”和“提问者”在企业协作中最本质的差别。

3. 实战:三个高频场景的命令库设计

3.1 /review:把代码审查变成稳定流水线

代码审查是我用得最频繁的场景。早期我直接在对话里说“审查下我改的代码”,结果 AI 给出的建议泛泛而谈,什么“注意错误处理”“优化性能”,既没有定位到行号,也没有严重程度分级,根本无法直接贴到 MR 评论里。

后来我设计了/review命令,核心思路是:先锁定审查范围,再定义审查标准,最后钉死输出格式。

--- description: 审查当前分支相对主分支的改动,输出分级问题清单 argument-hint: [base-branch] allowed-tools: Bash, Read, Grep --- 你是一名高级代码审查员。审查范围:当前分支相对于 ${1:-main} 的代码改动。 执行步骤: 1. 先用 git diff ${1:-main}...HEAD --stat 了解整体改动范围。 2. 读取改动文件的完整内容,重点检查以下维度: - 错误处理是否完整,特别是外部 IO、网络请求、资源释放 - 是否存在并发安全问题(共享状态、竞态条件) - 是否有明显性能隐患(循环内查询、重复计算、N+1 问题) - 命名是否符合项目惯例,是否存在误导性命名 - 是否有未使用的变量、死代码、调试残留 3. 忽略纯格式调整和注释修改,不要在这种改动上浪费输出。 输出格式(严格按此格式): ## 审查结论 - 严重问题:N 处 / 建议问题:N 处 / 提示信息:N 处 ## 问题清单 每条问题的格式为:[严重|建议|提示] 文件路径:行号 —— 问题描述 —— 修复建议 最后在末尾给出三选一结论:建议合入 / 修复后合入 / 不建议合入。

几个设计细节值得说。

${1:-main}是 Shell 参数默认值语法,表示“如果用户没传参数,就用 main 作为基准分支”。用户执行/review就能用,跑/review develop就能换基准分支。命令应该做到无参数可用,参数只是微调。

先跑git diff --stat而不是直接git diff。这样 AI 能先建立整体认知,知道这次改动涉及几个文件、每个文件改了多少行。等它读完整内容时,已经有了一份“地图”,不会一头扎进某个小文件里出不来。

allowed-tools 只给了 Bash、Read、Grep,不给编辑工具。审查就是审查,AI 不应该在审查过程中改代码。

3.2 /audit-todo:技术债巡检与防幻觉设计

第二个场景是技术债巡检。项目里的 TODO、FIXME、XXX 越堆越多,靠人来逐个找不现实,直接让 AI 扫描又容易出幺蛾子——它会在没看上下文的情况下,对标记的含义脑补出一套解释。

--- description: 扫描指定目录下的 TODO/FIXME/XXX/HACK 标记,按模块输出技术债清单 argument-hint: [path] --- 你是一名负责技术债治理的架构师。任务是审计代码中的待办标记。 执行步骤: 1. 用 Grep 搜索 ${1:-src} 目录下的 TODO、FIXME、XXX、HACK 标记,统计每个文件中的命中行。 2. 对每个命中位置,读取前后 5 行代码理解上下文,然后判断该标记属于哪一类: - 遗留型:本应完成但一直未处理的功能缺口 - 临时型:为了赶进度临时绕开,需要尽快还的技术债 - 优化型:属于性能或体验改进,不阻塞当前功能 3. 按目录聚合,计算每个模块的技术债密度(标记数/文件数)。 输出格式: - 按模块输出一个 Markdown 表格,列为:标记类型 / 文件 / 行号 / 一句话说明 / 建议处理时机 - 表格后给出“优先级最高 Top 5”清单,按影响面 X 紧急度排序。 - 如果某个标记上下文不够清晰,直接写“无法判断”,不要编造含义。

这个命令里最关键的其实是最后一行:“无法判断就写无法判断”。这是防幻觉设计。模型天生倾向于在信息不足时给出看似合理的解释。你如果不主动给它“诚实退出”的许可,它就会把每个 TODO 注释都解读得像模像样,然后这些解读还会被同事当成真实依据。一条“无法判断”的记录,比十条看似合理的瞎猜要可靠得多。

3.3 /commit:把团队规范变成肌肉记忆

提交信息生成命令,是让团队协作最直观受益的一个。之前每次写提交信息,总有成员记不住 Conventional Commits 规范,写出来的东西五花八门。我把规范直接写进了命令:

--- description: 根据暂存区改动生成符合 Conventional Commits 规范的提交信息 --- 你是提交信息助手。请先运行 git diff --staged 查看已暂存的改动。 要求: 1. 判断改动类型:feat / fix / refactor / docs / test / chore / perf。 2. 如果改动混合多个类型,选择影响最大的类型作为主类型,并在 body 里说明其他部分。 3. 摘要行不超过 50 个字符,使用祈使句,不要用 “update” 这类无信息量的动词开头。 4. 如果有破坏性变更,必须有 “BREAKING CHANGE:” 段落说明影响。 5. 生成 3 个候选:简短版(只用摘要行)、详细版(摘要+body)、通俗版(面向非技术读者)。 输出格式: ## 候选 1(推荐) feat(scope): 一句话摘要 body 内容 ## 候选 2 ... ## 候选 3 ...

把规范写进命令之后,我发现一个有意思的现象:团队里新成员甚至不用去查规范文档,跑一次/commit,AI 给出的候选版本本身就是最好的教学案例。比起给人发一份几十页的风格指南,一个命令反而更有效。

4. 设计好命令的四个“为什么”与两个“不要”

4.1 为什么要把输出格式钉死

这是命令设计里最重要的一个原则。自由格式下,模型输出的相似度很低,同一份 diff 跑两次/review,两次可能是完全不同的结构;而钉死输出格式后,两次结果的结构几乎一致,只有内容随代码变化。

格式就是契约。当输出格式固定时,你可以拿它当接口来用。比如审查结果固定是## 审查结论 + 问题清单 + 合入结论,你就可以写个脚本解析输出,或者在 MR 模板里直接引用。如果格式每次都不一样,这些下游工序全都无从谈起。

4.2 为什么要设置默认值而不是留空

我见过不少命令写法是这样的:“请分析用户传入的路径,如果没有传入请询问”。这个设计有问题:让 AI 追问参数,等于把决策又抛回给用户。你希望在命令行里敲/review直接就出结果,而不是被反问“请问基准分支是什么”。

所以我在设计时遵循一条规则:无参数可运行,参数只用于微调。用${1:-main}这类默认值语法兜底,配合argument-hint告诉使用者“可以传什么”。让命令在默认情况下就能工作,是对使用者最基本的尊重。

4.3 为什么限制工具列表

Claude Code 这类 Agent 的能力在于能主动调用工具,但这份主动性也是双刃剑。我给审查类命令禁掉 Edit 和 Write 工具后,发生过一个小插曲:某次审查时,AI 发现一个变量命名有问题,直接在代码里“顺手”改了它,还自我感觉良好地汇报“已修复”。如果我没限权,这种改法在没跑测试的情况下很可能引入问题。

默认情况下,审查、分析、生成类命令只给只读工具;确认要改代码的命令,才放开写工具。另外给命令一个明确的后果预期:审查命令的产出是建议,不是修改。这句话写进命令,模型通常会克制很多。

4.4 为什么要写“不要做什么”

模型默认是个多动症,爱啰嗦、爱补充、爱解释。所以否定约束往往比肯定约束更值钱。

我在命令里常用的“不要”长这样:不要解释代码的每一行;不要输出与任务无关的分析;不要用泛泛的“优化性能”代替具体建议;不要试图修改不属于任务范围的文件。每一条都是从真实的无效输出里总结出来的。

有读者可能担心:写太多“不要”会不会让命令变得负面?实测不会。肯定约束负责指定该做的事,否定约束负责阻止浪费 token 的行为,两者配合,输出质量反而明显提升。

4.5 两个“不要”之外,还有两层边界

第一,不要写“万能命令”。一个命令只解决一类问题。早期我图省事,写过一个/helpme,试图让它“处理项目的一切事务”,结果它对什么都了解一点,但对什么都不精。后来拆成了/review、/audit-todo、/commit等十几个专用命令,每个都能在它自己的领域里做深做透。命令设计跟模块划分是一个道理:单一职责。

第二,不要把 CLAUDE.md 里的全局规则重抄进命令。CLAUDE.md 负责存放跨任务的全局约定,比如“代码注释用中文”“错误处理必须明确返回错误信息”。命令只负责当前任务的特定步骤。如果两处重复,一旦规则更新,你就要在两处同步修改,而且当全局规则和命令内容冲突时,模型会陷入困惑。全局与局部,各管各的。

5. 翻车现场:参数解析、上下文膨胀与调试三步法

5.1 $ARGUMENTS 的引号灾难

我最开始写命令时,用过$ARGUMENTS直接拼接用户输入,遇到过这样的事:用户执行/review login --verbose,$ARGUMENTS这一整段被拼进命令里,模型误以为login --verbose是文件路径,直接报错。

后来我改成了位置参数:$1拿路径,$2拿选项。再配合argument-hint做说明,问题才解决。这里给你两个实用技巧:

  • 能用$1、$2就别用$ARGUMENTS。位置参数更容易被 AI 正确理解。
  • 如果必须用$ARGUMENTS,在命令里明确写一句“参数可能是多个单词,先解析参数列表,再判断含义,不要把它们当成单个路径”。

5.2 上下文膨胀:命令越长效果反而越差

我一度追求命令事无巨细,写过一份 1500 字的超级命令,覆盖二十多种边界情况。结果工作没变轻松,效果反而变差了。

原因在于:命令全文会一次性被读进上下文窗口,你的命令越长,留给真实代码的空间就越少。AI 需要同时记住“命令说了什么”和“代码里是什么”,两边抢注意力。

我做过一个对照实验:同一个审查任务,用 1500 字命令跑一次,再用压缩到 400 字的命令跑一次。后者的输出,在关键问题覆盖度上反而更高,因为模型有更多上下文去理解代码本身。现在我的经验是,命令正文控制在 400 到 600 字以内,核心约束放开头和结尾各强调一次。把“角色”压到一句话,“步骤”压缩到三个以内,剩下的空间留给输出模板。

5.3 与 CLAUDE.md 的指令打架

有次我项目里的 CLAUDE.md 规定了“所有注释和文档使用中文”,而一个输出英文报告的命令恰好被触发,结果 AI 在中间反复横跳,一会儿中文一会儿英文。

问题出在设计冲突,而不是模型智商。我的解决方式有两种:要么在命令开头明确写“本命令的输出语言不受全局规则约束,严格使用英文”,要么干脆让命令跟 CLAUDE.md 保持完全一致的风格。优先级这件事,与其让 AI 自己判断,不如由你提前写清楚。我在模板里加了一句固定话术:“如果本命令要求与全局规则冲突,以本命令为准,除非冲突内容涉及代码安全。”

5.4 调试三步法:定位命令失效的通用流程

命令写得再好,也要过调试这关。我摸索出一套三步走的调试流程。

第一步,跑最简参数。先执行/review不带任何参数,如果基本流程通了,再逐步加参数复测。这一步能快速区分“命令逻辑问题”和“参数解析问题”。

第二步,查看上下文占用。用/status看看当前会话的上下文构成,如果模型行为飘忽,多半是上下文被占满,那就先/compact压缩,再试一次。

第三步,拆解三段分别验证。把命令拆成“角色/步骤/输出格式”三部分,单独用对话去测每一段。比如先只发“你是一名高级代码审查员”,看它如何理解角色,再逐步叠加步骤和格式。哪一段失效,就单独修正哪一段,不需要重写整个命令。

这套流程走完,我的命令基本能做到对同一份输入的两次运行结果结构一致、内容差异可控。这其实是“稳定可复现”的底线。

5.5 最后补一个高频意外:命令目录的大小写与缓存

还有一个看起来不值一提、实际坑过我的细节:命令行工具对文件名的解析通常是大小写敏感的。review.md触发的/review,但你存成了Review.md,触发的时候就可能找不到命令。我后来统一用全小写文件名,并在description里把关键词写全,这样即使偶尔拼错命令名,模糊匹配也能兜底命中正确的命令。


按我自己的体会,能把命令设计好的人,通常也是最能把复杂任务拆清楚的人。命令库就是你思考方式的实体化——你的约束、你的优先级、你对“什么算好结果”的定义,全都写在里面。不要追求一次写完美,把它放进 Git,用的时候觉得哪里不对就改一版。我的命令库三个月改了四版,每一次改动,都对应着我对一类任务更深一层的理解。希望这篇文章能帮你也开启这个迭代过程。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询