1. 为什么模板化是Claude Code使用的分水岭
1.1 从"每次都重新说一遍"到"结构即默认行为"
用Claude Code一段时间的人,大概率都经历过这么个阶段:每开一个新项目,第一件事就是花十几二十分钟把上下文灌进去——"咱们这个项目是Python写的,用FastAPI,数据库是PostgreSQL,测试必须用pytest,代码风格遵循Black,不要随便改依赖版本,提交信息要按Conventional Commits写……"。说的时候是清楚了,可第二天换个终端继续干活,它又忘了。尤其是多项目并行的时候,来回切换上下文语境,AI一会儿把A项目的目录结构套到B项目上,一会儿又用B项目的测试框架跑A项目的用例,心累得很。
后来我想明白一件事:Claude Code这种东西,本质是一个"上下文驱动的执行引擎",它缺的不是能力,是稳定可靠的上下文来源。你把规则放在对话里,规则就是一次性的;你把规则放在文件里,规则就成了项目的默认行为。这正是模板化能解决的核心问题——把那些反复口头强调的东西,固化成结构、文件和约定,让AI在没有你絮叨的情况下,自己做出符合预期的行为。
所以我开始系统地整理自己的Claude Code模板配置,也就是现在的 claude-code-templates 这套方案。它不是某个单一文件,而是由CLAUDE.md记忆文件、斜杠命令、Hook规则、目录脚手架共同组成的一套"项目初始化资产"。做完之后,新项目从clone到进入理想工作流,基本五分钟就能搞定,而且团队里其他人拉下来同一套模板,行为表现也是接近的。
1.2 模板到底要包含哪几层东西
要理解模板方案,先得理解Claude Code的配置体系是分层的。我的理解是四个层次,各有各的管辖区:
- 用户级配置(~/.claude/):包括用户级CLAUDE.md、全局斜杠命令、全局Hook,作用于所有项目。
- 工作区级配置(.claude/ 在工作区根目录):作用于整个多仓库工作区,适合放跨仓库的通用约定。
- 项目级配置(项目根目录的CLAUDE.md和 .claude/):作用于单个仓库,放这个项目的专属规则。
- 会话级指令:你在对话里补充的临时要求,优先级最高但最不稳定。
一个常见的误区是把所有东西都塞进项目级CLAUDE.md,结果就是一个文件几千行,AI每次读上下文都要吃掉几千token,反而影响了主要任务。模板化的核心其实是"职责划分+就近生效":近的管近的,远的管远的,各层只放自己该管的内容。
这一节先搭认知框架,下面我用完整踩过的路径来讲每一层的具体设计和写法。
2. 三层CLAUDE.md的职责划分:工作区、项目、用户
2.1 用户级:个人偏好与全局纪律
用户级CLAUDE.md放在~/.claude/CLAUDE.md,它的特点是"不管你在哪个项目里,它都会生效"。这个东西最适合放什么?我个人的经验是放三样东西:
第一,跨项目通用的编码习惯。比如"变量命名要有意义,不允许出现a、b、tmp这种无法理解的缩写""所有修改变动必须同步更新相关测试""字符串拼接用f-string而不是+号"。这些规则对Python、JavaScript、Shell都适用,放在用户级就不用每个项目的CLAUDE.md里重复写。
第二,对你个人工作方式的约束。比如"回答技术问题时先给结论再展开""遇到不确定的需求先列出假设清单再动手""只使用项目环境中已经安装的依赖,不要擅自安装新包"。这其实是在给AI"立人设",让它配合你的协作习惯。
第三,安全底线。这是我的血泪教训——有段时间AI动不动就给我执行git push --force,或者在我没允许的情况下修改数据库连接配置。现在我会在用户级CLAUDE.md里明确写:涉及git push、rm、DROP TABLE、生产环境操作之前必须停止并向我确认。
有人可能担心用户级配置会污染不同项目的专属逻辑。这种担心合理,解决办法是:用户级只写"纪律",不写"业务"。纪律是通用的,业务是专属的,一混就容易出错。比如你用户级写了"所有时间字段一律用UTC存储",那没问题;你要是写了"本项目数据库密码是xxx",那这个配置就彻底没法在不同项目间复用了。
2.2 项目级:仓库的红线与上下文压缩
项目级CLAUDE.md放在仓库根目录,这是大家最先接触也最容易用错的一层。它的正确打开方式有两个关键词:红线、压缩。
先说红线。每个项目都有一些"天条",比如"这个模块是生成代码,禁止手改""数据库迁移只能由migration_runner脚本执行""对外接口的返回格式必须符合v2协议"。这些规则写进项目级CLAUDE.md,AI就不会越界。之前我们有个项目,AI为了"快速修复"一个类型问题,绕过了统一的数据访问层,直接写原生SQL去查表,差点把生产数据搞乱。原因就是你根本没告诉过它这个项目的红线在哪。AI没有道德直觉,它只有规则意识——你不写,它就按自己理解的"最优解"来,而这个最优解往往不是你想要的。
再说压缩。AI能携带的上下文总量有限,CLAUDE.md不是越长越好。我的做法是:项目级CLAUDE.md保持在200行以内,只写目录结构摘要、技术栈清单、构建与测试命令、红线规则、代码风格要点这五类。像"为什么这么设计""某模块的历史包袱"这类细节,放到/docs或者代码注释里,并告诉AI"需要时自己去翻/docs/AI_CONTEXT.md"。这叫上下文外置。
我踩过的坑是:一开始把项目背景、架构演进历史全部堆进CLAUDE.md,结果每次对话光读记忆文件就消耗了差不多3000 token,AI的半条命都没了。建议大家可以做一个实验,把CLAUDE.md压到原来的一半,观察一下回复质量,很多时候不仅没变差,反而因为上下文干净而变好了。想到这里我突然意识到,AI其实跟人一样,规则太多等于没有规则。
2.3 工作区级:多仓库协作的粘合剂
工作区级CLAUDE.md是很多人忽略但实际非常有价值的一层。它的作用范围是整个工作区/多仓库根目录。什么时候需要用?最典型的是微服务项目、前后端分离的多仓库项目。
比如你工作区下有frontend、backend、shared-libs三个仓库,经常需要AI跨仓库改代码。如果只在每个仓库放项目级CLAUDE.md,AI对"整体架构是什么、三个仓库之间怎么通信、改动需要同步哪些仓库"是缺乏全局认知的。工作区级CLAUDE.md正好补这一段:可以写"frontend调用backend的/api/v1接口,改动接口必须同时更新OpenAPI文档和前端对应类型定义""shared-libs是被两个业务仓库依赖的公共库,任何对外API变更必须先提出变更说明"。
实际效果上,工作区级配置相当于给AI一张"地图",让它清楚每个仓库的边界和关联。项目级配置负责"地方法规",用户级配置负责"宪法",三个层级的优先级和覆盖范围互不冲突。曾经处理过一个跨仓库问题:后端把接口字段做了重命名,但前端类型定义没跟着更新,整个联调环境直接崩了。后来我在工作区级CLAUDE.md里强制加了"接口变更必须同步前后端类型"这一条,这类问题才彻底绝迹。
2.4 一个可以抄的CLAUDE.md骨架
很多人看了一堆理论还是不知道怎么落笔,我直接放一个经过几个项目验证的CLAUDE.md骨架(项目级),你们按需删改:
# 项目概览 该仓库是xxx服务的核心实现,基于FastAPI+PostgreSQL,部署环境分为staging和production。 # 技术栈与关键路径 - 框架: FastAPI 0.1xx, 使用 app/main.py 作为入口 - ORM: SQLAlchemy 2.x, 所有查询必须经过 repository 层, 禁止直接使用 session.execute 写裸SQL - 测试: pytest, 测试文件与源码目录一一对应 - 格式化: Ruff, format与lint配置在 pyproject.toml # 常用命令 - 本地启动: uv run uvicorn app.main:app --reload - 运行测试: uv run pytest -x -q - lint检查: uv run ruff check . # 红线规则 - 禁止修改 migration/ 下的已发布迁移; 新变更必须新建迁移文件 - 外部API返回结构必须保持 {code, message, data} 三层结构 - 凡是涉及用户隐私字段的改动,必须经过评审标注 [PRIVACY] # 代码风格与提交规范 - 提交信息使用 Conventional Commits, 例如 feat(api): add pagination - 新代码必须附带对应单测, 覆盖率不得低于新增代码的80%写到这里再补充一个经验:CLAUDE.md写完之后别急着用,先让它"自我问答"。最简单的验证方式就是你直接问AI:"根据你的记忆文件,这个项目的技术栈是什么?红线有哪些?"如果它答得上来,说明文件结构是有效信息;如果它答得含含糊糊,说明你的文件写成了摆设,需要重写。这种验证方式成本极低,但能避免你带着一份根本不被AI理解的配置跑好几周。
3. 斜杠命令模板:把高频操作固化成固定动作
3.1 命令模板的文件结构与格式
CLAUDE.md管的是"AI怎么想",斜杠命令(Slash Command)管的是"AI怎么干活"。斜杠命令本质上是把一段完整的、可复用的指令做成一个固定入口,你在对话里输入/commit、/review、/refactor,AI就会执行对应的模板指令。
命令文件的格式不复杂,本质上是一个带YAML frontmatter的Markdown文件,放在 .claude/commands/ 目录下。文件名就是命令名,frontmatter里写描述和参数提示,正文里写具体执行步骤和逻辑。最核心的机制是变量占位符:$ARGUMENTS代表用户输入斜杠命令时附带的所有参数,$1、$2代表第一个、第二个参数。
我个人的项目里,命令模板被放在 .claude/commands/ 下跟随仓库走,和CLAUDE.md分开管理。为什么要分开?因为斜杠命令往往带着复杂的执行逻辑和脚本操作,单独管理能避免把记忆文件变得臃肿,也方便单独做版本控制。想象一下,如果你把五个命令模板全塞进CLAUDE.md,那AI每次读上下文都要多出几千token,而这些内容只在触发命令时才真正需要。
一个最简单的命令模板长这样:
--- description: 按规范生成 commit message argument-hint: [type] <简要描述> --- 请根据当前 git diff 内容生成一个符合 Conventional Commits 规范的提交信息。 要求: - type 从 feat/fix/docs/refactor/test/chore 中选择,若用户提供了 $1 则优先使用 $1 - 提交信息不超过80个字符 - 根据 diff 的关键改动点生成描述 - 不得包含任何 AI 相关字样或多余解释3.2 我日常必配的六个命令模板
用好斜杠命令的关键在于"什么样的高频动作值得固化成命令"。我列一下自己一直在用的六个,每个都有明确的场景:
- /review:代码审查。读取git diff,按"正确性、安全性、性能、可维护性"四个维度输出审查意见,并标出每个问题的严重级别。以前我都是手动复制diff丢给AI让它看,现在一条命令搞定。
- /fix:修复指定问题。接收问题描述或报错信息,定位根因,给出修复方案,并要求它先说明根因再改代码,防止AI上来就一顿乱改。
- /refactor:小范围重构。限定改动边界,要求保持接口兼容,并自动运行测试验证。
- /test:为本次改动补充测试。自动识别改动函数,生成对应的pytest用例,标记缺失的mock和断言。
- /commit:生成符合规范的提交信息,并追问是否需要我确认后执行git commit。
- /explain:解释一段代码/一个目录结构,输出"这段代码的作用、核心流程、潜在风险"三段式说明。
这六个命令基本覆盖了我日常80%的重复性操作。它们的共同特点是:有明确的输入形态、有固定的输出格式、有明确的质量要求。如果你的某个操作流程里这三个要素缺了一个,说明它还不适合固化成命令,先靠对话解决更灵活。比如"帮我看看为什么这个性能有瓶颈"这类开放性问题,就不适合做成命令——因为它没有清晰的输入边界。
3.3 参数透传、子命令与占位符技巧
命令模板用好之后,我发现两个进阶技巧值得分享。
第一个是参数透传。很多命令不止一个参数,比如/review可以要求"只审查api模块、忽略测试文件",/test可以指定"只给某几个函数生成测试"。我的做法是利用$ARGUMENTS做自然语言解析,模板里写上"如果用户通过$ARGUMENTS注明了范围,请优先遵循;否则自行从diff判断"。这样用户输入/review api 时,AI会自动把api作为审查范围约束。这个设计比严格的$1/$2参数化要灵活得多,因为自然语言能承载的信息量远大于位置参数。
第二种做法是让命令支持"无参数默认行为"。很多用户输入/review就回车,没带任何参数。模板里就应该写明:"如果$ARGUMENTS为空,默认审查所有未提交的改动;如果带了路径参数,则只审查该路径下的改动。" 这样命令既能快速用,也能精确用,覆盖面广得多。
第二个是命令内部的子任务拆分。好的命令模板不应该是一段"让AI自己发挥"的散文,而应该是一个带检查点的流程。比如/review的模板我写的是:
1. 运行 git diff --stat 确认改动范围 2. 读取改动对应的完整上下文文件 3. 按 正确性/安全性/性能/可维护性 四个维度逐一审查 4. 输出审查结果,每个问题标注 严重/中等/建议 三级 5. 最后给出一个总体的改动健康度评分,满分10分为什么要把流程写出来?因为AI默认不会主动做"确认修改范围"和"读取完整上下文"这两件事,你不写,它就基于你对话里已有的信息直接输出,经常漏掉关键上下文。流程化的模板实际上是强迫AI按人类审查的步骤来,质量会稳定很多。曾有同事问我为什么他生成的review总是不准,我让他打开模板一看,就写了三行"请审查代码改动并输出意见",这种模板等于没有模板。
4. Hook模板:让质量门禁不再靠口头提醒
4.1 PreToolUse:拦住危险操作的守门员
如果说CLAUDE.md是"告诉AI规则",那Hook就是"在规则被违反之前拦截它"。Hook是Claude Code里真正能在执行层面做安全控制的机制,它在AI调用工具之前或之后触发,让你能用脚本介入。
我用得最多的是PreToolUse事件——也就是AI准备调用某个工具的时候,先跑你的脚本确认安全。脚本返回一个JSON结构,里面如果带"hookSpecificOutput"字段,就可以把工具调用拦下来,或者替换参数。
我拿一个真实事故说明为什么必须要做这层拦截。某个凌晨,我让AI做一个批量任务,它不知怎么就脑抽开始执行git push --force,直接把同事的分支覆盖了。虽然没有造成大事故,但那次之后我再也不敢只靠对话里的"不要乱push"来保平安。现在的配置是:
{ "hooks": [ { "matcher": "git push", "hooks": [ { "type": "pre_tool_use", "command": "node ~/.claude/hooks/guard-git-push.js" } ] } ] }脚本逻辑并不复杂:检查push命令里是否包含force或者upstream参数,如果包含就返回拒绝执行;同时把即将执行的命令和触发它的对话上下文记录到日志文件,方便事后排查。有了这层物理拦截,AI再怎么糊涂也推不掉不该推的代码。
4.2 Stop:提交信息与变更摘要的强制生成
PreToolUse是"拦",Stop事件则是"补"。Stop事件在AI准备结束一段响应之前触发,非常适合强制它执行收尾动作。
我做的第一个Stop Hook是"提交信息补全"。很多团队的规范是commit message必须包含issue编号和改动摘要,但AI经常忘。所以我在Stop阶段加了一个检查:如果当前对话中AI说自己完成了改动,就让一个脚本检查git status与git diff,如果发现存在未提交的改动且当前的响应里没有对应的commit message,就输出一条提示:"检测到改动尚未产生提交信息,请先执行/commit命令。"
这个机制看起来简单,实际价值很大。它等于把"质量门禁"从人的记忆中搬到了工具链里,AI想糊弄过去都不行。还有一次我直接让Stop hook自动生成一份改动摘要文本并写入CHANGELOG_pending.md,方便发布时统一整理。效果是可以的,不过要注意控制生成摘要的时机,别每次对话都写一份,不然文件会乱。我现在的配置是"仅在git status有改动时才触发",这样既不会漏核心改动,也不会制造噪音。
4.3 一套可供参考的最小Hook集合
如果你刚开始接Hook,不需要搞得很复杂。我推荐从一个最小集合开始,先把安全底线兜住,再逐渐加码:
| 事件 | 匹配对象 | 脚本职责 | 建议策略 |
|---|---|---|---|
| PreToolUse | git push | 禁止force/upstream,记录命令日志 | 拦截高危参数 |
| PreToolUse | rm, mv, sed | 检查删除目标是否在项目目录内且非脚本生成目录 | 拦截误删 |
| PreToolUse | Bash(通用) | 命令包含curl/wget时先下载白名单校验 | 提示确认 |
| Stop | 任意结束 | 检测未提交改动并提示生成commit信息 | 温和提醒 |
| PostToolUse | Bash | 将执行过的命令追加到execution_history.log中 | 审计留痕 |
这套Hook集合我曾经在内部项目上跑了一个季度,最大的感受是:Hook管得住"硬操作",比如推代码、删文件、跑高危命令;但管不住"软问题",比如代码逻辑本身写得烂、架构设计不合理。软问题还是得靠CLAUDE.md+斜杠命令模板+人工审查去约束。所以正确的姿态是:CLAUDE.md负责规则,斜杠命令负责流程,Hook负责强制执行,三者配合而不是互相替代。
要知道,预设Hook脚本的具体行为在不同版本之间可能存在差异,但设计思路是通用的:先记录日志,再逐步加上拦截逻辑,最后才考虑自动修正。这个渐进思路能帮你避免一上来就把AI的正常操作卡死。
5. 模板仓库的设计、落地与演进
5.1 一个可以直接拉下来改的目录结构
前面几节讲的概念比较多,现在把它们汇成一个具体的模板仓库结构。下面是我当前使用的 claude-code-templates 目录骨架:
claude-code-templates/ ├── CLAUDE.md # 模板总说明,读起来像"使用手册" ├── user/ # 用户级配置 → 复制到 ~/.claude/ │ ├── CLAUDE.md │ └── commands/ │ ├── commit.md │ ├── explain.md │ └── review.md ├── workspace/ # 工作区级配置 → 复制到工作区根目录 .claude/ │ ├── CLAUDE.md │ └── commands/ │ └── cross-repo-sync.md ├── project/ # 项目级模板 → 按需复制到每个仓库 │ ├── CLAUDE.md │ ├── commands/ │ │ ├── fix.md │ │ ├── refactor.md │ │ └── test.md │ └── hooks/ # 项目级Hook脚本 │ ├── guard-git-push.js │ └── check-license.js ├── hooks/ # 通用Hook脚本,软链或复制到 ~/.claude/hooks/ │ ├── guard-git-push.js │ ├── guard-dangerous-rm.js │ ├── changelog-summary.js │ └── execution-audit.js └── settings.example.json # 各层settings.json的样例为什么要用这种分层目录?因为它跟Claude Code的配置生效机制一一对应,复制成本最低。你拉下来之后,把user目录内容放到~/.claude/,把project目录的内容放到具体的项目根目录,就能立刻生效。这种目录结构也方便团队共享——把仓库放到公司内网Git,拉下来之后每个人都能按同一套模板初始化自己的开发环境。
5.2 命名规范、变量管理与版本管理的细节
模板类资产最怕的就是"漂移"——不同项目的CLAUDE.md越改越不一样,最后根本没法统一。所以我给模板定了三条规矩,算是用踩坑换来的:
第一,模板正文里不允许出现真实业务信息。所有具体的项目名、数据库连接、API路径一律用占位符表示,比如{{PROJECT_NAME}}、{{DB_URL}}、{{API_BASE}}。初始化新项目时,全局替换一遍占位符就行。这样模板仓库本身不会泄密,也能被不同项目复用。
第二,模板必须标注适用场景和变更记录。CLAUDE.md文件头部放一个区块,写明"本模板适用:Python后端服务;最近变更:2025-06 增加Hook安全拦截规则"。这个习惯让模板演进时可追溯,出了诡异问题也能快速定位是哪次改动引入的。
第三,模板仓库用语义化版本管理。新增一个命令文件、调整Hook逻辑、修改CLAUDE.md结构,分别对应minor、patch、major的递增。团队内部用git tag区分版本,每个项目记录当前使用的模板版本号。这样当模板更新时,你能批量评估哪些项目需要同步升级。版本管理这块不能偷懒——没有版本号的模板仓库,早晚会变成谁都不敢动的烂摊子。
5.3 模板初始化的一条龙脚本思路
光有静态文件还不够爽,我的最终形态是用一个初始化脚本把整个流程自动化。脚本的逻辑很简单:把用户级配置复制到~/.claude/,在指定目录创建项目级CLAUDE.md、commands、hooks,用交互式问答填充占位符,最后运行一个自检命令验证AI能正确读取配置。
伪代码大概是这样的:
#!/bin/bash # init-claude-templates.sh # 1. 备份现有配置 cp -r ~/.claude ~/.claude.backup.$(date +%Y%m%d%H%M%S) # 2. 复制用户级模板 cp -r templates/user/* ~/.claude/ # 3. 交互式收集项目信息 echo "项目名称:" read PROJECT_NAME echo "技术栈 (python/js/go):" read STACK # 4. 渲染项目级模板 sed -i "s/{{PROJECT_NAME}}/$PROJECT_NAME/" templates/project/CLAUDE.md sed -i "s/{{STACK}}/$STACK/" templates/project/CLAUDE.md # 5. 复制到目标项目目录 cp -r templates/project "$TARGET_PROJECT_DIR/.claude/" echo "完成。请进入项目后验证配置。"这条脚本我第一次跑通时,效果确实有种"工业感"——之前要折腾十几分钟的配置过程,变成一条命令三秒搞定。而且因为模板统一了,团队里每个人的行为基线一致,跨人协作时上下文成本明显降低。当然,脚本本身不复杂,你也可以根据自己的业务场景扩展,比如自动创建.gitignore、初始化README、生成docs/AI_CONTEXT.md等。
5.4 模板演进中的几个坑
最后聊聊我用这套模板过程中真正踩过、也真的建议你避开的几个坑。
第一个坑是"把模板当成宝典来写"。模板写得越详细,AI越容易被海量规则淹没,导致关键规则被稀释。我的经验是每个层级的CLAUDE.md都控制在合理篇幅内,宁可少写三条不重要的,也要保证核心红线足够醒目。我在一个早期版本里写了四十条编码规范,结果AI经常忽略最关键的那三条,后来精简到十条,反而准确率上来了。
第二个坑是"只建不用"。很多人建好模板仓库就当成任务完成,后面再也不维护。事实上模板是需要跟实际项目持续对账的——每次你发现AI做出了不理想的决策,都应该复盘:是模板没写这条规则?还是写了但排序权重太低?然后下意识地更新模板。我几乎每周都会因为某个翻车案例,给模板仓库补一条规则或调整一段描述。
第三个坑是"Hook配置过于激进"。拦截规则写得过死,会导致AI的正常操作频繁被打断,反而严重影响工作效率。我的建议是Hook先做日志记录,跑两周看看误伤率,再逐步收紧到真正需要拦截的边界。比如最初我把所有npm install都拦下来确认,结果每次跑测试都要弹确认,烦得很;后来改成只拦截"非package.json声明的全局安装",误伤率瞬间降下来。
第四个坑是"混淆了记忆文件与上下文的关系"。CLAUDE.md是给AI读的规则,不是文档中心。很多团队把CLAUDE.md写成几千行的百科全书,其实是对"AI为什么表现不好"这个问题的错误归因。表现不好首先要排查上下文是不是干净,上下文干净了再考虑规则够不够,顺序不能反。
一些实站体会
写到这里,基本上把我从"每次对话都要重新教学"到"一套模板跑遍所有项目"的全过程都梳理了一遍。现在我个人开新项目的流程已经固定成三步:拉取claude-code-templates,跑一遍初始化脚本,进去问一句"根据你的记忆文件,我该从哪开始"。剩下的对话质量,基本就是这套模板质量的直接反馈,互动多了之后你会发现,模板维护得好,AI是真的能替你省掉大量重复性工作。
如果你准备动手搭自己的模板,我建议别追求一步到位。先建一个最小集合:一层CLAUDE.md加两个斜杠命令加一个PreToolUse安全Hook,跑两个星期。在这期间把"AI每次表现不好的时候,是哪里没管住"记下来,然后迭代进模板。模板这种东西,最忌讳的就是闭门造车,它是靠真实项目的摩擦喂出来的。我的这套结构能给你当起点,但最终的形态,一定是你自己踩过坑之后改出来的那版。相信我,当你在新项目里第一次说出"帮我按咱们的规范初始化一下"然后事情真的按预期推进时,你会觉得前面那些整理配置的时间都值了。