新项目初始化完,我打开终端,把 claude-code 叫出来,准备让它接着上个会话继续干活。结果它问我"这个项目的技术栈是什么""测试命令是什么""代码风格有要求吗"——这些问题我在上个会话里明明已经回答过三遍。那一刻我意识到,问题不在模型,问题在我:我把一个本应稳定的上下文环境,当成了每次都要重新对齐的临时对话。
后来我把项目里反复要交代的事情整理成了一套模板,也就是现在这套claude-code-templates:小到命令习惯、大到代码审查流程,通通固定成模板文件。这套东西适合谁?适合已经在 CLI 编程助手里吃过"模型失忆"苦头的人,也适合想把 AI 辅助编码从"可用"推到"可复用"的团队。下面我把这套模板的搭建过程、设计思路和踩坑记录完整展开,希望能给你一个可以直接照抄的起点。
1. 模板到底解决了什么问题:从"每次重新对齐"到"一次配置处处生效"
1.1 Claude Code 的"记忆文件"机制
首先要搞清楚一件事:Claude Code 本身并不具备跨会话的稳定记忆。每一次启动,它都像一个刚入职、脑子一片空白但能力很强的开发助手。它能知道你当前目录下有哪些文件,也能通过对话理解你刚说的话,但如果没有人告诉它"这个项目用什么语言、测试怎么跑、提交信息要写成什么格式",它就只能现场猜。猜对了是运气,猜错了就是返工。
CLAUDE.md 就是干这个的。在项目根目录放一个 CLAUDE.md,相当于给这个助手写了一份开机必读的员工手册;在用户目录放一个全局的 CLAUDE.md,则相当于新员工入职培训的通用部分——你个人的命令偏好、常用脚本位置、不希望模型做的事,都可以写在那里。Claude Code 在每次会话开始时会自动读取这些内容,把其中的约定当作后续工作的默认前提。
我用一个生活化的类比:CLAUDE.md 之于 Claude Code,就像新手导航里预设的"家和公司地址"。没有预设的时候,每次上车都要重新输入目的地、重新选路线;有了预设,它自己就知道先上哪条高速、再拐哪个路口。模板化的第一层意义,就是把这个预设动作从"每次手动做"变成"自动加载"。
由于不同版本的读取顺序可能有细微差别,我建议你只依赖两条铁律:项目根目录的 CLAUDE.md 只影响当前项目,用户目录的 CLAUDE.md 影响你所有项目。这两份可以并存,覆盖面不同,互不替代。千万不要把团队约定写进用户目录,否则你同事拉走你的配置,看到的全是你的私人习惯。
1.2 没有模板的裸奔状态:三类高频浪费
我在没有模板之前,每个会话都在重复三类无效劳动,后来统计了一下,效率损失远比我预想的大。
第一类是环境性问题。模型不知道包管理器是 npm 还是 pnpm,不知道 Python 版本是 3.11 还是 3.9,不知道数据库是本地 Docker 还是远程实例。这些信息每次对话都要重新交代一遍,哪怕只是在会话中间插入一个新问题,前面的上下文也可能被遗忘或覆盖。
第二类是约定性问题。比如项目里要求 commit message 遵循 Conventional Commits,代码里 import 顺序有严格约定,或者后端接口统一返回{ code, data, msg }结构。模型如果没有在上下文里看到这些约定,它会按它训练数据里的大众风格来写——风格没错,但不符合你的项目。
第三类是操作习惯问题。有些人喜欢让模型先给方案再动手,有些人希望它直接用脚本执行;有些人要求每改动一个文件就停下来等确认,有些人希望连续把一串任务做完。这些偏好如果不写进模板,就只能靠"幸运":有时候模型记得住,有时候它就是放飞自我。
| 裸奔状态 | 模板化状态 |
|---|---|
| 每个会话重复描述技术栈 | 自动加载 |
| 模型按通用风格写代码 | 按项目约定输出 |
| 高风险命令裸奔执行 | 权限清单提前声明 |
| 新人/新会话无法接手 | 一套模板带走全部上下文 |
1.3 模板化的隐藏收益:可评审、可迁移、可交接
这一点很少人提,但我认为是模板化最大的价值。把上下文从对话里抽出来变成文件之后,它就具备了三个普通对话不具备的特性。
可评审:项目约定能不能过审,直接看 CLAUDE.md 里的内容就行。以前你说"模型上次写代码风格不对",没人能证明;现在模板里白纸黑字写着"函数注释必须写明复杂度",模型没遵守就是模型的问题,模板写错了就是模板的问题,责任边界很清楚。
可迁移:换电脑、加新人、给另一个仓库用同一套规范,复制目录就行,不用重新调教。我把 web-app 和 python-lib 两套目录模板分开管理,新项目直接 cp 对应模板,十分钟内就能让模型进入状态。
可交接:我休假回来,或者同事接手我的项目,看一遍模板——尤其是我在 commands 里写的那些 slash 命令——就能完全复现我平时的工作流。对话是易逝的,模板是沉淀下来的资产。
2. 模板仓库的结构与设计:别把提示词堆进一个文件
2.1 claude-code-templates 的整体布局
我在第一次做模板的时候走过弯路:把所有要求写进一个超长 CLAUDE.md,结果又臭又长,模型反而抓不住重点。后来我调整成了分层结构,坚决不把提示词堆在一个文件里。
claude-code-templates/ ├── README.md ├── _base/ # 通用层:所有项目都能用的底稿 │ ├── CLAUDE.md │ ├── settings.json │ └── commands/ │ ├── plan.md # 需求拆解 │ ├── review.md # 代码审查 │ └── commit.md # 规范提交 ├── web-app/ # 场景层:前端/后端项目专属约定 │ ├── CLAUDE.md │ └── commands/ │ ├── add-api.md │ └── fix-style.md ├── python-lib/ # 场景层:Python 库项目专属约定 │ ├── CLAUDE.md │ └── commands/ │ └── lint-fix.md └── scripts/ ├── install.sh # 一键安装到新项目 └── validate.sh # 检查模板是否被正确加载分层的理由很直接:通用层解决"你作为一个开发者的稳定偏好",场景层解决"具体技术栈的项目必须遵守的约束"。两层叠加,模型拿到的是一份"说话有重点"的上下文,而不是一锅乱炖。如果你只有一个文件,那这个文件很快就会变成大杂烩:个人习惯、团队规范、技术栈说明、临时调试指令搅在一起,模型每次读上下文都要自己分辨哪条更重要。
2.2 CLAUDE.md 模板的分块逻辑
我写的 CLAUDE.md 模板永远遵循一个原则:每个模块只解决一类问题。一个典型的_base/CLAUDE.md长这样(节选):
# 项目级通用约定 ## 技术栈 - 优先使用项目已有的依赖,不要随意引入新库 - Python 版本以 .python-version 为准 ## 常用命令 - 安装依赖:pnpm install - 运行测试:pnpm test - 单测:pnpm test -- --runInBand - 代码检查:pnpm lint ## 代码风格 - 提交信息使用 Conventional Commits 格式 - 组件文件命名使用 PascalCase,工具函数使用 camelCase - 不要修改与当前任务无关的文件 ## 禁止事项 - 不要直接改动 lockfile,除非明确要求 - 不要在代码里留下 TODO/FIXME 标记 - 不要用全局安装的 CLI,统一走项目脚本分块背后对应的是真实失误:技术栈块解决"模型引入不存在的依赖",常用命令块解决"模型用错包管理器",代码风格块解决"输出风格和仓库不一致",禁止事项块解决"模型自作主张改了一堆无关文件"。每个模块都有明确的存在理由,而不是为了凑字数。
我见过很多人的 CLAUDE.md 写得像散文,开头是"你是一个优秀的工程师",中间来一段"请注意代码质量",最后加一句"确保代码可维护"。这种内容模型不会反对,但也很难执行。真正有效的 CLAUDE.md 是具体到"哪个命令、哪种命名、哪个不许做"的清单式约定。语言越接近项目本身的表达方式,模型执行得越准确。
2.3 自定义命令模板:真正把"流程"固化成可调用动作
CLAUDE.md 是静态约束,custom slash commands 则是把一套流程封装成可复用的动作。在.claude/commands/目录下放一个 Markdown 文件,文件名就是触发命令,比如review.md对应/review。命令文件正文里的内容,就是模型执行这个命令时要遵循的流程。
我最早的 review 命令模板:
--- description: 执行一次符合项目规范的代码审查 --- 流程: 1. 先运行 git diff --stat 和 git log --oneline -5,了解改动范围 2. 重点检查:错误处理、边界条件、敏感信息泄露 3. 对每个问题按阻塞/建议/可选分级 4. 最后输出一份 Markdown 审查报告,按文件分列 约束: - 不要直接修改文件,只输出审查意见 - 所有结论必须引用具体代码行,禁止空泛评价触发/review后,模型会严格按照流程执行,而不是凭心情自由发挥。这里注意一点,description这类元信息字段在不同版本里支持程度不一样,最可靠的做法是把流程直接写在正文里。CLAUDE.md 是背景知识,命令是"点餐"——你不点它就不上,点了就必须按菜单走。这样既不会让背景知识占用太多上下文,又能保证流程稳定。
2.4 settings.json 与 hooks:权限和钩子的边界
模板的第三部分是 settings.json,它负责管理权限和钩子。权限声明了"哪些命令可以直接执行、哪些需要确认、哪些直接拒绝",而 hooks 可以在特定事件前后插入自动化检查。
例如我的_base/settings.json里会有类似这样的结构:
{ "permissions": { "allow": [ "git status", "git diff", "pnpm test" ], "deny": [ "rm -rf *", "git push --force" ] }, "hooks": [ { "event": "PostToolUse", "matcher": "这里填你要匹配的工具名", "command": "node scripts/check-commit-msg.js" } ] }不同版本的 hooks 配置结构会有差异,具体 matcher 请以你当前版本的官方文档为准。但思想是一致的:权限层负责"能做什么,不能做什么",hooks 层负责"做完之后必须检查什么"。我在这里用一个提交信息检查的 hooks 做示例,它保证每次提交动作发生之后,自动校验提交信息格式,不合规就失败。
权限和钩子的价值,在于把"模板说话"升级成"模板执行"。不是模型"应该"遵守约定,而是系统层面"必须"遵守约定。我在搭建初期只做了 CLAUDE.md,发现模型偶尔还是会漏,后来补齐 settings.json,违规率才真正降下来。
3. 从零搭一套可落地的模板:四步实操
3.1 第一步:先做上下文盘点
先说方法:把最近一两周和 Claude Code 的对话记录翻出来,统计哪些信息是你反复在说的。我自己的做法是直接翻终端历史,把每一条"我又得重新说一遍"的话记下来。记下来之后你会很震惊:原来每天有三分之一的时间花在了帮模型补齐背景上。
我当时的盘点结果:
| 高频信息 | 出现频率 | 应该放哪一层 |
|---|---|---|
| 项目技术栈与目录结构 | 每个新会话必提 | CLAUDE.md |
| 测试命令 | 几乎每个任务都涉及 | CLAUDE.md |
| 提交信息格式 | 每次提交都要纠正 | CLAUDE.md + commit 命令 |
| 代码审查 checklist | 每次审查都要重新说 | commands/review.md |
| 危险操作边界 | 偶尔被误触发 | settings.json |
这个方法的关键在于:只收录高频、高代价的信息。低频信息写进模板反而增加噪音;高代价信息哪怕只发生过一次,也要写进去。比如"不要用 npm 强制覆盖依赖"这种教训,可能一年只遇到一次,但遇到就是大事故,写进"禁止事项"之后,我再也没犯过。
3.2 第二步:写最小可用版本的 CLAUDE.md
模板不需要一步到位。我建议先写精简版,不要一上来就追求齐全。我第一个正经可用的 CLAUDE.md 只有十几行:
# 项目约定 - 技术栈:FastAPI + SQLAlchemy + PostgreSQL,测试用 pytest - 启动服务:uvicorn app.main:app --reload - 运行测试:pytest -x - 提交信息:Conventional Commits - 禁止:不要为测试写 mock 数据库,直接使用测试容器足够短,但覆盖了最高频的四类上下文。写完之后跑一个会话,验证模型能不能回答出"这个项目的测试命令是什么"——能,就说明 CLAUDE.md 生效了。之后再按上面说的分块逻辑逐步扩充,每次扩充都遵循"一个模块对应一类失误"的原则。如果某一条信息加进去之后,你发现它从来没有改变过模型的行为,那就把它删掉,它就是噪音。
3.3 第三步:把重复动作变成 slash command
我的经验是不要一上来就设计十来个命令。先挑两个最高频的动作:一个是 plan(需求转任务),一个是 review(代码审查)。前期一个命令文件超过 30 行的,我会重新考虑是否拆分。
创建过程:
- 在项目根目录创建
.claude/commands/目录。 - 新建
plan.md和review.md,先在内容里写清流程和约束。 - 启动 Claude Code,输入
/plan或/review,观察是否按预期执行。 - 如果命令模板太长,或者模型没有严格按流程走,先精简流程,再加约束性措辞。
这里有个细节:命令文件里除了流程本身,最好写一点"为什么"。例如 review 里写明"重点检查错误处理,因为之前出现过吞异常的问题",模型就能在检查时更有针对性。模板不是给机器背的考试大纲,是给机器用的工作手册,补上背景知识,执行质量会明显不一样。
3.4 第四步:验证清单
模板写完之后,我会跑一遍验证清单:
- 新建一个会话,不输入任何项目背景,直接问"本项目测试命令是什么",如果答案正确,说明 CLAUDE.md 生效。
- 输入
/review,确认模型先执行git diff --stat,而不是直接开始评论。 - 在会话里故意要求模型执行危险命令(比如
rm -rf),确认被权限层拦下。 - 修改 CLAUDE.md 后重新开启会话,确认模型能立刻感知到修改(而不是沿用旧上下文)。
把这套验证做成脚本(scripts/validate.sh)也是可以的,重点是让"模板生效"这件事变得可测试。否则模板改没改成功,全靠玄学。我在自己的 validate.sh 里就放了几个简单的 grep 和一问一答,每次改完模板跑一遍,心里立刻有底。
4. 模板在真实工作流中的效果:两个典型场景复盘
4.1 新项目接入:一条命令完成模板安装
上面这套模板如果只躺在仓库里,价值有限。我写了一个 install.sh,作用是把模板复制进新项目,并替换掉项目名等变量。脚本核心逻辑:
#!/usr/bin/env bash set -euo pipefail TEMPLATE_DIR="$HOME/code/claude-code-templates" TARGET_DIR="${1:-$PWD}" # 1. 复制通用层 cp -r "$TEMPLATE_DIR/_base/CLAUDE.md" "$TARGET_DIR/CLAUDE.md" mkdir -p "$TARGET_DIR/.claude/commands" cp "$TEMPLATE_DIR"/_base/commands/*.md "$TARGET_DIR/.claude/commands/" # 2. 根据技术栈参数写场景层 case "$2" in web) cat "$TEMPLATE_DIR/web-app/CLAUDE.md" >> "$TARGET_DIR/CLAUDE.md" ;; python) cat "$TEMPLATE_DIR/python-lib/CLAUDE.md" >> "$TARGET_DIR/CLAUDE.md" ;; esac # 3. 初始化 settings cp "$TEMPLATE_DIR/_base/settings.json" "$TARGET_DIR/.claude/settings.json"注意脚本里最后一步会创建.claude/settings.json,这个文件的作用域只在该项目内。跑完这个脚本,再启动 Claude Code,模型就已经"认识"这个项目了。我更推荐在团队内用这种安装脚本而不是每个人手写模板,因为只有从脚本安装,才能保证所有人拿到的是同一份基线。否则每个人随手改几行,半年之后,同一个团队里会有七八种互相冲突的"约定"。
4.2 场景一:/plan 需求拆解模板
后端项目,我输入的内容很简单:"给订单接口增加一个超时状态字段,并在列表接口中返回。"然后触发/plan。由于 CLAUDE.md 里已经注入了技术栈、数据库迁移方式、接口返回结构,plan 命令不需要再问"你们用什么 ORM"。
当时拿到的输出大致长这样:
任务拆解: 1. 修改 order 表迁移:增加 status='timeout' 的枚举值 2. 更新 Order model 与 Pydantic schema 3. order_list 接口返回字段补充 timeout_at 4. 为列表接口补充对应测试用例,覆盖超时状态过滤 风险点: - 枚举变更需要同步检查现有数据 - 该接口有外部依赖,字段顺序不可随意调整如果在裸奔模式下,这段对话大概率会从"这个项目用 SQLAlchemy 吗"开始,来回两三次之后才进入正题。而模板把前置信息消掉了,模型直接进入执行逻辑。对一个需要长期维护的项目来说,节省的不是几分钟,而是注意力。模型每少问一个背景问题,你就少一次切换上下文的开销,整个会话的流畅度会完全不同。
4.3 场景二:/review 代码审查模板
代码审查是最适合模板化的场景,因为审查流程稳定,而审查质量高度依赖上下文。裸奔时我跟他说"帮我 review 一下",它经常只给一句"整体实现不错,注意点边界条件"。用上模板后,审查报告会明显结构化。
我的 review 命令里有一条硬性要求:"任何结论必须引用代码行。"这句话救了我很多次。因为一旦要求引用行号,模型就不能说空话,它必须真的去读 diff。另外,我在模板里写了"先看错误处理,再看敏感信息",这是从一次生产事故里总结出来的教训,那次它把日志里可能泄露 token 的问题放过了。
这两个场景反复验证了一个观点:模板的作用不是让模型变得更强,而是让它的强项稳定输出在正确的上下文里。没有模板时你是在碰运气,有模板后你是在验收流程。
5. 模板不生效?我踩过的坑和完整排查路径
5.1 CLAUDE.md 放错作用域:全局、项目与仓库层级
第一次把 CLAUDE.md 放到用户目录以后,我以为所有项目都"记住"了,结果在另一个项目里它还是问技术栈。原因很朴素:用户目录的 CLAUDE.md 确实全局生效,但我只在里面写了自己的 IDE 偏好和编码风格,项目技术栈根本不在里面。模板不是魔法,它的作用范围是物理的:你放在哪个目录,它就只能覆盖哪些场景。
后续我还遇到过团队仓库里已经有一份 CLAUDE.md、我又在本地项目根目录放了一份的情况。两份同时存在就容易出现"到底听谁的"的混乱。我的处理原则是:用户目录只放个人偏好,项目仓库放团队约定,本地未提交的 CLAUDE.md 只放临时调试指令。三者职责分开,绝不混放。
排查路径:如果模型表现得好像没看见模板,先用find确认 CLAUDE.md 的实际位置,再确认当前工作目录与项目根目录的关系。很多时候是终端的工作目录不对,模板根本没被加载。
5.2 命令模板与别的命令冲突
我一开始给命令文件取名/init,结果发现它在团队仓库里已经被一个初始化脚本占用,行为变得不可预期。后来我把所有自定义命令改成带项目前缀的名称,比如/api-plan、/api-review。虽然多敲几个字母,但冲突概率大幅下降。
另外,命令文件里的description也很关键。如果 description 写得模糊,模型无法判断什么时候该触发这个命令,有时候会在我没输入斜杠命令时自作主张执行模板流程。后来我把描述改得非常具体,限定使用场景,误触发才消失。命令名建议用"动词-对象"的结构,比如/review-api,而不是笼统的/check,这样不管对模型还是对同事,意图都更清楚。
5.3 模板膨胀:当 CLAUDE.md 超过 500 行
第三个坑是我自己挖的:我一度追求"信息齐全",把历年踩坑记录全塞进了 CLAUDE.md,最后文件到了 600 多行。结果模型确实记得很多东西,但回答问题开始变得温吞,经常在无关的约束上绕圈子。我后来做了清理,把 CLAUDE.md 压到 200 行以内,技术细节拆到 commands 和 docs 里。
我的经验:CLAUDE.md 里的每一条都必须是"该项目的强约束",而"参考信息"应该放进单独文档,让模型在需要时按命令读取。否则模板越长,信噪比越低,模型越难抓住重点。定期 review CLAUDE.md 的每一行,问自己:少了这一行,模型会犯什么错?答不上来就删。
5.4 权限与 hooks:模板里要求的动作被模型拒绝
我用模板定义了一套"自动修复 lint 并提交"的流程,但是实际跑的时候,模型停在执行权限确认上,流程中断。起初我以为命令模板写错了,后来发现是 settings.json 里没把git add等命令加入 allow 列表。模板里的流程、hooks 里的检查、权限里的清单,三者需要对齐。
排查这类问题的方法是打开调试输出,看每一条工具调用被哪个环节拦截。确认是权限层的问题后,我调整了 allow 列表并明确写明"仅允许项目脚本目录内的命令"。这个教训说明:模板不是只在 CLAUDE.md 里写好话,权限和 hooks 才是真正能拦得住问题的执行层。你要求的动作越多,权限配置就越要认真,否则模型会整天卡在"是否允许执行"的确认弹窗上。
6. 模板的维护与长期迭代
6.1 模板也要走版本管理
我把 claude-code-templates 当成一个正式仓库来维护。每次调整模板,都会更新 CHANGELOG,并在改动影响行为时打 tag,比如 v1.2.0 表示命令流程有变化,v1.1.1 只是修正文案。为什么这么重?因为模板直接影响模型行为,改一行描述,可能导致所有下游项目的输出风格变化。没有版本记录,你就无法回答"为什么这个月模型的代码风格变了"。
另外,我会让 install.sh 接受版本参数,可以指定安装某个 tag 的模板。团队里如果有人发现新模板有问题,可以快速回滚到上一个版本,而不必全团队一起陪着踩坑。这跟项目管理里的依赖版本管理是一个道理:凡是影响行为的变更,都要留好回退点。
6.2 从个人模板到团队模板:分层的边界
当我把模板分享给团队后,遇到一个新的问题:同事说"你的模板太个人化了"。比如我把"终端输出用简洁模式"写进了公共层,对其他人就是噪音。后来我把模板分成两层:personal 与 team。team 里只放团队共识,personal 里放个人偏好,install 时先装 team 再用 personal 覆盖。这样一来,公共层可以放进项目仓库,个人层留在各自机器,既不会污染仓库,又能保证每个人的实际体验一致。
这条经验的价值在于:模板不只是一种技术配置,它也是一种团队契约。没有边界的模板,会让人产生"你在强加你的工作习惯给我"的抵触感。分层之后,大家反而更愿意往 team 里贡献内容。
6.3 我最近在做的三个实验
最后分享三个我正在做的实验,给想继续深挖的人一点方向。
第一个是参数化命令模板。我在尝试让同一个命令适配不同模块,例如/api-test后面带上模块名作为参数,模板根据参数切换不同的测试命令集。第二个是上下文压缩策略:CLAUDE.md 尽量精简,把详细规范放进命令模板或按需加载的文档,避免长期占用模型注意力。第三个是模板生成模板:用一套 meta 模板,根据项目的 package.json、pyproject.toml 自动生成初始 CLAUDE.md。目前来看,第三点最有潜力,因为它把"手工维护模板"变成了"项目结构驱动模板",未来的模板可能不是写给人看的,而是从项目元数据里长出来的。