Slash Commands:把反复重打的提示词,固化成团队命令

Slash Commands:把反复重打的提示词,固化成团队命令
TL;DRSlash Commands 是.claude/commands/里的 Markdown 文件按需加载用$ARGUMENTS参数化。它解决的是第三次重复写同一段提示词的问题——把高频、短流程的任务固化成版本化文件消除提示词漂移统一团队输出标准。问题同一个团队里每个人都手写帮我 review 一下代码。A 写的 prompt 关注安全B 关注性能C 啥都关注但写了两千字。结果同一种任务Claude Code 每次拿到的上下文和判断标准都不一样。这不是风格问题是工程问题。没有标准化的任务定义就没有可度量的输出质量。更糟糕的是当有人离职或者换项目时他写的那段好用的提示词也跟着消失了——知识没有被沉淀只是暂时停留在某个人的终端历史里。Slash Command 的本质把散落在每个人脑子里的任务模板变成仓库里的版本化文件。它和 CLAUDE.md 的区别是加载时机——CLAUDE.md 每次会话全量加载Command 只在调用时加载。这意味着 Command 里写再长的提示词也不会拖慢日常会话。这带来一个关键推论命令的长度不会惩罚不使用它的人。一个 80 行的/review命令只有调/review的那个会话才承担这 80 行的 Token 成本。其余 99% 的会话完全不受影响。这个属性让命令成为安全的长提示词容器——审查标准写多详细都行不会像 CLAUDE.md 那样挤占全局上下文。命令系统架构文件结构.claude/commands/ ├── review.md → /review ├── fix-test.md → /fix-test ├── release-notes.md → /release-notes └── commit.md → /commit命令就是 Markdown 文件。文件名即命令名去掉.md后缀就是调用方式。例如fix-test.md对应/fix-test。命令文件支持子目录组织.claude/commands/db/migrate.md对应/db:migrate。子目录用冒号分隔这为大型项目提供了命名空间。Frontmatter文件顶部可以用 YAML frontmatter 声明元数据---name:reviewdescription:Review current diff for correctness, security, and test coverage.---name字段覆盖文件名作为命令标识。description在命令列表中展示帮助团队成员发现和选择命令。如果省略 frontmatter文件名就是命令名第一行会被当作描述。一个常见的错误是在description里写技术实现细节。description的读者是团队里不太熟悉命令的人——它应该回答这个命令干什么而不是这个命令怎么实现。好的描述“Review current diff for correctness, security, and test coverage.”。坏的描述“Runs git diff and applies a structured review template with severity classification.”。前者是用途后者是机制。$ARGUMENTS 占位符$ARGUMENTS是命令体内的动态参数。用户输入/review src/auth/时src/auth/会替换命令体里所有$ARGUMENTS出现的位置。Review thediffin$ARGUMENTS.如果用户不传参数$ARGUMENTS被替换为空字符串。命令设计需要处理这个场景——要么在提示词里给默认值要么明确要求用户提供参数。这是命令设计中最容易被忽略的细节也是导致命令有时候不好用的头号原因。举例/review src/auth/展开后变成 “Review the current git diff src/auth/”——审查范围限定在 auth 目录。/review不带参数展开后变成 “Review the current git diff”——审查整个 diff。两种情况都能工作因为提示词里的$ARGUMENTS位置设计成了可选后缀。加载机制CLAUDE.md每次会话启动 → 全量注入上下文 → 持续消耗 Token Rules匹配路径时 → 按需注入 → 匹配即消耗 Command用户调用时 → 一次性注入 → 仅该轮消耗 Skill触发任务时 → 按步骤注入 → 任务期间消耗Command 的 Token 成本是用多少付多少。不调用就是零成本。这个特性决定了它的适用范围——适合高频但不连续的任务。对比一下加载行为的差异假设你的团队有 5 个命令每个平均 400 tokens。一天 10 次会话其中 3 次调用了命令。用 Command 方案命令相关的 Token 消耗是 3 x 400 1200 tokens。如果把这些内容全塞进 CLAUDE.md2000 tokens10 次会话的总消耗是 10 x 2000 20000 tokens。前者是后者的 6%。这就是按需加载的经济意义。四个真实命令/review代码审查--- name: review description: Review current diff for correctness, security, and missing tests. --- Review the current git diff$ARGUMENTS. Produce a structured review with three sections: ## Findings For each finding, provide: - **Location**: file:line - **Severity**: CRITICAL / HIGH / MEDIUM / LOW - **Category**: bug | security | performance | maintainability | style - **Description**: What is wrong and why it matters - **Suggestion**: Concrete fix (code snippet preferred) ## Summary - Total findings by severity - Overall risk assessment for this change ## Verification Gaps - Which behavior changes lack test coverage? - Which edge cases are untested? Rules: 1. Report findings first, summary last. Do not open with praise. 2. Prioritize correctness and security over style. 3. Cross-reference project rules in CLAUDE.md. 4. If the diff is empty, check staged changes: git diff --cached.关键设计点要求findings first, summary last——防止模型用一段总结稀释关键发现。Severity 用固定枚举值CRITICAL / HIGH / MEDIUM / LOW让下游工具CI 流水线、Slack 通知可以解析。Category 也用固定值方便后续按类别统计审查发现的分布。一个容易忽略的细节是第四条规则“If the diff is empty, check staged changes”。用户经常在git add之后调/review此时git diff输出为空。没有这条规则模型会报告没有变更可审查。有了这条规则它会自动检查git diff --cached。这是从真实使用中反馈回来的改进——第三次遇到空 diff 之后就把它加进了命令。/fix-test测试修复流程--- name: fix-test description: Diagnose and fix failing tests with structured diagnostic steps. --- Fix the failing test(s): $ARGUMENTS Follow this diagnostic workflow: ## Step 1: Reproduce - Run the failing test command exactly as the project defines it. - Capture the full error output. ## Step 2: Diagnose - Read the test file and the source file under test. - Identify the root cause. Classify it: - **Assertion mismatch**: Test expectation is wrong. - **Implementation bug**: Source code has a defect. - **Environment issue**: Missing fixture, wrong config, race condition. - **API change**: Interface changed but test was not updated. ## Step 3: Fix - If assertion mismatch: Update the test. Explain why the old assertion was wrong. - If implementation bug: Fix the source. Show the minimal diff. - If environment issue: Fix the setup. Do not modify test logic to work around it. - If API change: Update the test to match new interface. Flag if this is a breaking change. ## Step 4: Verify - Re-run the failing test in isolation. - Run the full test suite for the affected module. - Report: test name, root cause classification, files changed, verification result. Rules: - Do not skip or comment out failing tests. - Do not add .skip() or xit without explicit justification. - If the fix is unclear, stop and report the diagnosis. Do not guess.关键设计点诊断分类Assertion mismatch / Implementation bug / Environment issue / API change让修复路径明确防止模型用可能是缓存问题这种模糊解释跳过诊断。每个分类对应不同的修复策略——实现 bug 修源码断言不匹配修测试环境问题修配置。这比帮我修一下这个失败的测试的通用 prompt 效果好得多因为模型不需要猜测修复方向。Do not skip or comment out failing tests这条规则看起来多余但实际上是必须的。模型在没有明确指导时倾向选择阻力最小的路径——跳过失败测试确实能让测试套件通过但那不是修复。/release-notes变更日志生成--- name: release-notes description: Generate release notes from commit history between two refs. --- Generate release notes for the range: $ARGUMENTS If no range is provided, use the range from the last tag to HEAD: git log $(git describe --tags --abbrev0)..HEAD --oneline Steps: 1. Collect all commits in the range. 2. Classify each commit by type: - **feat**: New features - **fix**: Bug fixes - **breaking**: Breaking changes (contains BREAKING CHANGE or ! after type) - **refactor**: Internal changes with no user-facing impact - **docs**: Documentation only - **chore**: Build, CI, tooling changes 3. Group by type. Within each group, order by impact (user-facing first). 4. For each feat/fix/breaking entry, write one sentence describing the change from the users perspective. Do not copy-paste commit messages. Output format: ## Whats Changed ### Breaking Changes - **scope**: description (commit abc1234) ### New Features - **scope**: description (commit abc1234) ### Bug Fixes - **scope**: description (commit abc1234) ### Internal - refactor and chore entries, summarized in one paragraph ## Contributors List unique commit authors. Rules: - Do not invent changes not present in the commit log. - Do not evaluate or praise the changes. State facts only. - If a commit message is unclear, use git show to read the diff before summarizing.关键设计点要求从用户视角重写而不是复制粘贴 commit message。这个要求在提示词里明确写出来是因为模型默认行为就是复制粘贴 commit message。Do not evaluate or praise the changes也是针对真实问题的——模型在没有这条规则时会生成this exciting new feature或this important bug fix之类的营销语言。嵌套的代码块输出格式模板是另一个设计细节。命令体内同时有 Markdown 代码块作为输出模板需要用不同层级的反引号区分。如果出现渲染问题可以用缩进替代三反引号来标记输出模板。/commit规范化提交--- name: commit description: Generate a conventional commit message from current changes. --- Generate a commit message for the current staged changes. Steps: 1. Run git diff --cached to see what will be committed. 2. If nothing is staged, run git diff to show unstaged changes and ask whether to stage them. 3. Analyze the changes: - What files were modified/added/deleted? - What is the primary purpose of this change? - What is the correct conventional commit type? 4. Generate the commit message using this format:():[optional body with 2-4 lines of context]Co-Authored-By: Claude noreplyanthropic.com[1]Type must be one of: feat, fix, refactor, test, docs, chore, ci, perf, build, revert. Rules: - Description line: imperative mood, lowercase, no period, ≤72 characters. - Do not includeCo-Authored-Byifthe user did not use Claude Code. - If the change touches multiple unrelated concerns, suggest splitting into multiple commits. - Do not stage or commit automatically. Output the message andletthe user confirm.关键设计点最后一条规则Do not stage or commit automatically是安全边界。命令只生成消息不执行提交。把决策权留在人手里。这个设计反映了一个原则命令应该是一个强助手不是一个自动代理。它提供建议、执行分析、生成内容但不做不可逆操作。涉及文件修改和 git 操作的决策权永远在人手里。Conventional commit type 枚举值是故意固定的。不写 “etc” 或 “and so on”因为模型会在模糊的枚举里自己发明类型。固定的类型列表让输出可预测也能被下游工具CHANGELOG 生成器、语义版本工具正确解析。命令 vs 直接提示词决策矩阵不是所有任务都需要做成命令。以下矩阵帮助判断。|判断维度|用 Command|用直接提示词|| — | — | — ||使用频率|≥ 3 次/周|偶尔一次||团队复用|多人需要相同标准|仅个人使用||输出格式|需要一致的固定结构|灵活格式即可||步骤复杂度|≥ 3 步诊断/分析流程|一两句话能说清||迭代历史|已经改过提示词 ≥ 2 次|第一次用还没验证||参数化需求|需要传入文件路径、范围等|不需要||Token 成本|按需加载不浪费日常 Token|写在 CLAUDE.md 会持续消耗|决策流程任务出现频率 ≥3次/周 ├── 否 → 直接提示词即可 └── 是 → 需要团队统一标准 ├── 否 → 个人 CLAUDE.md 或 auto memory └── 是 → 输出需要固定格式 ├── 否 → 直接提示词 复制粘贴 └── 是 → 封装为 Command举例说明•/review代码审查频率高每次 PR团队需要统一标准severity、category输出格式固定findings summary gaps→Command。•/fix-test测试修复频率高诊断步骤固定reproduce → diagnose → fix → verify需要结构化输出 →Command。• “解释一下这个模块的职责”频率低不需要固定格式不需要参数 →直接提示词。• “用 Tailwind 重构这个组件”频率中但每次目标不同不需要团队统一标准 →直接提示词。团队命令策略发现值得提取的命令命令不是设计出来的是从重复行为中提取出来的。以下方法帮助识别命名规范动词-名词 格式 /review → 审查当前diff/fix-test → 修复失败测试 /release-notes → 生成发布说明 /commit → 生成提交消息 /update-deps → 更新依赖 /migrate-db → 执行数据库迁移规则• 用动词开头review、fix、generate、update、migrate、explain。• 用连字符分隔fix-test而不是fixTest或fix_test。• 一个命令一个任务不要做/review-and-fix拆成/review和/fix。参数设计$ARGUMENTS的设计需要考虑默认值和可选性# 好的设计有明确默认值Review the currentgitdiff$ARGUMENTS.# 不传参数 → 审查整个 diff# 传参数 → 审查指定路径如 /review src/auth/# 坏的设计参数是必须的但没有说明Fix$ARGUMENTS# 不传参数 → $ARGUMENTS 被替换为空字符串模型不知道修什么推荐模式# 模式 A可选路径过滤Review thediff$ARGUMENTS(leave emptyforfulldiff).# 模式 B必须参数 错误提示Fix the failing test:$ARGUMENTSIf notestpath is provided, list all failing tests and askwhichone to fix.# 模式 C结构化参数Generate release notes for:$ARGUMENTSAcceptable formats:v1.2.0..HEAD,main..feature-branch, or leave emptyforlast-tag..HEAD.维护生命周期命令不是写了就完。它有自己的生命周期淘汰信号• 连续 2 周没人调用 → 删除或归档。• 命令文件超过 50 行 → 评估是否升级为 Skill见第 08 篇。• 命令内容和 CLAUDE.md 重复 → 删除命令保留 CLAUDE.md 里的规则。Token 成本分析Command 的核心经济优势是按需加载。以下用真实数据对比。场景一个 8 人团队仓库有 120 行的 CLAUDE.md约 1800 tokens3 个命令平均每个约 400 tokens。不用命令所有规则塞 CLAUDE.md每次会话 Token 开销Claude Sonnet 200K 上下文 ├── 系统提示词 ~3,000 tokens ├── CLAUDE.md膨胀版 ~4,200 tokens ← review 规则 fix-test 流程 commit 规范全在里面 ├── Rules 文件 ~400 tokens ├── 用户消息 ~1,000 tokens ├── 工具调用 结果 ~15,000 tokens中等复杂任务 └── 历史对话 ~20,000 tokens ───────────────────────────────── 合计 ~43,600 tokens 剩余推理空间 ~156,400 tokens 问题一个改按钮颜色的任务加载了 review 规则、test-fix 流程和 commit 规范 但这些内容只在特定场景才需要。2400 tokens 的无效加载。用命令CLAUDE.md 精简 按需调用日常会话无命令调用 ├── 系统提示词 ~3,000 tokens ├── CLAUDE.md精简版 ~1,800 tokens ├── Rules 文件 ~400 tokens ├── 用户消息 ~1,000 tokens ├── 工具调用 结果 ~15,000 tokens └── 历史对话 ~20,000 tokens ───────────────────────────────── 合计 ~41,200 tokens 节省 ~2,400 tokens5.5% 调用 /review 时 ├── 基础开销 ~41,200 tokens ├── /review 命令注入 ~400 tokens ├──diff内容 ~8,000 tokens └── review 输出 ~2,000 tokens ───────────────────────────────── 合计 ~51,600 tokens 命令边际成本 ~10,400 tokens仅本次会话 调用 /commit 时 ├── 基础开销 ~41,200 tokens ├── /commit 命令注入 ~350 tokens ├── stageddiff~1,200 tokens └── commit 消息输出 ~200 tokens ───────────────────────────────── 合计 ~42,950 tokens 命令边际成本 ~1,750 tokens仅本次会话年度成本估算基于 200 个工作日每天 3 次会话|策略|每日 Token 成本|年度 Token 成本|浪费比例|| — | — | — | — ||全塞 CLAUDE.md|~130,800|~26.2M|~15% 无效加载||Command 按需|~125,200 按需| 25.0M 0.5M|~2% 无效加载|差距不大是因为单个命令的 token 量小。但当命令数量增加到 10 或命令内容变长800 tokens each按需加载的优势会放大。更实际的场景假设团队有 8 个命令每个平均 500 tokens分布在 review、test-fix、deploy、migration 等不同领域。一个典型的工作日每个开发者大概调用其中 2-3 个。如果这些全塞进 CLAUDE.md每天每个会话多消耗 4000 tokens8 x 500。一个 10 人的团队200 个工作日下来就是 10 x 3 x 200 x 4000 2400 万 tokens 的无效加载。按 Claude Sonnet 的定价约 $3/M input tokens这就是约 72 美元/年的纯浪费。金额不大但它挤占的是模型的有效推理空间——每个会话少了 4000 tokens 的思考余地。核心洞察Command 的主要价值不是省 Token而是标准化输出和消除提示词漂移。Token 节省是副产品。真正的收益是每个团队成员调/review得到的都是同一种格式的输出不需要每次重新教 Claude Code 审查标准。失败案例15 个命令的僵尸仓库一个 12 人的后端团队在 monorepo 里创建了 15 个 Slash Commands。三个月后只有/review和/commit被持续使用其余 13 个要么从未被调用要么调用结果不如直接写 prompt。这个案例的教训不是不要创建命令而是没有纪律的命令创建比没有命令更糟糕——因为 15 个命令的维护成本保持描述准确、同步业务变更分散了团队注意力却没有带来对应的价值。命令清单名称已脱敏.claude/commands/ ├── review.md → 高频使用 ✅ ├── commit.md → 高频使用 ✅ ├── fix-test.md → 偶尔使用 ⚠️ ├── release-notes.md → 偶尔使用 ⚠️ ├── explain-api.md → 从未使用 ❌ ├── generate-mock.md → 从未使用 ❌ ├── update-deps.md → 调用过但效果差 ❌ ├── migrate-user.md → 单项目特用不该做命令 ❌ ├── seed-data.md → 单项目特用不该做命令 ❌ ├── deploy-staging.md → 内容和部署文档重复 ❌ ├── deploy-prod.md → 内容和部署文档重复 ❌ ├── lint-fix.md → 一句话能说清直接写就行 ❌ ├── format-code.md → 一句话能说清直接写就行 ❌ ├── check-types.md → 一句话能说清直接写就行 ❌ └── onboard.md → 应该是 Skill不是 Command ❌根因分析三类失败模式模式 A边界不清——Command、CLAUDE.md、Skill 混淆deploy-staging.md和deploy-prod.md的内容是从部署文档里复制过来的流程步骤。这些步骤应该写在部署文档里需要时通过 Skill 加载见第 08 篇。做成 Command 的结果是部署流程更新了命令文件没同步更新团队不信命令输出的内容。onboard.md更是典型——它包含 80 行的项目介绍、架构说明和开发环境搭建步骤。这显然是 Skill 的职责需要步骤、需要资源、需要长期维护但被塞进了 Command 格式。explain-api.md的内容本质上是读 src/routes/ 目录解释每个端点的职责。这个任务不需要标准化输出每次执行的关注点不同直接写 prompt 更灵活。模式 B过度具体——单项目特用命令migrate-user.md是为用户表迁移写的专用命令。seed-data.md是为开发数据库种子数据写的专用命令。这些命令只在一个项目的一个特定阶段有用。做成命令的理由是以后可能复用但以后从未到来。教训不要为假设的复用创建命令。只有真实发生 ≥ 3 次的重复才值得提取。模式 C过于简单——一句话就是提示词lint-fix.md的全部内容是Run the linter and fix all auto-fixable issues.。format-code.md是Run the code formatter on all changed files.。check-types.md是Run the type checker and report errors.。这些命令的提示词短到没有必要做文件。直接写pnpm lint --fix的效果一样甚至更可控。更关键的是这类操作应该自动化不应该依赖人记得去调用命令。格式化和类型检查是 PostToolUse Hook 的职责——每次文件修改后自动执行不需要人工触发。把自动化操作包装成人工命令本质上是把工具的问题转嫁给了人的记忆力。修复方案修改前15 个命令2 个高频使用13 个闲置 修改后 ├── review.md → 保留高频使用 ├── commit.md → 保留高频使用 ├── fix-test.md → 保留中等频率 ├── release-notes.md → 保留中等频率 ├──[其余11个删除]│ ├── explain-api → 不需要命令直接 prompt 更灵活 ├── generate-mock → 不需要命令直接 prompt 更灵活 ├── update-deps → 迁移为 CLAUDE.md 规则更新依赖后运行 pnpm test├── migrate-user → 一次性脚本不是命令 ├── seed-data → 一次性脚本不是命令 ├── deploy-staging → 迁移为 Skill见第 08 篇 ├── deploy-prod → 合并到 deploy Skill ├── lint-fix → 迁移为 CLAUDE.md 规则lint --fix after changes├── format-code → 迁移为 HookPostToolUse 自动格式化 ├── check-types → 迁移为 HookPostToolUse 类型检查 └── onboard → 迁移为 Skill需要步骤、资源和长期维护Command vs CLAUDE.md vs Skill 边界规则|内容类型|正确位置|原因|| — | — | — ||高频多步任务需要固定输出格式|Command|按需加载不浪费日常 Token||一句话就能说清的规则|CLAUDE.md|不值得单独文件||每次都应该自动执行的操作|Hook|确定性 提示词||需要步骤、资源、脚本的复杂流程|Skill|Command 装不下||偶尔用一次的灵活任务|直接 prompt|不需要标准化|落地检查清单按顺序执行• [ ] 仓库里有.claude/commands/目录• [ ] 命令数量 ≤ 5 个初期。超过 5 个时用上面的决策矩阵审查每个命令的必要性• [ ] 每个命令有 frontmatter至少description字段团队成员能在命令列表中理解用途• [ ] 每个命令用$ARGUMENTS参数化关键输入并处理了参数为空的场景• [ ]/review命令要求 findings first、severity 枚举、verification gaps• [ ]/commit命令不自动执行提交只输出消息让用户确认• [ ] 没有单项目特用的命令——那些是一次性脚本• [ ] 没有一句话就能说清的命令——那些应该放 CLAUDE.md• [ ] 没有超过 50 行的命令——超过 50 行考虑升级为 Skill• [ ] 每个命令在 3 个真实任务上验证过误判和漏判已反馈进命令文本• [ ] 团队成员知道命令存在在 README 或 CLAUDE.md 里列出可用命令交叉引用•第 04 篇CLAUDE.md命令里一句话就能说清的规则应该放在 CLAUDE.md不要单独做命令。Command 和 CLAUDE.md 的 Token 成本差异是分工的基础。•第 08 篇Command → Skill 升级当命令文件超过 50 行、需要资源文件或脚本、或者需要长期迭代时应该升级为 Skill。本文的失败案例展示了延迟升级的后果。•第 09 篇SKILL.md 结构Skill 的Use When/Do Not Use When设计解决了命令的误触发问题。如果命令经常被错误调用它更适合 Skill 的触发模式。引用链接[1]noreplyanthropic.com:mailto:noreplyanthropic.com