写代码这几年,我有个雷打不动的习惯:凡是超过三次的重复操作,我一定会想办法把它自动化。在终端里用 Claude Code 跑代码审查、补测试、生成提交信息的时候,我一开始也是每次手动输入一长串提示词。直到我试了 template 机制,才发现自己之前在同一个沟里反复摔了十几次——明明可以把那些高价值、高重复的提示固化成一键调用的 slash 命令。
claude-code-templates 这个项目,说白了就是一套 Claude Code 自定义命令模板的集合。它的核心价值不是省几步打字,而是把“怎么跟模型描述任务”这件事标准化。用过的人应该都有同感:同一个任务,你随手写的提示和认真设计的提示,输出质量能差出好几个级别。模板就是把这个差距固化下来,让每一次调用都维持在高水位。
这篇文章我会从模板的存放机制、YAML 头部结构、变量传参,讲到怎么自己设计、测试和迭代模板,最后给你看几个我日常真正在用的模板实例。如果你也在用 Claude Code 做编码辅助,或者刚接触 slash command 这套玩法,这篇文章应该能帮你少走不少弯路。
1. 模板机制的本质:一个 Markdown 文件就是一个新技能
1.1 两个命令目录,决定模板的作用范围
Claude Code 的模板不是写在配置文件里的复杂 DSL,就是一个普普通通的 Markdown 文件。文件放在指定目录里,文件名就是触发命令的名字。我一开始没搞懂这点,以为需要注册或者配置什么,实际上形式简单到有点让人意外。
这套机制底下有两个存放位置,对应两种作用范围。一个是用户级目录~/.claude/commands/,所有项目都能用;另一个是项目级目录.claude/commands/,只对当前仓库生效。这两个目录的取舍逻辑很直白:通用性高的放用户级,项目特性强的放项目级。比如我常用的代码审查模板放在用户级,但针对特定项目数据表结构的检查模板就放在项目级,团队一起共享,避免污染全局配置。
实际操作中,两边的文件格式完全一致,都是.md文件,所以迁移起来很轻松。我见过有人把项目级模板做到三四十个,全局只有三个核心模板,这种结构我个人觉得比较健康。全局模板越多,维护成本越高,因为你要不断保证它们对所有项目都通用。
1.2 YAML 头部是命令的身份证
每个模板文件开头都有一段被---包裹的 YAML 区域,这段元数据决定了这个命令怎么被识别。最少需要三个字段:name是显示名称,description是给模型和用户看的说明文字,argument-hint提示用户该输入什么参数。其中description的作用常被人低估。
在 Claude Code 的交互界面里,你敲/之后,系统会把模板的description展示出来供选择。这就像命令行工具的 help 文本——写得好,命令好不好找、找得准不准,全靠它。我见过有人写“‘代码审查’”这种模糊描述,结果每次都得靠记忆去匹配;也见过有人写“‘检查当前分支未提交改动,按安全、性能、可测试性、可维护性四个维度给出问题列表,每个问题附对应行号和修复建议’”,这种一眼就知道调用了能得到什么,交互摩擦小很多。
argument-hint的作用则是给执行输入框占位提示。比如审查模板的提示可以写“可选:指定重点审查的文件或目录”。用户敲/review看到这个提示,自然知道自己可以在后面追加内容。
1.3 模板正文:不是普通提示词,而是约束协议
模板的正文部分,就是斜杠后跟着的真实系统提示内容。理论上你写什么都行,但我觉得这里必须克制。一个模板不应该堆砌一堆宏大的目标描述,比如“你是一个资深的软件架构师,精通所有语言和框架”,而要聚焦在这个任务的具体输入输出约束上。
我把比作协议栈:提示词就像是应用层协议,把一切都规定好;正文中应该指出输入是什么,输出长什么样,边界条件有哪些。比如一个代码审查模板,正文就该写清:先执行什么命令获取 diff,按什么顺序检查,如何报告严重程度,哪些情况不要涉及,输出格式要求是什么。这样模型的行为边界清晰,不会被无关信息带跑。
--- name: 深度代码审查 description: 对当前分支未提交的改动进行结构化审查,输出按严重程度排序的问题清单 argument-hint: 可选:指定审查范围,如某个文件或某类问题 --- 你先执行 git diff 获取最近一次提交以来的所有改动记录。 审查维度依次为: 1. 安全问题 2. 边界条件与异常处理 3. 性能隐患 4. 可读性与可维护性 5. 测试覆盖缺口 对于每个问题,必须给出: - 问题所在文件和行号 - 问题说明和影响范围 - 具体修复建议 如果改动涉及外部接口或数据格式变更,优先检查兼容性。未发现问题的维度直接跳过,不要输出“没问题”之类的占位内容。我刻意用命令式的“你”开头,让模型明确自己在执行指令而不是参加讨论。命令语气和纯提示词之间的差别,调用几次之后你会有非常直接的体感。
2. 第一个模板实操:把审查流程变成一键命令
2.1 从裸提示到模板:审查工作流的三个痛点
没写模板之前,我每次让 Claude Code 做代码审查,都得现场输入一大段说明。最麻烦的是这三点:第一,审查的标准每次都不完全一样,今天强调安全,明天强调性能,输出就飘忽不定;第二,获取代码差异的命令有时候会忘,模型会问我要 diff,一来一回浪费不少时间;第三,输出格式不统一,有时候它给一大段散文,有时候给个列表,我还得自己整理。
模板要解决的就是这三件事。标准写死在模板里,命令自己预置执行,输出结构固定。所以写模板的第一个动作,不是一上来写一堆要求,而是先把这几件事理清楚:输入靠什么获取,检查标准是什么,输出怎么组织。
2.2 完整范例:review 模板的组成拆解
一个标准模板由两个文件片段构成:YAML 头部 + 正文提示。我把实际在用的review.md简化一下,你就能看出设计是怎么落地的:
--- name: 深度代码审查 description: 获取当前分支与主分支的差异并执行结构化审查,返回带行号的具体问题清单 argument-hint: 可选:重点审查的文件或目录 --- 你已经连接到一个 git 仓库。先执行以下命令: git diff --stat git diff -- $(if [ -n "$ARGUMENTS" ]; then echo "$ARGUMENTS"; else echo ""; fi) 随后按以下顺序逐项审查变更内容: 1. 越权与数据校验缺口 2. 空指针、数组越界、资源未释放等边界问题 3. 数据量增大时的性能和复杂度问题 4. 设计一致性与代码重复 5. 测试覆盖缺失的关键分支 输出格式: - 每个问题使用单独条目,包含文件路径、行号、问题类型、修复建议 - 按严重程度排序,从高到低 - 如果有跨文件的数据流变更,单独一节画出数据流向 约束: - 不要提出重构整个模块规模的建议 - 不要输出表扬性评论 - 所有建议必须能直接落地到具体代码行这里有几个细节值得展开说说。第一,git diff命令被预先写死在模板里,模型不需要猜或者问你要 diff;第二,$ARGUMENTS是用户敲/review 文件名时传入的内容,模板脚本会把它嵌入命令;第三,“约束”这一段不是摆设,它实际上定义了行为的上下界,避免模型把审查报告变成夸夸群或者重写建议书。
2.3 模板与模型能力的分工边界
写模板时要不断提醒自己一件事:模型本身已经很聪明了,不需要你把每一步都掰开揉碎。模板的价值在于把信息结构和约束表达清楚,而不是替模型思考。
比如审查维度那五条,如果不写,模型也会尝试从几个常见维度审查,但结果往往时有时无,偶尔还会冒出一些和当前任务无关的泛泛而谈。写上之后,模型会沿着固定轨道走,行为和输出质量的可预测性大大提升。但你再往里写“检查第 100 行有没有缓存缺失”这种具体细节,反而会限制模型结合上下文做判断的能力。这个分寸,多做几次模板调试就会拿捏。
有一个判断标准我一直在用:模板跑完之后,如果每一轮输出都能直接看,不用二次加工说明,这个模板的约束就算合格了;如果还需要你手工补充背景信息、修正格式、追问深挖,那就是提示约束和真实工作流还是没完全对齐。
3. 模板里的变量系统:别硬编码,让参数飞一会
3.1 处理用户输入的传参入口$ARGUMENTS
模板最容易被忽视的部分是变量系统。我自己已经踩过坑:第一种是把参数硬编码进模板,导致换一个场景就要改文件;第二种是压根不用变量,认为模板是一次性的,结果工作量全花在改模板上了。
$ARGUMENTS是用户调用命令时输入的文本,会原样传给模板正文。比如你敲/review src/utils/,那$ARGUMENTS值就是src/utils/。前面审查模板里那句git diff -- $(if [ -n "$ARGUMENTS" ]; ...),就是在没有参数时对全量 diff 执行审查,有参数时就限定到指定路径。
这个变量可以出现在模板正文的任何位置。它不限于命令里的参数占位,也可以是任务描述的内容。比如测试生成模板里写上“‘请为 $ARGUMENTS 对应的函数生成单元测试’”,用户敲/test login,模型就会聚焦到 login 相关的模块。
3.2 上下文内置变量:让模板感知所在环境
除$ARGUMENTS之外,Claude Code 还提供了若干内置变量,常见的有$CLAUDE_PROJECT_DIR,指向当前工作区根目录。这类变量可以把模板从“通用文本”升级为“能感知环境”的助手。
拿提交信息模板举例。模板可以让模型先看$CLAUDE_PROJECT_DIR对应目录里的CHANGELOG.md风格约定,再参考git log --oneline -10的提交习惯,生成符合项目组织惯例的提交信息。不同团队的提交信息风格差异很大,不通过变量感知上下文的话,就得每换一个团队就改一个模板。
我在并发处理多个项目时深刻体会到这套变量的好处,同样的提交信息模板在不同仓库跑出来的信息格式完全贴合各自习惯,零手工改动。
3.3 通过参数组合调节模板行为模式
一个容易被忽略的参数是子点位切换,其实就是利用$ARGUMENTS做条件分支。模板正文可以用一些常见文本判断逻辑,让同一个模板适用不同模式。
比如我有个方案评审模板,参数支持“架构”“接口”“安全”三个关键词之一。模板正文里写“‘当前模式为 $ARGUMENTS 对应的专项评审,请围绕该专项展开,同时不以其他维度为审查重点’”。这样一个模板顶三个用,维护成本自然降下来。
我建议不要一上来把模板拆到粒度太细,一个任务一个文件,那样命令列表会爆炸。先用参数区分场景,观察哪种场景的输出质量确实撑不住,再考虑拆成独立模板,这样既保持命令面板整洁,也不牺牲输出质量。
4. 模板设计与测试流程:先想清楚,再写文件
4.1 我的模板决策清单
很多人写模板的路径是“临时要用→随手写→不好用→重新改”。我推荐先过一遍决策清单,能少改两轮。
第一,这个任务是否每周至少出现一次。低于这个频率,直接用普通对话即可,不值得为它建模板。第二,必须的输出结构是否明确。如果不明确,说明任务本身还没被理解透,先写成文档,等思路清晰了再做成模板。第三,这个模板未来会不会被反复修改。如果会,说明任务边界没稳定,先跑几轮对话观察规律,再沉淀成模板。第四,这个模板的输入是否稳定。输入不稳定就得靠参数来兜底,模板正文里必须预留条件分支。
这四条本质上是同一个问题:模板的底层稳定性够不够。任务描述、输入来源、输出结构三者的稳定度,决定模板是否值得固化。不稳定的话模板会成为维护负担,而不是生产力工具。
4.2 三步迭代法:从粗糙到够用
第一步,跑通路径。先在普通对话里手动完成一次完整任务,收集对话记录作为素材。第二步,提炼模板。把对话中有效的约束和格式提取到模板正文,注意只保留和当前任务强相关的指令,删除寒暄和泛泛要求。第三步,加变量和边界。把用户在真实工作中会传的参数接上,把不可能的输入提前兜住。
我每次新建模板都会留一个测试用例清单,比如审查模板的测试用例就包括:空 diff、带大量删改的 diff、跨文件接口变更、参数传了不存在目录等。这几类用例跑通之后,模板才敢在真实项目里用。
4.3 模板质量评审:怎么判断好不好用
写完之后,要站在“第二个使用者”的角度重新读一遍模板。如果一个陌生同事第一次打开这个模板,他能不能明白这个命令是干嘛的、需要他提供什么?这是最基础的体验标准。
第二个标准是健壮性:模板在模型“读不到 diff”“用户输入与预期不符”等异常情况下,输出是否仍然有参考价值。我见过不少模板把命令写得特别死,比如内容过时,模型跑完只给出一个空壳。大多数时候,只要在模板末尾加一段“当上述命令执行失败或没有输出时,请说明实际情况并建议替代方案”,输出就会扎实很多。
第三个标准是克制:模板有没有在教模型“变成一个好工程师”这种话?有的话删掉。模板应该聚焦任务本身,而不是给模型整容量身定制的世界观。
5. 六个我实测下来高频使用的模板
5.1 提交信息生成器的设计细节
提交信息模板是我用得最频繁的。它的痛点在于不同仓库的信息规范不一样,口头描述很容易跑偏。
模板的核心逻辑是三步:先看git diff --stat了解改动规模,再看git diff具体内容,最后参考git log --oneline -20的提交风格来撰写。生成信息时我会要求在 message 中明确指出改动目的、影响范围,以及是否有破坏性变更。模板按内容类型划分标签,而不是只按固定格式。
5.2 补测试模板:按缺陷驱动补覆盖
测试生成模板我曾经翻车过。一开始我写的模板让模型按函数一个个补测试,结果冒出一堆毫无意义的断言,覆盖路径和真实业务毫无关联。后来的版本改成按缺陷驱动:先分析当前实现的边界条件和异常分支,再反向生成能暴露这些缺陷的测试用例。
这个模板的正文会明确几条规则:不要生成只覆盖主路径的“快乐测试”;每个测试必须对应一个具体的边界场景;外部依赖要被 mock 掉,不能依赖真实网络或数据库;测试命名遵循Test{被测函数}_{场景}_{期望结果}的模式。跑下来的覆盖率和测试有效性都明显提升。
5.3 重构安全网模板:让重构告别盲目
重构类操作是高风险场景,模板的核心作用不是教模型怎么改代码,而是先建立安全网。输出分为三个区块:当前存在哪些隐性依赖,重构涉及哪些改动点,改完后如何验证没有行为变化。
模板要求模型先列出文件依赖关系,再逐个分析每个依赖是否会被改动波及。至少在提示里我会强调“行为必须完全保持,除非用户明确要求改动行为”。这是重构模板和通用编码助手的最大差别:它有明确的不变式约束。
5.4 技术方案评审:把评审当成架构深度检查
评审模板对项目级使用价值很高,特别是多人协作时。它不单单看代码问题,还会顺藤摸瓜把当前变更所在的模块上下文捞出来。
模板会要求模型读取相关文件后判断:这次变更是修修补补还是架构演进中的一个环节;如果是长期演进的一部分,是否应该先调整模块边界;是否存在替代方案,这些方案被否掉的理由是什么,等等。输出里还必须包含对当前技术债的评估,并在建议中标注“现在做”“版本内做”“必须提前规划”的优先级。
5.5 文档生成模板:保持与实现的一致性
写文档是最容易和代码疏离的任务。文档生成模板的目的不是从零写一份大百科,而是基于代码变更增量更新相关文档。模板让模型先找出现有文档中与变更描述冲突的部分,再生成变更补丁形式的文档更新。
关键是模板中加了一条指令:更新文档时原文整体结构不要推翻,只调整与当前变更相关的内容。避免模型顺手把所有旧文档都改成自己喜欢的样子,造成文档和代码之间更大的漂移。
5.6 调试协助模板:把错误堆栈变成排查路径
当我把一段错误日志直接粘进对话时,模型的表现经常忽上忽下。调试模板就是为了稳这块。它的流程是先识别错误类型,再定位体内变量状态,然后给出最小复现方式和修复路径。模板要求模型不要止步于这一处报错,而是向下追一层,“这个错误是否只是数据流下游的症状”。输出时会明确分“立即解决”和“根本解决”两个层次,很自然能避免隔靴搔痒的修复。
6. 常见坑与解决路线:模板不生效的原因排查
6.1 未生效的模板大概率是这几个原因
模板文件放好后,敲/命令时如果没出现,我第一个会检查的是文件扩展名和文件名。命令名与文件名保持一致的规则很容易因为复制过程出问题;扩展名必须是.md,写成.txt或者.markdown都可能导致命令不识别。
第二个常见原因是 frontmatter 格式问题。YAML 的字段缩进不能随意,name和description冒号之后要记得留空格。一个调皮的半角字符就能让你辛苦写的模板完全不可用。遇到这种情况我会先把文件内容复制到一个在线 YAML 校验器里跑一遍,通常立刻就能定位。
6.2 模板中出现的命令权限问题
模板正文里嵌入了很多 shell 命令,比如git diff或者find。如果当前项目目录不是标准 git 仓库,命令就会失败。这时模型会报错或者输出一段尴尬的错误信息。
我的处理习惯是在模板正文加一句“如果命令报错,请把错误信息原样转达,并建议用户检查是否在 git 仓库内执行”,同时要求模型把失败原因纳入输出,而不是自己猜一个。这样模板行为在任何环境下都有明确兜底。
6.3 模板迭代的最终归宿:先局部,再全局
模板不会一次成型。我建议先在项目级目录里跑新模板,经过两三周的实测验证、修改稳定之后,再升到用户级目录做全局共享。升到全局之前,一定要把模板中所有项目特有信息清理干净,比如项目名、特有路径、特定依赖库等。
模板的维护频率不需要特别高,每两三个月审视一次就够。如果发现某个模板长期没用上,我会先看看是不是命令入口太深,就靠调一下description把入口暴露得更明显;如果还是没人用,那就直接删掉。保持命令面板可以一个屏幕扫完,比攒一堆“可能有用”的模板更健康。
最后分享一点实际操作里的体会:模板做多了你会发现,最难的不是写提示词,而是克制住“什么都想写进模板”的冲动。一个模板只负责一件事,每份模板都按照任务的输入输出结构去设计,不掺入模型教育、不掺入风格偏好、不掺入与任务无关的规则,那它一定是个好模板。项目如果刚开始接触 Claude Code,建议挑一个最痛的任务建个模板试试,一天内你就能感受到这套机制的真正分量。