YAOTU INSIGHTS

Claude Code模板体系:从CLAUDE.md到Hooks的完整实战

Claude Code模板体系:从CLAUDE.md到Hooks的完整实战
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. 性能隐患N1 查询、循环内重复计算、不必要的同步阻塞 5. 可维护性复杂度过高、职责不单一、命名含糊 输出要求 - 按 Critical / Major / Minor 三级列出问题每个问题附带文件路径和行号 - 每个问题给出为什么是问题的一句话解释再给怎么改的具体建议 - 最后输出一个按优先级排序的修复清单标注预计改动量小/中/大 除非确有阻塞性问题否则不要输出超大段总结直接给问题清单。注意几个细节argument-hint字段会显示在命令帮助里告诉使用者这个命令可以接收一个可选参数。我特意写成留空则审查 git diffAI 在未收到参数时会自动切换模式这样/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 /reviewAI 会先读取git diff然后按模板中的审查维度依次检查。我实际拿到过的几条有价值的输出长这样Criticalsrc/modules/order/service.ts:224在并发扣减库存时UPDATE语句缺少stock quantity条件存在超卖风险。建议改为条件更新并检查 affected rows。Majorsrc/modules/order/service.ts:241捕获异常后直接return null丢失了错误上下文调用方无法区分订单不存在和库存不足两类失败。Minorsrc/modules/order/repository.ts:118在循环内逐条更新库存存在 N1 写入可改为批量UPDATE ... CASE WHEN。这比我手工 review 的覆盖率还高尤其超卖和 N1 这两个点确实是容易被忽视的。模板中输出要求那一节起了关键作用——它约束了 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里写了禁止使用 anyAI 却照用不误。先说排查路径。第一步确认模板是否真的被加载用/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 编码行尾统一成 LFfront matter 里的键值对使用英文冒号加空格。虽然大多数情况下 AI 能容忍这些小瑕疵但在解析 YAML 元信息时偶尔会翻车表现为命令描述显示异常或者参数提示丢失。用 VS Code 打开文件确认右下角编码方式顺手花一分钟标准化能省后续一小时的排查时间。6. 我整理模板库这段时间的一些体会现在回头看模板体系的收益不仅在于 AI 产出质量的提升更在于它把团队里隐性的编码认知显性化了。以前别人问我这个项目的代码规范是什么我得翻文档、翻代码、翻聊天记录才能拼出来。现在直接打开.claude目录就能看到一份带版本号的、活的项目规范。它不再只是给 AI 看的配置文件反而成了团队的技术文档入口。新人进来跑一遍/explain读一遍CLAUDE.md基本就能上手写代码。如果你还没开始建立自己的模板库我的建议是从最小闭环开始先写一份 30 行的CLAUDE.md把你的技术栈和三条最核心的编码底线放进去用上两天感受变化。然后再补第一个 slash command我推荐从/review入手因为它的收益最容易感知。后面再逐步加 hooks 自动化和角色模板不用一口气追求完美。我个人实际使用中还有一个习惯每两周会花半小时过一遍.claude目录删掉最近没有用到的命令、精简已经变长的模板文件。AI 工具迭代快模板不是写了就完事的静态资产而是跟着项目成长起来的活文档。你越维护它它给你的反馈就越稳定。