ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Claude Code模板工程化:从System Prompt到CLAUDE.md的稳定AI编码实践

2026/9/26 8:00:40 拓冰建站 浏览量
Claude Code模板工程化:从System Prompt到CLAUDE.md的稳定AI编码实践 1. 为什么我把“万能提示词”全部扔进了模板我大概是在 Claude Code 刚火那阵开始重度使用终端的最开始跟很多人一样直接把需求一句句丢给它“帮我看看这个文件哪里有问题”“给这段代码补个测试”。日常小任务还好一旦涉及跨文件改动、架构评审、多轮重构你会发现每次都得从头啰嗦一遍上下文、约束、输出格式而且它每次的理解还不太一样——同一个需求今天给的结果和昨天给的版本能差出一大截。后来我认真琢磨了一件事与其反复“调教”对话不如把高频任务的处理逻辑固化成模板文件让 Claude Code 每次启动都带着同一套规则、同一个工作流去干活。这就是我折腾 claude-code-templates 的起点。说白了模板就是把“你希望 AI 怎么思考、按什么顺序做事、输出什么结构”这件事变成一份可提交、可版本管理、可团队复用的配置文件而不是靠人肉记忆去维持一致性。这篇文章把我从零搭建模板仓库的完整过程写出来包括目录设计、system prompt 的写法、CLAUDE.md 的配合方式、hooks 动态注入还有我踩过的几个大坑。适合已经在用 Claude Code、但觉得输出不够稳定的朋友也适合打算在团队里统一 AI 编码规范的人。先说结论模板真正解决的不是让 Claude 变聪明而是让它每一次都“稳定地保持某个水平”。就像你请一位高级工程师来干活你不会每次重新介绍一遍公司背景和代码规范——你给 Ta 一份 onboarding 文档。Claude Code 的模板就是这份 onboarding 文档。2. 模板仓库的文件结构设计与启动流程2.1 模板放在哪里是一门学问我一开始很随意直接在项目里建了个templates.md结果发现 Claude Code 并不会自动读它——你必须通过某种方式把文件内容拼进 prompt 里。后来我整理出一套固定的放置方案分两种情况个人全局使用放在~/.claude/或~/.config/claude-code/下让所有项目共享同一套基础规则。项目级使用放在仓库根目录的.claude/文件夹下跟随代码库一起提交团队其他人 clone 下来就有同样配置。我的建议是两层都要全局放“通用行为规范”例如代码风格偏好、输出格式要求项目级放“业务上下文”例如模块结构、命名约定、测试要求。这样模板既不会因为塞太多项目细节而无法复用也不会因为完全没有项目信息而显得空泛。下面是我现在用的全局模板目录结构~/.claude/ ├── settings.json ├── system-prompts/ │ ├── review.md │ ├── refactor.md │ ├── test.md │ └── explain.md ├── scripts/ │ ├── collect-context.sh │ └── git-summary.sh └── CLAUDE.md项目级的建议放在.claude/下结构类似但侧重点是业务规则repo/.claude/ ├── settings.json ├── CLAUDE.md └── prompts/ ├── service-review.md └── migration-guide.md2.2 settings.json 是如何把模板“喂”给 Claude 的Claude Code 的配置文件支持prompt字段用来注入用户级或项目级的系统提示词。如果你像我一样把提示词拆成了多个 markdown 文件两种办法要么用脚本读取并合并成一个字符串再传给 CLI要么直接在 settings.json 里写短片段长内容用文件引用。我实际用的是后者配合一次启动前的小脚本把多个 md 拼成一个总 prompt。伪代码大概是这个样子我简化了逻辑重点是思路#!/bin/bash # scripts/build-prompt.sh PROMPT_DIR$HOME/.claude/system-prompts OUTPUT for f in $PROMPT_DIR/*.md; do OUTPUT${OUTPUT}$(cat $f)\n\n done claude --settings-file $HOME/.claude/settings.json \ --prompt $OUTPUT $跑起来之后Claude 每次启动都会先“读一遍”这些模板相当于给自己定了规矩。同样项目里的.claude/settings.json会覆盖或追加全局配置具体规则后面会专门说。2.3 拼接顺序至关重要系统提示词、CLAUDE.md、用户消息很多人的模板实践失败是因为根本不理解 Claude Code 内部 prompt 的拼接顺序。我实测下来大致是系统提示词system prompt在最前面然后是项目 CLAUDE.md 和全局 CLAUDE.md 的内容再往后才是你跟它说的用户消息。这个顺序决定了规则冲突时的胜出方——越是靠后的内容越容易在生成时被模型强调。所以我通常把“铁律”类约束比如禁止修改某些目录、必须输出中文注释放在系统提示词里把“背景知识”比如当前模块的技术栈、过往决策记录放在 CLAUDE.md 里。背景知识不需要每次当成命令执行它更像参考资料。3. 让 AI 稳定输出的系统提示词设计3.1 模板不是“长篇大论”而是“结构化指令”我见过不少人把模板写成两千字的小作文从 AI 伦理写到团队愿景。这不是模板是噪音。系统提示词的有效设计应该遵循极简结构身份定义、任务目标、工作流、输出格式、红线规则。拿我做代码评审的review.md举例核心内容就四块你是一名资深后端工程师负责审查 pull request。 任务目标 - 发现潜在 bug、性能瓶颈和安全问题 - 检查是否违反项目既有约定 工作流 1. 先阅读 diff列出变更文件清单 2. 对每个关键文件给出风险评级 3. 汇总问题并标注严重程度 输出格式 - 用 markdown 表格列出问题严重程度 | 文件 | 行号 | 问题描述 - 末尾给出一段 200 字以内的总体建议 红线规则 - 不评价代码风格偏好除非项目有强制 lint - 不为凑数量而提无意义 issue注意看每一块都是可执行、可校对的条目没有废话。AI 不是人类它对“写得很有文采”的判断力有限但对“明确的步骤编号”和“结构化的输出要求”特别敏感。3.2 为什么结构化提示词能压制“自由发挥”这个机制我后来想明白了Claude 在生成文本时本质上是在做概率预测——给它一段开头它预测后面最可能的内容。如果开头是一堆抽象形容词它就可能跟着抽象下去越写越飘如果开头是一二三四的清单它更倾向于继续按清单式结构输出。模板的核心作用就是把模型“惯性的输出方向”扭到你想去的轨道上。所以我写模板时特别讲究“决策点”的设置比如“如果发现内存泄漏风险请停止继续审阅并优先汇报”。这种指令实际上是在模型内部触发了一个分类决策——先判断是否存在高风险再决定走哪条分支。结果就是它不会闷头把整个文件评完才告诉你最严重的问题在哪儿。3.3 让模板具备“自检查”能力这是我最喜欢的一招在模板末尾加一段“自我检查指令”。比如要求 Claude 在输出前检查是否满足指定的 commit 规范、是否遗漏了编号、是否在回答中引用了具体文件行号。本质上就是让模型在生成后用另一段 prompt 再“看一遍自己写的东西”。成本几乎为零但效果极其明显。很多次它都会自我发现“我刚刚漏了一个约束”然后自己修正。这比你在外面反复催它“注意细节”管用得多。4. CLAUDE.md 作为项目级记忆模板的暗线4.1 全局模板管“怎么干活”CLAUDE.md 管“这项目是什么”很多文章把 CLAUDE.md 和模板混在一起讲但其实它们分工完全不同。模板是“方法论”CLAUDE.md 是“项目记忆”。打个比方模板是外聘顾问的工作手册CLAUDE.md 是公司内部的文档库。顾问不知道你们这个服务的架构图长什么样、哪个模块是新写的、哪段代码是为了兼容老接口而留的“疤痕”这些只能写在 CLAUDE.md 里。我见过最糟糕的 CLAUDE.md 写法是把整个 README 复制进去还贴了几百行 API 文档。模型确实能读但它根本分不清哪些是“当前任务需要关注的重点”哪些只是“历史背景铺陈”。CLAUDE.md 应该精简到只有三类内容技术栈和目录的关键事实当前迭代中已知的问题或技术债命令、脚本、代码生成约定比如我某个项目的.claude/CLAUDE.md就写成这样# 项目简报 - 后端: Python 3.11 FastAPI核心代码在 app/services/ - DB: Postgres 16迁移文件在 migrations/ - 当前已知问题: payments 模块存在死锁风险禁止在该模块加异步嵌套锁 - 测试策略: 新功能必须有单测关键路径需要集成测试 - 常用命令: make dev 启动本地环境make test 跑全部测试看上去很简单但 Claude 拿到这些信息后回答质量是飞跃式的。它不会再绕着你的架构图乱猜也不会建议你用项目里根本没装的工具。4.2 CLAUDE.md 和 system prompt 冲突时的“优先级规则”实际使用中一定会遇到冲突。比如我全局模板要求“所有代码注释必须用英文”但某个项目的 CLAUDE.md 写的是“注释必须用中文并包含需求单号”。实测结果是项目级的 CLAUDE.md 往往比全局 system prompt 更占上风因为它是更贴近当前任务的上下文。这个机制其实是可以利用的用全局模板定死那些“绝对不能妥协”的底线比如安全规范、敏感数据不得写入日志用项目 CLAUDE.md 做灵活的项目级覆盖比如注释语言、命名风格。如果发现覆盖结果不符合预期就调整拼接顺序或者直接在 system prompt 中写“禁止填充内容来自项目 CLAUDE.md 的 XX 规则”。4.3 别把 CLAUDE.md 写成一劳永逸的“圣旨”项目是活的CLAUDE.md 也应该跟着迭代。如果不维护它会逐渐变成一堆过时指令AI 拿着过时的技术栈信息给你出方案比没有记忆还危险。我的习惯是每次完成一个重要的架构决策或者踩坑修复就顺手在 CLAUDE.md 里加两行每次大规模重构就重写一半内容。模板和 CLAUDE.md 的关系应该是模板提供稳定的方法论框架CLAUDE.md 提供流动的项目事实。5. hooks、前置命令与状态注入让模板从“静态”变“动态”5.1 静态模板只是起点固定模板的局限在于它不知道你当前要处理的到底是哪个文件、当前分支上改了什么、测试跑没跑过。这些信息如果全靠手工描述每次都会漏掉一部分而漏掉的信息往往恰好是 AI 做判断的关键输入。所以我给模板加了一个前置脚本层思路就一句话在把 prompt 交给 Claude 之前自动收集当前仓库的状态信息注入到模板里。这样每次启动时它拿到的不是一份死模板而是一份“当次任务的实时简报”。5.2 一个动态模板的完整构成下面是我为一个代码评审场景设计的完整配置。首先要有一个收集上下文的脚本collect-context.sh#!/bin/bash # scripts/collect-context.sh BRANCH$(git branch --show-current) CHANGED_FILES$(git diff --name-only HEAD~1..HEAD 2/dev/null || git diff --cached --name-only) DIFF_STATS$(git diff --stat HEAD~1..HEAD 2/dev/null || git diff --cached --stat) echo ## 当前分支: $BRANCH echo ## 变更文件: echo $CHANGED_FILES echo ## 变更统计: echo $DIFF_STATS然后用一个启动器脚本拼接完整 prompt#!/bin/bash # scripts/review.sh CONTEXT$(bash $HOME/.claude/scripts/collect-context.sh) SYSTEM_PROMPT$(cat $HOME/.claude/system-prompts/review.md) claude --settings-file $HOME/.claude/settings.json \ --prompt ${CONTEXT}\n\n${SYSTEM_PROMPT}\n\n请对上述变更进行代码评审。跑起来的效果是Claude 一上来就知道当前分支是feature/payment-fix改了哪些文件换了哪些逻辑而不是等着你去解释半天。实测下来评审意见的准确率明显提升了尤其在“这个改动会不会影响别的模块”这类问题上因为模型终于能看到具体的变更边界了。5.3 用 hooks 维持会话状态前两种方案都是“启动时注入”但实际工作时往往是一个会话要持续好几轮。我有段时间发现聊到第 5 轮之后Claude 会把最初给它的一些上下文“忘记”比如偶尔忘了自己是“代码评审员”的身份。后来我在 settings.json 里配了 hooks 功能在每轮用户消息之前自动重新注入核心身份和关键约束。这样只要对话还在继续身份就不会丢。这个机制的原理类似于“每次对话都重新拉一遍确认”代价是 prompt 变长但好处是长会话的一致性有了保障。6. 一份可直接落地的“全栈评审模板”实战6.1 目标让每次代码评审输出格式统一、发现问题有优先级我在团队里推广模板时最大的阻力不是 AI 不听话而是大家看不懂 AI 的输出。每个人习惯不同有人喜欢列 bullet有人喜欢写长段落。所以我做了个决定用模板把输出的结构强制统一成表格并且给问题定性、定量。这是完整的review.md模板内容你可以直接抄走改成自己的# 代码评审规则 你是团队的技术负责人请对给定的代码变更进行严格评审。 ## 评审步骤 1. 阅读所有变更文件先理解业务意图再分析代码 2. 逐个文件检查以下维度正确性、性能、安全、可维护性 3. 对每个问题给出文件路径、行号区间、严重等级 ## 严重等级定义 - P0: 可能引发线上故障、数据丢失或安全漏洞必须立即修复 - P1: 明确的功能缺陷或性能瓶颈应在合并前修复 - P2: 可维护性或潜在风险建议修复但不强制 - P3: 风格或微小建议不阻塞合并 ## 输出格式 ### 评审摘要 一句话说明本次变更的整体风险和是否建议合并。 ### 问题清单 | 等级 | 文件 | 行号 | 问题描述 | 修复建议 | |------|------|------|----------|----------| | P1 | app/service.py | L88-95 | ... | ... | ### 优点 列出一到三条做得好的改动避免只报问题。 ## 自我检查 输出前检查 - [ ] 是否所有 P0/P1 问题都给出了修复建议 - [ ] 是否每条问题都包含具体行号 - [ ] 是否在摘要中明确表达了阻塞/不阻塞的意见这份模板的实际效果是不管项目里谁跑review.sh产出的评审意见格式都是一样的可以省掉大量解释时间。团队里新来的同事只要跑一遍也能立刻看懂。6.2 配合 settings.json 的完整配置这套方案还需要一个配套的settings.json控制横纵配置{ model: opus, permissions: { allow: [ GitDiff(*) ] }, hooks: { PreToolUse: [ { matcher: GitDiff, command: bash ~/.claude/scripts/collect-context.sh } ] } }这里有个设计意图要解释一下允许模型使用 Git 命令不是为了让它随便跑 git而是为了让它在面对模糊问题时能自己去查代码仓库的当前状态而不是瞎猜。配合上面的collect-context.sh模板就从“启动时静态注入”变成了“运行时动态查询”两者一起用效果最好。6.3 实际运行效果一次标准的评审输出我把这套配置跑在一个实际项目上变更是一个支付模块的超时重试功能。Claude 的输出从一开始的“这个代码看起来不错但有几个小细节可以优化”变成了带有 P0/P1 分级、精确行号、修复建议的评审报告。它甚至捕捉到了我在代码里埋的一个“签名验证失败后吞掉异常只 return false”的问题并且直接指出这会导致支付回调无法感知失败——这恰是我故意留的 bug。模板认真写和不认真写AI 的表现完全不是一个量级。7. 踩坑记录模板不是写出来就完事的7.1 模板太长导致 token 膨胀连带成本翻倍我第一次写的 review 模板洋洋洒洒 3500 字想着“细节越多越精准”结果实际用下来每次评审上下文的 token 消耗暴涨成本翻了接近一倍而且效果没有同比提升。原因很简单模型对于长文本的注意力会分散特别是指令之间出现冗余或重复时决策点反而不清晰。后来我把模板裁到 700 字左右只保留步骤编号、严重等级、输出格式、红线效果反而更好。核心原则是模板里的每句话都必须能在 30 秒内读完整否则就是冗余。7.2 CLAUDE.md 和 system prompt 打架Claude 直接懵了有一段时间我的全局模板说“不要输出中文注释统一用英文”但项目 CLAUDE.md 写着“公共函数必须有中文注释”。结果 Claude 的行为变得极其怪一会儿英文一会儿中文甚至在同一段代码里混合出现。排查之后确认是规则冲突了。解决方案是给 CLAUDE.md 增加一条“以项目级规则优先如与全局规则冲突以本文件为准”然后在全局模板里给规则设置一个“可覆盖”。更重要的是我养成了一个习惯写模板时明确哪个规则是“绝对不可覆盖”哪个规则是“默认值”。7.3 模板路径用了相对路径换个目录就失效这事说起来很蠢。我有一次在~/.claude/scripts/collect-context.sh里写了cd ./repo结果从项目的子目录启动时脚本直接找不到路径Claude 拿到空的上下文评审结果完全跑偏。排查链路是这样的先怀疑是模板内容问题后来发现系统报错说找不到collect-context.sh再一查才知道脚本里的相对路径依赖当前工作目录。解决方式是把脚本里所有涉及项目操作的路径都改成动态获取PROJECT_ROOT$(git rev-parse --show-toplevel) cd $PROJECT_ROOT这是个特别基础的问题但特别容易埋下定时炸弹。以后不管是谁跑脚本它都会先找仓库根目录再干活就不会因为启动位置不同而出现诡异行为了。7.4 模板里引用文件列表但没有过滤大文件我还踩过一个坑collect-context.sh会把所有变更文件列出来包括一个 3MB 的 lockfile。Claude 为了“表现好”试图去理解这个 lockfile 里的每一行依赖差异直接把上下文撑爆了。修法也很简单在收集脚本里加一个过滤逻辑超过阈值的大文件只保留文件名不保留内容。这个经验放在其他场景也通用——在任何模板设计里都要主动思考“哪些信息 AI 看了有用哪些只是噪音”。8. 我最终定型的一套增量式模板法踩完这一圈坑之后我的模板策略已经从“一次写个大而全”变成了“增量式、局部可替换”。现在我是这么组织 claude-code-templates 的全局维护一套基准模板每个项目用 CLAUDE.md 覆盖业务上下文再用脚本收集实时状态最后靠 hooks 维持长会话的一致性。这套结构跑了大半年算是稳定下来了。如果你准备照做我的建议是别急着照搬全部先做三件事找出你每周重复次数最多的 3 个任务比如代码评审、写测试、解释老代码针对这 3 个任务各写一份精简模板。给模板仓库建 git每次调整都提交一次方便回溯“哪个改动导致输出变化”。跑两周后只保留真正提升了效率的规则其余全部删掉。模板系统真正有价值的不是“堆规则”而是“沉淀决策”。每一条可靠的规则背后都对应着一次踩坑或者一次团队讨论。把这些东西固化下来AI 才能从一个“懂很多却经常跑偏的助手”变成一个“虽然能力有限但每次都不掉链子的稳定协作者”。如果有时间我下一版模板里最想加的是一个自动更新模块——让模板根据项目最近的 git 历史自动调整部分上下文省掉手动维护 CLAUDE.md 的负担。但目前这套方案已经足够解决我日常 80% 的痛点剩下的慢慢打磨就好。