用 Claude Code 写了小半年真实项目,我最深的感受是:这工具的上限很高,但下限也很低。同一个问题,你在干净的新会话里问,和在一个被历史对话塞满的会话里问,得到的方案质量能差出两个档次。后来我试过把项目背景、代码规范、常用任务流程都塞到每次对话里,结果上下文越来越臃肿,模型反而抓不住重点。直到我开始认真整理一套 claude-code-templates——把反复使用的项目记忆、任务指令、审查清单沉淀成固定模板文件——效果才有了质变:新会话也能秒懂项目上下文,输出风格稳定,重复劳动明显减少。
这篇文章不是官方文档翻译,而是我从零搭建、持续维护这套模板体系的完整记录。适合谁看?答案很简单:已经在用 Claude Code 干活、但总觉得它“时灵时不灵”的人;刚接触 AI 编程助手、想从一开始就建立正确工作流的人;还有带团队、希望让 AI 辅助开发的产出质量尽量一致的技术管理者。你会看到模板到底该拆成哪些层、每层怎么写、参数怎么设计、哪些坑我踩过,以及一套可以直接抄走的模板骨架。
1. 先想清楚:模板体系到底在解决什么问题
1.1 没有模板时的三个典型症状
我见过太多人在吐槽“Claude Code 不靠谱”,大部分时候问题不在模型本身,而在我们根本没给它一个稳定的工作环境。没有模板时,最典型的是这三个症状。
第一个是每次新会话都要重新做背景交代。项目叫什么、技术栈是什么、代码目录怎么组织、测试怎么跑、有哪些需要注意的坑——这些信息你在上一个会话里可能花了十分钟讲清楚了,模型也理解得很好,但只要会话一关、场景一换,一切归零。换到新会话之后,你又得从头开始解释。一天开五个会话,就要重复五遍。这种体力活干上两周,你就会开始怀疑自己到底是在写代码还是在当客服。
第二个是同一类任务的输出质量飘忽不定。同样让模型“写一个接口测试”,今天它记得遵守项目里的测试规范,明天可能就自己发明一套风格;今天 code review 会认真查边界条件,明天可能只是把代码复述一遍。模型的输出受对话历史影响极大,而对话历史又完全是随机的。没有模板兜底,你就是在让模型每天摸黑工作。
第三个是上下文被没用的历史对话污染。会话拉到二三十轮之后,模型开始抓不住最初的约束条件,有时候甚至会出现前后矛盾的建议。这也是为什么很多人觉得“越聊越笨”——不是模型退化,而是窗口里的噪音太多,真正重要的指令被淹没了。模板体系的核心价值,就是把这些噪音在源头上压下去:该让模型知道的东西,在对话开始前就摆到它面前;不该让它看到的东西,根本不要进入上下文。
1.2 模板化的本质:把“人肉记忆”变成“项目记忆”
理解模板体系,最合适的类比是带新人。你带一个刚入职的工程师,肯定不会每天把“我们技术栈是 React + TypeScript”“接口错误码规范在 wiki 上”“提交前必须跑 lint”这几句话重复八十遍。你会给他一份入职手册,让他自己看;遇到具体任务,再给一份任务清单。
Claude Code 的模板体系就是这套手册和任务清单。CLAUDE.md 是入职手册,负责描述项目背景、技术栈、代码规范和约定;自定义命令和技能文件是任务清单,负责定义“遇到某类任务时按什么流程做”。这两个层级的核心区别在于触达方式:手册是自动加载的,模型一开始就看得到;任务清单是懒加载的,只有用户主动触发或者在执行过程中判定“这个场景需要用到”时才会被调用。
明白了这个区别,你就能理解为什么不能只靠一个巨长的 CLAUDE.md 解决所有问题。你当然可以把所有指令全都写进 CLAUDE.md,但那样等于把整本手册加上所有任务清单都塞进模型的上下文里。上下文一长,模型对每条指令的“注意力”就会被稀释。更合理的做法是分层:高频、全局、必须每次都知道的信息放进 CLAUDE.md;低频、特定场景才需要的信息放进命令和技能文件里,用时再取。
1.3 模板体系上线前后的对照
| 场景 | 没有模板 | 有模板 |
|---|---|---|
| 新会话启动 | 每次重新解释项目背景,前五轮都在对齐信息 | CLAUDE.md 自动加载,开场即进入干活状态 |
| 同类任务执行 | 输出风格、流程、代码习惯全靠“抽卡” | 命令和技能文件固定流程,质量下限有保证 |
| 上下文管理 | 历史对话越长越乱,后期频繁偏离需求 | 静态约束前置,动态指令精简,上下文更干净 |
| 团队协作 | 每个人的用法、习惯、提示词各自一套 | 模板统一入库,新人照着模板即可快速上手 |
这张表不是理论上推出来的,而是我自己和团队实际用了一个季度之后肉眼可见的变化。尤其是“新会话启动”这一行,体感最明显。以前开一个新会话,光是让模型搞清楚“这个仓库是干什么的”“目录怎么组织”“有哪些约定”就要花掉四五轮对话。现在模板加载完,它能直接说出项目的正确全称、已知的技术债和常见的坑,我只需要把具体任务丢给它就行。
2. 模板库的骨架:四个层级一起用
2.1 第一层:CLAUDE.md 项目记忆模板
CLAUDE.md 是这套体系的地基。它的加载机制决定了它适合放什么内容:模型每次处理任务前都会自动读取相关目录下的 CLAUDE.md,不需要用户手动指定。也就是说,只要文件存在,项目的“核心价值观”就不存在遗忘的可能。
我用的 CLAUDE.md 模板长这样,大家可以按项目情况删改:
# 项目记忆 ## 项目概述 - 项目名称:{{project_name}} - 一句话定位:{{one_line_description}} - 线上地址 / 部署环境:{{urls}} ## 技术栈 - 前端:{{frontend_stack}} - 后端:{{backend_stack}} - 数据库:{{database}} - 基础设施 / CI:{{infra}} ## 目录结构 - src/ 应用源码,按业务模块组织 - tests/ 单元测试与集成测试 - docs/ 架构决策记录与接口文档 - scripts/ 本地开发与运维脚本 ## 开发约束(务必遵守) - 所有 API 响应必须符合项目错误码规范,禁止直接抛裸异常 - 数据库变更必须配套迁移脚本,禁止手工改库 - 提交前必须运行 `pnpm lint` 和 `pnpm test`,不得跳过 - 新增依赖需在 MR 描述里说明原因,并评估体积影响 ## 常用命令 - 启动开发环境:`pnpm dev` - 运行全部测试:`pnpm test` - 构建生产产物:`pnpm build` - 代码检查:`pnpm lint`这里有个关键点:不是让你把整个项目文档抄进去,而是只放“模型每次干活都必须知道”的信息。具体的技术细节、接口清单、历史决策,应该写成一句“更多信息见 docs/xxx.md”,让模型在需要时自己去读。模板写得太厚,反而会让真正重要的约束被淹没。
2.2 第二层:自定义斜杠命令模板
自定义命令是模板体系里使用频率最高的一层。它的加载方式和 CLAUDE.md 正好相反:CLAUDE.md 是自动加载,命令则是等着你主动敲。你把 markdown 文件放进项目的 .claude/commands/ 目录,文件名就是命令名。比如我常用的是一个 code review 命令:
--- description: 对指定代码进行严格 code review argument_hint: 目标文件或范围 --- 请对 {{ $ARGUMENTS }} 涉及的代码变更进行严格审查,按照以下流程执行: 1. 先定位变更范围和 diff,不要凭印象评价 2. 逐项检查:逻辑正确性、边界条件、错误处理、性能风险、安全风险 3. 对照项目 CLAUDE.md 中的开发约束,重点检查是否违规 4. 输出格式: - 问题列表(按严重程度排序:阻断 / 建议 / 可忽略) - 每个问题必须给出具体行号或代码片段定位 - 建议修复方案,但不要直接改代码 5. 如果存在阻断性问题,最后用一句话总结“是否建议合入”,并说明理由这个模板解决了一个很现实的痛点:过去让模型 review 代码,它经常给我交一篇“整体来说代码写得不错、结构清晰、建议补充注释”之类的空话。现在的模板把审查步骤和输出格式都固定死了,它会老老实实按顺序检查,然后给我一张可执行的问题清单。命令模板的价值就在这里——把你不满意的输出方式,用流程强制扭转过来。
2.3 第三层:Skill 技能文件
技能文件和自定义命令有点像,但定位不同。命令是你主动触发的固定动作,而技能更适合“多步骤、需要模型自己判断何时调用”的复杂任务。技能文件放在 .claude/skills/<技能名>/SKILL.md 里,需要通过 Front Matter 声明名称、描述和触发条件。
以“修 bug”这个技能为例,我写的 SKILL.md 是这样的:
--- name: bugfix description: 定位并修复代码缺陷,适用于用户报告 bug、测试失败、崩溃排查等场景 --- ## 执行流程 1. **复现与定位** - 先要求用户提供复现步骤或最小复现用例 - 通过日志、断点、代码阅读定位根因,禁止“看见症状就猜原因” - 如果涉及多个模块,用二分法缩小范围 2. **确认根因** - 向用户说明根因分析结果,并附证据:日志、代码路径、调用链 - 只有当用户确认“根因正确”后,才进入修复阶段 3. **修复与验证** - 最小化改动,不顺手重构无关代码 - 编写或更新回归测试,确保能捕获该 bug - 运行相关测试,验证修复不破坏其他功能 4. **收尾** - 输出变更摘要:根因、修复方案、影响范围、测试结果 - 如果修复涉及文档或配置,提醒用户同步更新为什么把这类流程做成技能而不是命令?因为“修 bug”是一个由模型主动识别的场景。当用户抛出一段崩溃日志、说“线上挂了”,模型需要在众多能力里判断该启用哪一套流程。技能文件把场景描述写清楚,模型就能在恰当的时候自己匹配到它,不需要用户记忆“我应该先敲一下 /bugfix 再说”。这一点差异,在实际使用中让整个交互的自然度提升了一大截。
2.4 第四层:任务级 Prompt 片段
前三层都属于“放进去就能被自动或半自动触发”的结构化模板。但实际工作里还有一类需求是高度临时、高度个性化的,比如“把某个 API 的返回结构改一下”“给某个页面加一个暗黑模式开关”。这类任务不值得为它单独建一个技能,但如果你每次都现场组织语言,质量又很不稳定。
我的做法是在模板库里维护一个 prompts/ 目录,存放各种任务级 prompt 片段,按场景命名,例如:
## 任务:新增一个 CRUD 接口 请在 {{module}} 模块中新增一个关于 {{resource}} 的 CRUD 接口,要求: - 遵循项目既有的分层结构(controller / service / repository) - 入参校验使用项目现有的校验规范,非法输入返回 {{error_code}} - 补充单元测试,覆盖正常路径和至少两个异常路径 - 涉及数据库变更时,先输出迁移脚本,等待确认后再执行这种片段的特点是“开箱即用、用完即走”。它不是常驻上下文的一部分,不会被模型自动读取,而是当你需要时复制粘贴到对话里。它的存在保证了一件事:哪怕今天状态再差、时间再赶,你给模型的指令质量也不会低于某个及格线。对一个依赖 AI 干活的开发者来说,这个及格线也许才是最重要的东西。
3. 实操记录:从零搭一套模板库的完整过程
3.1 先盘点高频任务,再动手写
写模板最容易犯的错,就是一上来就设计一个宏大体系,然后发现大部分模板根本没人用。按照我的经验,正确的顺序是先盘点,再抽象,最后才是动手写。
找一个安静的时间,把你最近两周在 Claude Code 里让它做的所有事情过一遍,列成一张清单。不用精确,靠记忆就行。然后问自己三个问题:哪些任务一周出现三次以上?哪些任务你每次都要花额外的话去纠偏?哪些任务做完之后你经常需要返工?满足其中任意一条,这个任务就应该有模板。
以我自己的后端项目为例,两周下来高频任务排序是这样的:修 bug、写接口测试、code review、写提交信息、数据库迁移、重构某个模块。前四个频率明显高于后两个,所以我的第一个迭代版本就只做了四套模板:一个 bugfix 技能、一个 review 命令、一个测试生成命令、一个 commit 命令。数据库迁移和重构后来被验证确实有必要,补进了第二个版本。先少后多、按需迭代,是模板库能长期活下来的关键。
3.2 按依赖关系排序:CLAUDE.md 永远第一个写
很多模板之间是有依赖关系的。比如 review 命令里会引用“项目 CLAUDE.md 中的开发约束”,测试命令里会要求“遵循项目的单测规范”。所以正确顺序一定是:先写 CLAUDE.md,再写命令和技能。
这个顺序不是洁癖,而是有实际意义的。如果你先写了命令模板,里面引用了“项目开发约束”,回头再补 CLAUDE.md 时还要回头改命令;更麻烦的是,有些规则你可能会写进命令、写进技能、写进 prompt 片段,分散在三处——结果就是同一个规则出现了三个版本,模型不知道该听谁的。把规则先收敛进 CLAUDE.md,下游所有模板只引用不重复,才能避免“规则多头管理”的混乱。
这里分享一个我自己定的硬性规范:凡是全局性的、跨任务的约定,一律只出现在 CLAUDE.md 里。下游模板中的相关措辞统一写成“遵循项目 CLAUDE.md 中的 XXX 约定”,绝不在命令里再复制一遍具体细节。这样一来,哪天要改技术栈约定,我只需要改一个文件,全部模板自动生效。
3.3 用占位符设计模板参数,而不是硬编码
模板面对的是一类任务,而不是一次具体任务,所以必须考虑参数化。Claude Code 的自定义命令支持在调用时接受参数,但说实话,靠参数传递的描述信息终究有限。更多时候,我依赖的是“占位符 + 自然语言填空”的方式。
看这个 commit 命令模板,你应该能理解我的意思:
--- description: 生成符合规范的 git 提交信息 argument_hint: 描述本次改动 --- 根据用户的描述 {{ $ARGUMENTS }} 以及当前代码变更,生成一条 git commit 信息。 要求: - 遵循项目的提交信息规范:类型(范围): 描述 - 描述使用简洁的祈使语句,例如“修复登录接口空指针问题” - 如果变更涉及多个方面,省略次要项,只保留最核心的变更点 - 禁止在信息中补充代码审查意见,只输出具体的 commit message命令模板里可以放参数占位符,prompt 片段里则更适合用双大括号。比如我在 2.4 节里写的 {{module}}、{{resource}},就是“写给模型看的约定”:模型看到这个标记,就知道应该把它替换成实际内容。这种方式不依赖任何底层机制,却能让模板在不同项目、不同任务之间自由复用,属于最笨但最稳的参数化方案。
3.4 用 Git 管理模板库,让模板可以被“审计”
模板库一旦开始积累,它就不再是几个 markdown 文件,而是你团队开发方法论的沉淀。它值得像代码一样被版本化管理。
我的做法是在 GitHub 上建一个私有模板仓库,目录结构如下:
templates/ ├── global/ │ ├── CLAUDE.md # 个人全局规则 │ └── commands/ │ ├── commit.md │ └── review.md ├── project/ │ ├── web-frontend/ # 按项目类型或项目名分组 │ │ └── CLAUDE.md │ └── backend-service/ │ ├── CLAUDE.md │ └── skills/ │ └── bugfix/SKILL.md ├── prompts/ # 任务级 prompt 片段 │ ├── add-crud-interface.md │ ├── write-unit-test.md │ └── refactor-module.md └── README.md # 使用说明和目录索引每次修改模板,我都在提交信息里写清改动原因,比如“review 命令增加安全审查项,因为上周线上暴露出一个越权问题”。这看起来很轻量,但时间长了之后,模板库本身就成了团队的决策日志——翻一遍 git 历史,你就能看到哪些问题反复出现、我们是怎么调整应对的。这种价值,是写在聊天记录里的临时提示词永远没法比的。
3.5 内容密度怎么把握:目标是“两秒内读完”
很多人写 CLAUDE.md 时抑制不住想把所有内容塞进去,我可以负责任地说:这是把模板变成噪音最快的路径。我给团队定的指标是:一个项目的 CLAUDE.md 应该在两秒内能被扫读完,大约 150 行以内,超过这个量就要开始怀疑是不是塞了太多不该放进去的内容。
为什么是这个量级?从模型的角度想,CLAUDE.md 是每次请求都会携带的信息,它占用的 token 越多,留给实际任务和对话的上下文空间就越少。更重要的是,当一条信息被淹没在五十条同级别指令里时,模型的注意力很难判断哪条才是真正重要的。我的经验是:把最重要的五条规则放在 CLAUDE.md 最靠前的位置,比如“禁止手工修改数据库”“提交前必须跑测试”,这些规则甚至可以带加粗标识;具体细节、步骤、背景,全部下沉到命令、技能或 docs 文档里。把 CLAUDE.md 当成一份“摘要”,而不是一本“百科全书”。
4. 常见问题与排查技巧实录
4.1 模板写好了,但模型就是不遵守
这是模板体系里最让人崩溃的问题:你明明把规则写进了 CLAUDE.md,模型却好像完全没看见。根据我踩过的坑,这个问题十个里有八个出在文件位置或层级关系上。
Claude Code 会从多个位置读取 CLAUDE.md,包括用户级目录和项目各级目录,并且不同位置的规则会发生合并。如果你把某条规则只写进了子目录的 CLAUDE.md,而实际对话发生在另一个目录,这条规则就不会被加载。解决办法是:重要规则要么放在项目根目录的 CLAUDE.md,要么明确写进全局 CLAUDE.md,不要放中间层。另外,规则之间如果相互冲突,模型的执行效果也会大打折扣。我曾在全局 CLAUDE.md 里写“所有回答使用中文”,但项目 CLAUDE.md 里写“代码注释使用英文”,结果模型的注释经常中英混用。现在我的处理方式是:规则避免重复定义,同一件事只在一个地方出现;确需区分场景的规则,写明“在 X 场景下执行 A,在 Y 场景下执行 B”。
4.2 上下文越来越胖,模型开始“忘记”前置条件
模板写得多了以后,你会遇到另一个问题:上下文被模板撑胖了,模型反而抓不到重点。这尤其在长会话后期明显——它开始忘记你最开始塞进去的 CLAUDE.md 里的约束,反而被当轮对话里的临时信息带偏。
排查的时候,我一般先看会话前半段的加载信息,确认 CLAUDE.md 有没有被正常读取。如果读取了但后期失效,大概率是会话太长、信息滑出了有效窗口。解决思路有两个方向:一是给 CLAUDE.md 瘦身,只保留最高优先级的内容;二是把长任务拆成多个短会话,每个会话只聚焦一个子任务,配合自定义命令和技能文件,让模型在每一步都重新加载精简后的约束。我的体感是,拆会话比续聊更能保持输出稳定,宁可多开几次新会话,也不要让一个会话无限拉长。
4.3 全局模板和项目模板打架
同时维护全局模板和项目级模板,早晚会遇到规则冲突。我自己遇到过一次:全局 CLAUDE.md 里要求“代码中使用单引号”,而某个项目的 CLAUDE.md 里约定的是“无分号 + 双引号”,结果模型在不同文件里输出风格忽左忽右。
解决这类问题的思路是明确优先级,并且把优先级规则写进全局模板的开头。我的写法是:当项目级 CLAUDE.md 与全局 CLAUDE.md 冲突时,以项目级为准;项目级没有明确约定的,再回退到全局规则。同时,在项目级模板里,我只写与全局不同的特殊约定,相同的规则一律不重复。这样虽然有极少数的覆盖关系需要记忆,但至少规则是清晰可判的,模型的输出也不会再“人格分裂”。
4.4 自定义命令里的参数不生效
自定义命令的参数能力有一定限制,这一点在社区里经常被吐槽。我最初也期待它能做复杂的参数解析,比如“/review 只检查安全风险”,后来发现效果不稳定,倒逼我想出了一个更简单的方案:模板在开头引导模型自己问问题。
比如我的 review 命令模板里,一开始就写了“如果用户没有指定关注范围,请先询问是完整审查还是仅安全审查”。这样参数交互就从“硬解析”变成了“模型主动澄清”。虽然多了一次对话,但胜在稳定、理解准确,而且对用户来说完全无感。这算是模板设计里一个非常实用的妥协策略——与其跟工具机制较劲,不如让模型多问一句。
4.5 团队推广:最大阻力不是技术,是习惯
最后补充一个团队层面的坑。模板体系在一人项目里很容易落地,但到了团队里,最大的阻力永远是“别人不想用”。你费心维护的 CLAUDE.md 和命令模板,队友可能根本不会去看,最后还是各自为政。
我试下来最有效的方法是把模板的使用门槛降到零:第一,在仓库根目录放一个简短的 README,说明“这个仓库长什么样、有哪些命令、新人第一天怎么用”;第二,在项目里写一个 /help 命令模板,让队友只要敲一下斜杠就能看到可用命令列表;第三,把模板评审纳入正常的 code review 流程——当有人在 MR 里漏掉了 CLAUDE.md 明确要求的步骤时,直接引用那条规则来拒绝合入。靠制度而不是靠热情,模板体系才能真正活起来。
5. 模板库维护:让模板持续进化,而不是一封陈年邮件
模板库最大的敌人是腐烂。任何文档类资产,一旦停止更新,就会从“生产力工具”变成“历史包袱”。维护这件事,我总结成三条很朴实的原则。
第一条是每两周做一次模板修剪。打开模板库的 git 历史,看看过去两周哪些文件被修改过,哪些命令被用到过。如果一个命令模板半年没有人调用、也没有人更新,那就删掉。留着一堆用不上的模板,只会让真正好用的模板被淹没。
第二条是把自己踩过的坑“固化”进模板。模型重复犯同一个错误的时候,第一时间不是去骂模型,而是想想是不是模板里少了什么。比如我的团队曾经有两次因为没检查 migration 的逆向操作而出问题,后来我直接在 CLAUDE.md 里加了一条:“涉及数据库迁移时,必须同时评估 down 迁移的完整性。” 模板不是写出来就完事的,它是你工作经验的持续沉淀。
第三条是保持模板的“单一职责”。每个命令、每个技能只做一件事,并且命名清晰,比如 review 就只管审查,commit 就只管提交信息。不要搞一个“万能助手”命令,什么东西都想往里塞。可组合的小模板比一个大而全的模板灵活得多,而且更容易排查问题。
最后说点个人体会。claude-code-templates 这套东西,最难的从来不是“写模板”这个动作,而是判断“哪些信息值得被固化成模板”。太细的会僵化,太粗的等于没写。我的判断标准很简单:如果同一件事,我在两周内需要向 Claude Code 解释或纠偏第三遍,那就该考虑进模板了;如果一个模板两个月都没派上用场,那就该删了。模板体系说到底是一种“记忆管理”——把你脑子里的项目知识,逐步转移到一个模型也读得懂的地方。这个过程不会一蹴而就,但只要坚持迭代几个月,你的 AI 工作流会肉眼可见地变得稳定和顺手。