
1. 为什么我会专门折腾一套 Claude Code 模板先说个背景。我日常大概有四五个项目在并行维护每个项目用的技术栈、目录结构、代码风格都不一样。早期我直接在终端里跑 Claude Code 干活最痛苦的不是它不懂代码而是每次切换到另一个项目我都得重新把这个项目是什么、目录怎么组织的、有哪些不能动的文件、测试命令是什么、提交规范是什么这些东西复述一遍。有时候换了个终端窗口忘了补充某个关键约束它就能一本正经地改到完全违背项目约定的地方去——比如给一个纯 REST 的老项目硬塞进 tRPC 的写法。后来我发现问题不在 Claude Code 本身而在于我交付给它的上下文太随意了。同样是让 AI 写代码给它一份完整的项目说明文档和让它现场猜项目结构出来的东西完全是两个质量等级。与其每次手动敲一堆说明不如把常用的约定、规范、命令、工作流全部沉淀成一套可复用的模板。这就是我这个 claude-code-templates 项目的来由——一套把 Claude Code 的配置能力全部用起来、可以在多个项目间复用的模板合集。这套模板解决的核心痛点有三个。第一是上下文一致性不管哪个项目进来AI 都能第一时间知道这个项目的底细不需要反复人工解释第二是效率复用平时高频的操作像跑单测做 code review按规范提交更新变更日志全部固化成命令一句话就触发第三是团队统一性把模板提交到仓库里新同事拉下来就能获得同样的 AI 协作环境不用在 onboarding 的时候口口相传。如果你属于下面这几类人这套模板的思路大概率能帮上忙日常大量使用 Claude Code 写代码但每次都要手动交代项目背景同时维护多个项目频繁切换上下文希望有一个即插即用的配置体系团队里多个成员都在用 Claude Code想统一 AI 辅助开发的规范纯粹对 Claude Code 的配置能力感兴趣想知道 CLAUDE.md、commands、hooks 这些机制到底怎么配合起来用。下面我就按我实际搭这套模板的顺序把每个部分的设计思路和具体内容展开讲。2. 模板的心脏CLAUDE.md 的分层设计CLAUDE.md 是 Claude Code 的项目记忆文件相当于每次启动对话时自动加载到上下文里的项目说明书。很多人对它有个误区觉得把越多信息塞进去越好。实际不是这样塞太多垃圾信息反而会稀释掉真正重要的指令。我折腾下来觉得正确的姿势是分层全局一层、项目一层、本地私有一层。2.1 全局层、项目层、本地层各放什么Claude Code 启动时会自动加载~/.claude/CLAUDE.md这个全局文件同时在当前项目目录下读取项目级CLAUDE.md。这两者的职责要分清楚否则会出现全局规范误伤某个项目的尴尬。我的原则很简单凡是跟你这个人怎么工作相关的放全局凡是跟这个项目本身相关的放项目目录。比如你习惯代码里用双引号而不是单引号、提交信息用 Conventional Commits 格式、遇到不确定的设计决策倾向先列方案再动手——这些属于我个人的工作习惯放全局合适。而这个仓库的模块划分、接口文档位置、哪些文件是生成出来的、构建命令是什么——这些属于项目事实放项目级。本地私有层是CLAUDE.local.md虽然我没把它加进模板仓库本身但值得知道它的存在。项目根目录放一份CLAUDE.local.md里的内容不会被提交到版本库适合放你本地特有的配置、正在做的分支任务、临时的注意事项。我会在模板的.gitignore里把它加进去。2.2 一个经得起用的入口文件结构我项目里常见的 CLAUDE.md 不是一大段散文而是非常结构化的分块内容。分享一个我一直在用的基础模板结构# 项目概要 这个项目是面向内部运营团队的数据分析后台核心职责是从数仓读取业务表 提供报表查询与看板展示不涉及面向 C 端用户的业务逻辑。 # 技术栈与目录约定 - 前端: React 18 TypeScript Vite组件放在 src/components - 后端: Node.js Fastify路由放在 server/routes - 数据库: 只通过 server/db 下的封装访问禁止业务代码直连 SQL - 生成物: dist/ 与 server/dist/ 均为构建产物不要手动改动 # 常用命令 - 安装依赖: npm install - 启动开发: npm run dev - 运行全部测试: npm test - 单测某个文件: npx vitest run src/components/Table.test.tsx # 编码规范与硬性约束 - 组件命名一律 PascalCase状态管理只用 zustand不要在项目里引入 redux - 提交信息使用 Conventional Commits由模板仓库提供的 commit-template 命令辅助生成 - 修改 server/db 下的接口时必须同步更新 docs/api.md这是硬性要求 - 禁止格式化 src/generated 下的所有文件这些是代码生成器产物 # 工作流程 1. 接到需求后先阅读 docs/ 下对应的需求文档再动手 2. 涉及数据库查询时先看 server/db/README.md 确认表结构约定 3. 完成代码后跑一遍全量测试再交给用户做自查 4. 若需要跨多个文件改动先列改动清单确认再批量执行这个结构有几处值得注意。开头项目概要一定要写得直白尤其要点明项目不是什么。很多项目的坑恰恰在于边界模糊你写清楚不面向 C 端用户不涉及支付流程AI 就不会在代码里脑补出会员体系、购物车之类的架构。目录约定部分与其列一堆目录名字不如写明通过什么路径访问什么能力同时把禁止写清楚。AI 常见的作死行为就是在业务代码里直接拼 SQL把构建产物改得一团糟这些用否定句式列出来比正向引导更有效。常用命令这一段我吃过亏。早期我觉得命令写在 README 里 AI 自己会去看但实测下来 Claude Code 经常不会主动翻 README就算翻了也容易选错命令比如把 vitest 的 watch 模式当成普通测试跑挂在那里等输入。把最常用的命令直接写进 CLAUDE.md是最省钱的做法。2.3 入口文件不是越全越好我得泼一盆冷水CLAUDE.md 超过大概 200 行之后效果反而下降。我有一次把一个老项目的所有历史决策都写进去了结果它太注重那些边角约束导致在处理主流程时缩手缩脚。现在的原则是入口文件只放每次对话都必须知道的信息剩下的放到 README 或者专门的 docs需要时让它现读现用。另外CLAUDE.md 支持用引用的方式把其他文件内容拉进来。比如我在模板里写README.md、docs/architecture.md这样入口文件保持精简需要细节时自动展开。这个语法在较新版本的 Claude Code 里都支持实测下来比复制粘贴一大段内容好用得多也解决了入口文件越写越长的问题。3. 把高频操作固化成 slash commandCLAUDE.md 解决的是静态上下文的问题slash command 解决的是重复动作的问题。平时在 Claude Code 里输入/就能看到一堆可用的命令。内置的一些像/compact、/clear都很有用但真正让模板发光的是自定义命令——它们被放在.claude/commands/目录下每个文件对应一个斜杠命令。3.1 命令文件的组织逻辑这个目录在项目根目录下也可以是全局的~/.claude/commands/。我的组织方式是把模板仓库里的命令分成几组按文件名前缀区分commit-template.md—— 生成符合规范的提交信息review.md—— 对当前改动做一轮 Code Reviewplan.md—— 复杂任务先输出实施计划changelog.md—— 根据 git log 生成变更日志test-file.md—— 针对指定文件跑测试并修复失败用例。每个命令文件的第一部分是一段 YAML frontmatter指定命令的元信息。下面拿我实际在用的命令举例。3.2 三个最常用的命令模板第一个是review.md。这个命令把门面功夫做得很足因为 Code Review 的场景其实信息量很大。我的写法是--- description: 审查当前分支的代码改动输出阻塞项与建议 argument-hint: [可选] 指定审查重点如 类型安全 / 性能 / 边界条件 --- 请针对当前 git 分支相对主分支的改动执行一次 Code Review。 审查时需要关注以下维度但不要机械逐条输出 1. 类型安全有没有用 any 绕过类型系统、有没有未处理的 null/undefined 2. 性能隐患比如在 render 循环里做重计算、N1 查询、缺少 memo 等 3. 边界处理空数组、超长输入、并发覆盖、错误路径 4. 一致性命名风格、目录归属、是否遵循 CLAUDE.md 中的约定。 输出要求 - 只列真正值得修改的问题不要为了凑数而写无关紧要的建议 - 每个问题注明文件路径与行号并按 阻塞 / 建议 两级分类 - 如果有阻塞项给出具体的修改建议而不是只说这里有问题。如果你给这个命令传了参数比如/review 性能$ARGUMENTS就会拿到性能这个值正好可以放进请求里作为审查重点。这个文件实际运行时Claude Code 会自动把提示词和你的代码上下文结合起来。我实际用下来它不像一个死板的静态规则列表倒更像一个起手式给 AI 足够的空间往下探索。第二个是提交信息模板。这个看起来简单但很能体现模板的价值。--- description: 根据当前 git 改动生成符合 Conventional Commits 规范的提交信息 argument-hint: [可选] 一句话描述本次改动意图 --- 请先运行 git status 和 git diff --stat 了解本次改动范围 再结合 $ARGUMENTS若有生成 3 条候选提交信息。 要求 - 严格遵循 Conventional Commits 2.0 规范使用 feat / fix / refactor / docs / test / chore 等类型 - 正文部分说明为什么做这个改动而不是简单复述代码 - 如果有 breaking change必须在脚注标明 BREAKING CHANGE。 最后请用户选择一个候选信息确认后再执行 git commit。命令通过 frontmatter 里的description出现在/菜单中这一步千万别省略不然你在终端里按/根本看不到这个命令。第三个是计划类命令。复杂任务我一般不让 Claude Code 直接上手就写而是先让它出方案。我的plan.md核心逻辑是把需求拆成实施步骤、标出风险点、明确哪些文件会被改动等用户确认后再动手。这个命令的提示词里我特意加了不得在确认前修改任何文件效果显著至少在改代码这层多了一道人为把关的保险。3.3 命令里的变量与嵌套调用技巧自定义命令文件里可以直接用一些内置变量常用的有$ARGUMENTS—— 用户在斜杠命令后输入的完整参数文本$1、$2—— 按空格分隔的第 1、第 2 个参数$CLAUDE_PROJECT_DIR—— 当前项目的根目录$CLAUDE_CWD—— 调用命令时的工作目录。我写命令时还有一个偏好能用脚本完成的事实提取不要让 AI 靠猜。比如changelog命令里我不会让 AI 自己去跑git log --oneline然后脑补而是先在 frontmatter 描述里让它执行git log -20 --prettyformat:%h %s拿到准确的提交列表再基于真实提交去整理变更日志。这一步避免了 AI 凭印象编造提交记录的现象。4. 用 hooks 把模板变成自动执行的规矩如果说 CLAUDE.md 是写在纸面上的规矩commands 是随叫随到的工具那 hooks 就是不用提醒也会自己动的规矩。4.1 hooks 能做什么Claude Code 在特定事件发生时可以触发预先配置的脚本返回结果还能影响后续行为。我在模板里主要用到了几个时机PreToolUse—— 在某个工具被调用前触发可以在脚本里决定放行、拒绝或转人工确认PostToolUse—— 工具调用完成后触发适合做校验和记录Stop—— 在 Claude 完成一轮回复后触发适合做收尾自动化比如统一格式化代码、运行核心测试UserPromptSubmit—— 用户提交新输入时触发可以注入或者改写上下文。这个能力的价值在于你不用再手动跟 Claude Code 说记得跑格式化记得跑测试它每次结束回复时脚本自动帮你收尾。我第一次用上这个的时候惊喜感明显比 slash command 更强。4.2 我在模板里放了三个 hook 配置下面这段是我项目settings.json里的实际配置片段{ hooks: { Stop: [ { matcher: edit|write, hooks: [ { type: command, command: npm run format:check, timeout: 60 } ] } ], PreToolUse: [ { matcher: Bash(npm run lint:fix), hooks: [ { type: command, command: node .claude/hooks/check-branch.mjs, timeout: 15 } ] } ], PostToolUse: [ { matcher: Edit|Write, hooks: [ { type: command, command: node .claude/hooks/append-todo.mjs, timeout: 10 } ] } ] } }第一个 hook 的意图是只要 Claude Code 本轮产生过代码改动在它结束回复时自动跑一遍format:check。注意我用的是format:check而不是format因为自动格式化有风险——如果 AI 改的代码还没完全稳定自动格式化可能引入额外的 diff而且有些编辑器里的格式化工具和命令行版本不一致会导致改完立刻又被改回去的循环。先做检查有问题再单独让它修这个节奏安全得多。第二个 hook 是我踩坑后的产物。有几次 Claude Code 在 main 分支上直接跑了lint:fix把所有文件都重新格式化了diff 大得吓人。后来我在 PreToolUse 阶段加了个脚本检测到要执行 lint:fix 时先检查当前分支如果是在 main 或者 master 上脚本返回拒绝并要求它先创建功能分支。这个小脚本大概二十行但足以避免很多次的手滑。第三个 hook 更像一个流水账记录器。每次 Claude Code 修改文件后把改动的文件路径追加到.claude/.last-session.md这样我每天收工前扫一眼这个文件就能知道 AI 今天都动过哪些地方。这个习惯帮我发现过不少次它改了我根本不想让它碰的文件的情况。4.3 hook 脚本的三个注意事项hook 写多了以后总结出几条经验第一脚本必须幂等。hook 可能会被多次触发脚本本身不能有副作用比如追加日志时别重复追加、做检查时别修改文件内容。最好设计成只读检查 返回 JSON的模式。第二超时时间别设太短。timeout默认以秒为单位我给格式检查留 60 秒给分支检查留 15 秒给日志追加留 10 秒。如果脚本里要跑 npm 依赖的东西时间要再放宽些宁可多等也别让 hook 因为超时被强制终止那样会造成脚本执行一半的尴尬状态。第三hook 的返回结构要规范。比如 PreToolUse 里的permissionDecision字段可以返回allow、deny或者ask。用deny时建议同时带上reason这样 Claude Code 能把拒绝原因反馈给模型而不是只显示一个干巴巴的错误。5. 模板库的完整目录结构与版本管理前面几节讲的是模板里的零件这节把它们组装起来。我在 GitHub 上维护的这个 claude-code-templates 仓库目录长这样claude-code-templates/ ├── README.md ├── templates/ │ ├── global/ │ │ ├── CLAUDE.md │ │ └── settings.json │ ├── project/ │ │ ├── CLAUDE.md │ │ ├── CLAUDE.local.md.example │ │ ├── .claude/ │ │ │ ├── commands/ │ │ │ │ ├── commit-template.md │ │ │ │ ├── review.md │ │ │ │ ├── plan.md │ │ │ │ ├── changelog.md │ │ │ │ └── test-file.md │ │ │ └── hooks/ │ │ │ ├── check-branch.mjs │ │ │ └── append-todo.mjs │ └── docs/ │ ├── setup-guide.md │ └── customization.md └── scripts/ ├── install.sh └── sync.sh各部分的职责我做了一个对照表路径作用放什么内容templates/global/安装到~/.claude/的全局配置个人工作习惯、全局命令、通用 hooktemplates/project/复制到项目根目录的模板项目结构、目录约定、常用命令、项目级命令与脚本templates/docs/使用说明与定制指南安装步骤、如何新增命令、如何调整 hookscripts/自动化安装与同步把模板复制到指定位置并生成必要的本地配置安装脚本做得很简单本质上就是拷贝文件#!/usr/bin/env bash set -euo pipefail # 安装全局模板 mkdir -p ~/.claude/commands cp templates/global/CLAUDE.md ~/.claude/CLAUDE.md cp templates/global/settings.json ~/.claude/settings.json # 把项目模板复制到当前项目目录 cp -r templates/project/. $(pwd)/ echo 模板已安装到当前项目检查 .claude/ 目录后即可使用实际使用的时候我不建议直接把整个项目模板全量覆盖到一个已有项目里因为每个项目的差异很大更合理的做法是手动挑选需要的部分。5.1 跨项目复用的几个选择用了一段时间之后我总结了三种复用方式第一种是直接拷贝适合新项目初始化把templates/project/整个复制过去再删掉不适用的部分。好处是干净坏处是后续模板有更新时需要手动再同步。第二种是软链接把.claude/commands和 hook 脚本软链到一个共享位置。好处是模板更新即时生效坏处是如果你在某个项目里改了命令文件会直接改到共享模板容易污染其他项目。第三种是git submodule 或子仓库把模板作为一个远程仓库项目里以子模块方式引入。这种方式最适合团队多人协作模板的升级通过 git 管理。我的建议是个人单项目用拷贝就够了个人多项目用软链接但注意备份共享目录团队协作优先 git submodule。5.2 模板版本怎么管我给模板仓库打 tag比如v1.2.0同时维护一份 CHANGELOG记录每个版本的变更点。这样当你需要把模板升级到新的版本时可以先看 CHANGELOG 判断这次改动是否会影响现有项目而不是闷头覆盖。对于命令文件和 CLAUDE.md我还用了一个比较原始的约定每个文件头部注释里写上最后更新时间和变更原因。这不算什么高科技但在多项目复用时特别好用——你能判断项目里这份模板是不是旧版以及它当初为什么被改过。6. 实测跑了几周后的避坑与优化心得模板搭好之后我在自己的几个项目里跑了大概一个多月中间迭代了好几次。这部分是我最想跟你分享的因为只看配置示例你根本意识不到哪些地方会出问题。6.1 别让 CLAUDE.md 变成愿望清单我第一次把模板铺到一个老项目时恨不得把所有的代码规范、历史包袱、禁忌事项全写进去。结果文件超过了三百行AI 的行为反而变得很奇怪它把注意力过度集中在那些边角约束上不敢动手改代码每次都先问是否允许修改 XXX。后来我把 CLAUDE.md 压缩到一百行以内只保留最高频的指令其余细节都放进 docs 目录让它按需读取效果立竿见影。现在我的标准是如果一个规则在超过一半的会话里用不上它就不该出现在 CLAUDE.md 里。宁可多写几条指向文档的引用也不要全堆在入口文件里。6.2 命令模板内容应该精简 指向而不是把逻辑全塞进去我犯过一个错误把 review 需要检查的所有维度、示例、输出格式全部写进命令模板结果命令执行时非常冗长而且模型容易在细节里迷失反而漏掉关键问题。后来我把命令模板分成三层目标、约束、输出格式具体细节尽量用短语概括而不是长句描述。另外一个值得注意的教训是命令模板里最好明确指示 Claude Code 先去执行某个命令拿真实数据而不是让它凭上下文瞎猜。比如生成变更日志时明确写上先运行 git log比含糊的看看最近的改动效果稳定得多。6.3 上下文膨胀问题模板与 compact 的配合跑了一段时间之后我注意到一个问题模板虽然提供了上下文但会话时间长了之后上下文窗口被对话历史撑满早期的项目约束信息会被遗忘AI 又开始出现忘记项目约定的行为。Claude Code 有/compact命令可以把当前对话压缩成摘要但这个摘要不一定能完整保留 CLAUDE.md 里的所有细节。我的经验是把 CLAUDE.md 的关键约束在对话早期就消耗掉——也就是在开始工作前先让它输出一下它对项目规范的理解确认它已经接收到这些信息。这相当于在上下文里做一次显式的复述压缩丢失信息的概率会小很多。如果你发现它漏掉了某条约束直接在对话里补一句记住约束禁止修改 dist 目录比重新跑一个命令更直接。6.4 下一步我还想往里加的东西这套模板目前还在迭代中。最近我在考虑把 MCP 服务器的配置也纳入模板体系因为不同项目用的 MCP 工具不一样与其每次手动配不如在模板里预置一份mcp.json的示例。另外我在考虑做一个团队共享的版本把「需求解析模板」和「Issue 自动分类模板」也纳入进来方便前端、后端、算法几个方向的同事直接用一套范式。最后说一个我这一个多月最深的感觉模板不是一次搭完就结束的东西它是跟着你的使用习惯一起演化的。你越是高频使用 Claude Code越能发现哪些环节值得模板化哪些模板里的内容是多余的。这个迭代过程本身比最终那套模板文件更有价值。