1. 我为什么开始认真折腾 Claude Code 模板
最近两三个月,我把 Claude Code 从"偶尔拿来写写脚本"升级成"日常主力开发工具",转折点就是开始系统整理模板。
先说一个背景:Claude Code 是 Anthropic 推出的终端命令行编程助手,跑在终端里,能直接读写代码、执行命令、调用测试,本质上是一个深度绑定工作目录的 AI 结对工程师。它跟你在网页上聊天的最大区别,就是它"能看到"你的项目结构、代码、git 状态,而且能自动完成多轮工具调用——改代码、跑测试、看报错、再改,一整条链路不需要你来回复制粘贴。
但你真正用它做正经项目就会发现一个痛点:每次会话它都像失忆了一样。你得反复交代技术栈、目录约定、不许用什么库、测试怎么写,甚至同一套 code review 标准每次都要重敲一遍。等到项目上了规模,团队里多人同时用,每个人交出去的上下午语境都不一样,AI 给出的方案风格也飘忽不定。
模板就是来解决这个问题的。我把"项目背景、编码规范、工作流约定、常用提示词、自动化钩子"全部固化到模板文件里,让 Claude Code 每次启动都能稳定地"读"到这些上下文。实测下来,模板化之后的产出质量稳定很多,代码风格高度一致,review 标准也不会因为当天问法不同而飘来飘去。
这篇文章会把我的整个模板体系拆开讲:从顶层设计、目录结构、每个模板文件的写法,到实际踩过的坑和排查方法。适合两类人看:一是刚接触 Claude Code、想让它真正干活而不是"聊聊天"的新手;二是已经在用但产出不稳定、想把这套工具团队化的进阶用户。
2. 模板体系的设计思路:先搞清楚你要固化什么
2.1 模板的本质是"上下文管理"
很多人以为模板就是一段好看的提示词,复制进去让 AI 按套路输出就行。这个理解太浅了。
模板真正管理的是AI 的工作记忆。Claude Code 每次会话开始时,会自动加载工作目录下CLAUDE.md文件、.claude/目录里的指令配置,这些内容会占据上下文窗口的前部,决定 AI 后续所有行为的"价值观"。你的模板写得越结构化,AI 的行为越可控。
我把需要固化的东西分成了四个层次,这个分层很重要:
- 项目层(CLAUDE.md):技术栈、目录结构、编码规范、测试要求。这是每次会话必须携带的"项目宪法"。
- 技能层(Slash Commands):代码审查、重构、写测试、生成提交信息等高频动作的标准工作流。相当于给 AI 预装了一套"操作手册"。
- 自动化层(Hooks):在 AI 执行特定动作前后自动触发脚本,做安全检查、格式校验、日志记录,不需要每次手动要求。
- 角色层(Prompt 模板):针对不同任务形态的精细提示词,比如"资深 reviewers""重构专家""测试工程师",可组合进会话开头或命令中。
这四个层次对应的是不同的加载时机和作用范围。项目层的CLAUDE.md是自动加载的,技能层的命令是你手动触发的,自动化层是事件驱动的,角色层则依赖你如何编排会话。
2.2 为什么不用"一段超大提示词"搞定一切
最早我也试过把项目规范、角色设定、任务要求全写进一个长提示词,一次性丢进去。效果不稳定,最直接的问题是:
第一,上下文窗口被挤爆。一段 2000 字的提示词看着不多,但后续对话的中间产物、工具调用结果都会叠加进来,多轮之后 AI 开始遗忘早期约束,规范形同虚设。第二,难以复用。项目 A 的规范换到项目 B 就失效,每次都要改一整段大文本,维护成本极高。第三,没有触发边界。审查代码时用写需求的语气,写需求时又用审查的口吻,角色串味。
所以我最终采用了"分层加载 + 按需触发"的方式:把永久不变的背景信息放进CLAUDE.md,把高频动作固化成 slash command,把安全校验交给 hooks,把特定角色需求做成独立模板文件。这样每个模板都短小精悍、职责单一,组合起来却覆盖了绝大多数场景。
2.3 目录结构的设计原则
我最终固定的模板库目录结构长这样:
project-root/ ├── CLAUDE.md └── .claude/ ├── settings.json ├── commands/ │ ├── review.md │ ├── test.md │ ├── commit.md │ └── migrate.md ├── prompts/ │ ├── architect.md │ ├── senior-reviewer.md │ └── debugger.md └── hooks/ ├── check-console-log.js └── guard-ts-ignore.js设计原则就三条:
- 职责单一。每个命令只做一件事,
/review只审查,/test只补测试,避免命令互相嵌套导致行为不可预测。 - 增量覆盖。
CLAUDE.md放全局约束,.claude/commands/里的命令只描述"如何做",不重复"为什么这样做"。AI 会把两者组合理解,而不是看到互相矛盾的指令。 - 可版本化。整个
.claude目录提交进 git,团队成员 clone 下来就能用同一套标准,新人上手成本大幅下降。
3. 实操环节:从零搭建一套可用的模板库
3.1 初始化目录与全局配置
第一步很简单,在项目根目录创建一个.claude文件夹,然后新建settings.json。这个文件管理的是 Claude Code 的运行时配置,包括权限开关、hooks 注册、环境变量等。
我的一个最小可用配置长这样:
{ "permissions": { "allow": [ "Bash(npm run *)", "Read(./src/**)", "Edit(./src/**)" ], "deny": [ "Bash(rm -rf *)", "Edit(.env)" ] }, "hooks": { "PreToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "node .claude/hooks/check-console-log.js" } ] } ] } }这里有几个细节值得展开说。
permissions是权限白名单与黑名单。Claude Code 默认在遇到敏感操作时会弹窗让你确认,但如果项目足够规范,你可以在allow里放行安全的常规命令(比如npm run build、npm test),把 AI 从频繁确认中解放出来。反过来,deny里务必写上对.env等敏感文件的编辑禁止、对rm -rf的拦截。这里有个经验:白名单写得越细,AI 干活越顺,但一定要先观察 AI 的常用命令再逐步放行,一开始太激进会失控。
hooks是事件钩子,PreToolUse表示在 AI 调用某个工具之前执行脚本,matcher限定触发范围。我这个例子是在 AI 执行任何文件编辑或写入操作之前,先跑一个脚本来拦截console.log写入生产代码。后面我会单独讲 hooks 的更多玩法。
3.2 编写 CLAUDE.md:项目的"宪法文件"
CLAUDE.md是 Claude Code 的自动加载文件,只要在当前目录或父目录里存在,每次会话启动时 AI 就会先读它。它不是可选的装饰,而是整套模板体系的基石。
我写CLAUDE.md有一套固定结构,按照"AI 读取时的优先级"排列:
# 项目说明 这是一个基于 TypeScript 的 Node.js 服务,采用 pnpm workspace 管理多包结构。核心业务是订单状态流转与库存同步。 ## 技术栈与目录约定 - 运行时:Node.js 20+,包管理使用 pnpm,禁止使用 npm/yarn 混用 - 语言:TypeScript 5.x,严格模式开启,禁止 any - 框架:Fastify + @fastify/type-provider-typebox - 测试:Vitest,测试文件与被测模块同目录,命名 `*.test.ts` - 目录结构:`src/modules/<业务域>/` 下自包含 controller、service、repository ## 编码规范(强制) - 所有新增 API 必须使用 TypeBox 定义 schema,并挂载到 Fastify 路由的 schema 字段 - 数据库访问统一走 repository 层,禁止在 service 里直接写 SQL - 错误处理:业务异常抛 `DomainError`,由全局错误中间件统一转换 - 日志统一使用 pino,禁止 console.log / console.error - 提交信息遵循 Conventional Commits 规范,类型前缀必须为 feat/fix/refactor/docs/test/chore 之一 ## 工作流要求 - 修改任何模块时必须同步更新对应的 `*.test.ts`,并保证测试通过 - 涉及数据库 schema 变更时,必须同时提供 `pnpm migrate:create` 生成的迁移脚本 - 执行 lint 命令:`pnpm lint`,不通过的代码不允许提交写这个文件有几个容易踩的坑:
不要写废话。我见过有人写"请友善地回答问题""你是资深工程师"这类话,纯属浪费 token。CLAUDE.md应该只包含影响代码产出的事实性约束。
区分"强制"和"建议"。AI 对含糊表述的理解会漂移,所以我明确用"强制"、"禁止"这类词划定边界,并配合具体示例说明。越是容易产生歧义的地方越要给反例。
CLAUDE.md 不适合写太长。我建议控制在 150 行以内。如果项目规范真的很多,把详细规范拆成独立文件,在CLAUDE.md里用"如需了解 XX 规范,读取.claude/prompts/coding-standards.md"这样一句话指路。AI 有需要时会自己按路径去读,不会白白占据上下文窗口。
3.3 构建自定义 Slash Command:让高频动作一键触发
如果说CLAUDE.md是"宪法",那.claude/commands/下的每个 Markdown 文件就是"标准作业程序"。命名方式就是你触发命令的名称,例如review.md对应/review。
我用的最多的一个命令是/review,完整内容如下:
--- description: 对最近改动或指定文件执行代码审查 argument-hint: "[可选] 文件路径,留空则审查 git diff" --- 请对 {{argument}} 执行一次严格的代码审查,审查范围优先基于当前 git diff。 审查维度按以下顺序执行: 1. 逻辑正确性:边界条件、并发问题、状态流转的遗漏分支 2. 类型安全:是否存在 any、隐式类型断言、未收窄的 unknown 3. 错误处理:异常是否被吞掉、错误信息是否可追踪、事务是否正确回滚 4. 性能隐患:N+1 查询、循环内重复计算、不必要的同步阻塞 5. 可维护性:复杂度过高、职责不单一、命名含糊 输出要求: - 按 Critical / Major / Minor 三级列出问题,每个问题附带文件路径和行号 - 每个问题给出"为什么是问题"的一句话解释,再给"怎么改"的具体建议 - 最后输出一个按优先级排序的修复清单,标注预计改动量(小/中/大) 除非确有阻塞性问题,否则不要输出超大段总结,直接给问题清单。注意几个细节:
argument-hint字段会显示在命令帮助里,告诉使用者这个命令可以接收一个可选参数。我特意写成"留空则审查 git diff",AI 在未收到参数时会自动切换模式,这样/review既适合提交前快速审查,也适合针对单个大文件做深度审查。
整个提示词只有两段话,加上输出要求,没有多余的"你是专家"之类的铺垫。原因是 slash command 已经占据了上下文中的明确位置,AI 知道自己在执行命令,不需要角色设定。把角色设定省下来,所有 token 都花在审查逻辑上,效果反而更好。
类似的命令我建议至少准备这几个:
/test:根据 diff 分析影响面,自动补全缺失的单元测试/commit:审查 unstaged 改动,生成符合 Conventional Commits 规范的提交信息/refactor:指定模块,输出重构方案和分步实施计划/explain:解释一段复杂代码的执行流程,适合对陌生模块做快速调研
每个命令的 markdown 文件都要遵守同样的格式规范:YAML front matter 管元信息,正文管行为指令,保持短小精悍。
3.4 配置 Hooks:让 AI 自动遵守规则的"隐形约束"
很多人用了 Claude Code 很久都不知道 hooks 的存在,但这是整套模板里价值最被低估的部分。
hooks 能让 AI 在触发某些工具调用时自动执行外部脚本,就像给 AI 加装了一套"感知器"。最常见的用途是在 AI 写代码前后做自动校验。
我前面配置过一个check-console-log.js,思路很简单:AI 在编辑文件之前,脚本先检查它即将写入的内容里是否包含console.log。实际脚本可以简化成下面这样:
#!/usr/bin/env node // .claude/hooks/check-console-log.js const fs = require('fs'); // Claude Code 会把上下文通过 stdin 以 JSON 形式传给 hook // 这里只做一次实际场景的简化处理 const input = fs.readFileSync(0, 'utf-8'); const { tool_name, tool_input } = JSON.parse(input); const content = String(tool_input.file_content || tool_input.content || ''); if (content.includes('console.log') || content.includes('debugger')) { console.error('Blocked: 禁止在生产代码中写入 console.log 或 debugger'); process.exit(2); // 非零且不等于 1 的退出码表示阻止该操作 }hooks 的退出码语义需要特别记住:0表示允许继续,1表示 AI 忽略并继续(相当于警告),2表示阻止该操作。市面上很多示例脚本都用错了退出码,动不动就exit(1),结果 AI 只是被提醒一下,照样把代码写进去了。想要"拦截",必须用2。
hooks 的第二个实用场景是在关键文件变更时自动记录审计日志。比如监听Edit(CLAUDE.md),任何人对模板文件的修改都留下记录,团队协作时能追溯是谁改了规范。hooks 的第三个场景是跟外部能力打通,比如PreToolUse时调用内部的 API 网关检查依赖版本是否合规。这块能力上限很高,值得长期投入。
3.5 角色层模板:什么时候才需要单独的角色提示词
我前面说 slash command 不需要角色设定,但角色提示词单独用在一个场景下特别合适:复杂任务的第一发投喂。
比如你要让 Claude Code 给一个老模块做架构梳理并输出优化方案,这不是简单调用某个命令能解决的。你需要先给它一个角色的"世界观",让它带着特定视角去探索代码,这时候角色模板才有价值。
我常用的architect.md角色模板大致长这样:
你是一个拥有 15 年后端架构经验的工程师,擅长微服务拆分、领域建模和渐进式重构。 在开始任何修改前,你必须先完成调研并输出结构化理解: 1. 梳理模块的领域边界:实体、值对象、领域服务分别在哪里 2. 识别当前架构的核心痛点:耦合点、数据一致性隐患、扩展瓶颈 3. 给出 2-3 个可选方案,标注每个方案的成本、风险、适用场景 4. 最终推荐方案必须包含分阶段实施计划,且每个阶段都能独立交付 风格要求:结论先行,用事实和证据支撑观点,不输出空洞的原则性废话。这份文件放在.claude/prompts/architect.md,需要时让 AI 读取这个文件再开始任务。路径可以写在会话里:"请先阅读.claude/prompts/architect.md,然后按其中要求分析modules/order目录"。
这里的思路是角色只影响思考框架,不影响具体行为约束。行为约束仍然由CLAUDE.md和 slash command 负责,两层井水不犯河水。
4. 模板实战拆解:从需求到落地的完整链路
4.1 一个真实的 /review 使用场景
光给模板不演示等于白讲,我拿一个实际场景完整走一遍。
假设我改了一个订单模块的库存扣减逻辑,git diff里新增了约 80 行代码。我在终端输入:
claude -p "/review"AI 会先读取git diff,然后按模板中的审查维度依次检查。我实际拿到过的几条有价值的输出长这样:
- Critical:
src/modules/order/service.ts:224在并发扣减库存时,UPDATE语句缺少stock >= quantity条件,存在超卖风险。建议改为条件更新并检查 affected rows。 - Major:
src/modules/order/service.ts:241捕获异常后直接return null,丢失了错误上下文,调用方无法区分"订单不存在"和"库存不足"两类失败。 - Minor:
src/modules/order/repository.ts:118在循环内逐条更新库存,存在 N+1 写入,可改为批量UPDATE ... CASE WHEN。
这比我手工 review 的覆盖率还高,尤其超卖和 N+1 这两个点,确实是容易被忽视的。模板中"输出要求"那一节起了关键作用——它约束了 AI 的产出格式,否则它会给你输出三段式作文,看起来专业但没重点。
4.2 Workflow 类模板:让 AI 按阶段执行任务
除了单点命令,我还常用一类"工作流模板",用来应对多阶段任务。比如"给新模块写完整 CRUD 服务",这类任务链路很长,直接让 AI 一口气做完,中间十有八九会跑偏。
我的解决方案是在.claude/commands/下新增一个workflow-module.md,内容按阶段编排:
--- description: 按阶段创建完整业务模块 argument-hint: "模块名" --- 请按以下阶段逐步完成 {{argument}} 模块的开发,每完成一个阶段必须停下来等我确认: 阶段一:产出设计草案。包括领域模型(实体、字段、关系)、API 路由清单、数据库表结构。只输出设计文档,不写代码。 阶段二:确认设计后,先写 repository 层和对应的测试,运行 `pnpm test` 确保通过。 阶段三:实现 service 层业务逻辑,补齐 service 测试,通过后进入 controller 层。 阶段四:注册路由与 schema 校验,运行 `pnpm lint` 和全量测试,输出完成总结。 每个阶段输出时,先给一个简短的"已完成清单",再列出下一步将要做的内容,方便我检查。这个模板的核心价值是把长任务拆解成可验证的短周期。AI 不会一次性闷头写完 1000 行代码然后丢给你一堆 bug,而是每一步都产出可检查的中间物。我确认后的设计才进入编码,避免了"方向错了白写 500 行"的典型悲剧。
4.3 模板中的变量与上下文组合技巧
Claude Code 的 slash command 支持{{argument}}这样的参数占位符,这是模板能否变通用的关键。我建议所有命令里只使用这一种参数形式,不要试图在模板里写复杂的条件逻辑——那是编程该干的事,模板保持"给 AI 的最小指令集"就够了。
组合使用的典型姿势是"一句会话里触发多个模板"。例如:
先阅读 .claude/prompts/senior-reviewer.md 建立审查视角, 再执行 /review src/modules/inventory/service.ts这样角色模板负责建立"怎么看",slash command 负责定"看什么和怎么输出",两层组合效果很好。不要把角色模板的内容复制进 slash command,也不要在 slash command 里重复角色设定,保持各自独立才能灵活组合。
5. 常见问题与排查实录
5.1 模板加载了但 AI 行为没变化
这是出现频率最高的困惑。明明CLAUDE.md里写了"禁止使用 any",AI 却照用不误。
先说排查路径。第一步确认模板是否真的被加载,用/context命令查看当前会话加载了哪些文件。如果列表里没有CLAUDE.md,说明你启动 Claude Code 的目录不在项目根目录。Claude Code 的加载规则是寻找当前目录及其父目录里的CLAUDE.md,所以如果你在src/子目录下启动,也依然能读到根目录的配置;但如果从项目目录外启动,就完全读不到了。
第二步检查是不是约束表述太软。我见过很多模板写的是"建议使用类型收窄""尽量不用 any",这种软性词 AI 会当成参考而非强制要求。把"建议"改成"必须""禁止",行为立刻不同。
第三步看是否存在冲突。如果根目录和子目录都有CLAUDE.md,两者的内容会合并,当规则冲突时 AI 会表现出随机性。解决方式是只在根目录放一份全局规范,子目录只放针对该目录的特殊约定。
5.2 Token 消耗飙升:模板太长或加载太多
模板体系建好之后,最直观的问题就是上下文消耗比之前大。CLAUDE.md150 行加上几个 slash command 的元信息,每轮会话可能多消耗 3000-5000 token。对长会话来说,这个成本很可观,可能影响到 AI 对后期内容的记忆力。
我建议做减法:
CLAUDE.md压到 100 行以内,只保留影响产出质量的硬约束- 把"背景知识型"内容(比如业务领域介绍、历史决策记录)挪到独立文件,用"当需要时读取"的方式按需加载
- slash command 的正文控制在 200 字以内,输出要求可以适当详细,但描述任务背景的话全部删掉
- 定期用
/context查看实际 token 消耗,把使用率不足 30% 的模板条目清理掉
这里有个反直觉的经验:删掉模板里"礼貌性"的内容。很多人在模板里写"请确保代码质量""请提供专业建议",这些表述不产生任何行为变化,却白白占用 token。模板只留"可执行的动作指令"。
5.3 Hooks 不生效或误拦截
hooks 是模板里调试成本最高的部分,我踩过三个典型坑。
第一个是退出码用错。前面提过,阻止操作必须exit(2),用1只会让 AI 收到一条警告然后继续执行。很多博客示例根本没讲清楚这个细节,导致很多人以为 hooks 是"形同虚设"。
第二个是环境问题。hook 脚本执行时不一定继承你终端里的完整环境变量,尤其是PATH。如果你在 hook 里调用node、pnpm报 command not found,很可能是 PATH 没带过去。解决方式是在脚本开头显式设置环境,或者用绝对路径调用可执行文件。
第三个是误伤正常操作。比如拦截console.log的脚本,如果把测试代码里的console.log也拦截了,AI 在写测试时会被反复打断。解决方式是让脚本检查文件路径,*.test.ts和*.spec.ts直接放行。hooks 的策略建议从"小而窄"开始,只覆盖最必须拦截的场景,逐步加码。
5.4 团队协作时模板漂移
如果你跟团队共享同一个模板库,最大的问题是"每个人都在改模板,最后变成一锅粥"。我经历过一次:A 觉得CLAUDE.md太长删了一段,B 又加回了一部分,两天后没人说得清当前规范是什么。
我的解法有两个,都很粗暴但有效。
第一,模板变更走 PR 评审。任何对.claude目录的修改都必须走 merge request,代码评审人专门看模板语义是否与项目实际一致。这样改动有记录,讨论有上下文,不会出现悄悄覆盖。
第二,给模板加版本号。在CLAUDE.md头部写version: 2.3.0,每次有行为变更就提升版本号。AI 在某个会话里用的是哪个版本一目了然,排查问题时能快速判断是不是模板版本差异导致的行为变化。
5.5 一个容易被忽略的细节:模板文件的编码与换行
这个坑可能很多人没遇到,但一旦遇到非常恶心:Markdown 模板文件如果包含全角标点混排、奇怪的换行,或者 YAML front matter 里有中文冒号,AI 解析时可能出现异常。
我统一的做法是:所有模板文件用 UTF-8 无 BOM 编码,行尾统一成 LF,front matter 里的键值对使用英文冒号加空格。虽然大多数情况下 AI 能容忍这些小瑕疵,但在解析 YAML 元信息时偶尔会翻车,表现为命令描述显示异常或者参数提示丢失。用 VS Code 打开文件确认右下角编码方式,顺手花一分钟标准化,能省后续一小时的排查时间。
6. 我整理模板库这段时间的一些体会
现在回头看,模板体系的收益不仅在于 AI 产出质量的提升,更在于它把团队里隐性的编码认知显性化了。
以前别人问我"这个项目的代码规范是什么",我得翻文档、翻代码、翻聊天记录才能拼出来。现在直接打开.claude目录就能看到一份带版本号的、活的项目规范。它不再只是给 AI 看的配置文件,反而成了团队的技术文档入口。新人进来跑一遍/explain,读一遍CLAUDE.md,基本就能上手写代码。
如果你还没开始建立自己的模板库,我的建议是从最小闭环开始:先写一份 30 行的CLAUDE.md,把你的技术栈和三条最核心的编码底线放进去,用上两天感受变化。然后再补第一个 slash command,我推荐从/review入手,因为它的收益最容易感知。后面再逐步加 hooks 自动化和角色模板,不用一口气追求完美。
我个人实际使用中还有一个习惯:每两周会花半小时过一遍.claude目录,删掉最近没有用到的命令、精简已经变长的模板文件。AI 工具迭代快,模板不是写了就完事的静态资产,而是跟着项目成长起来的活文档。你越维护它,它给你的反馈就越稳定。