用Claude Code模板把AI编程工具调教成老同事
先说结论Claude Code 这类 AI 编程工具真正拉开使用体验差距的不是模型版本而是你有没有一套自己的 claude-code-templates。我在连续几个项目里把同一个工具用出过两种极端——有时候它表现得像个熟悉项目的老同事上来就知道该看哪个文件、该用什么模式有时候它又像个第一天入职且不看文档的新人什么都要问问完还自作主张。折腾了大概两个月反复调整规则、试错、和团队对口径之后我把这套东西沉淀成了一组模板现在每个新项目初始化时间从半小时压缩到三分钟。这篇文章就把这套模板的完整思路、实际代码和踩坑过程都摊开讲适合正在用 Claude Code、或者准备把 AI 编程工具引入团队的人参考。1. 为什么我最终整理了一套 claude-code-templates三个让我抓狂的瞬间先说第一个瞬间。每次开新项目我都要对着 Claude Code 把技术栈、目录结构、代码规范重新讲一遍。讲得快还好讲漏了它就开始自由发挥。有一次我忘说service 层禁止直接访问数据库结果它写出来的接口直接绕过 service 层连了数据库测试居然还跑过了。后来 code review 的时候同事盯着那段代码问了我十分钟这是什么设计——其实哪有什么设计就是我没给它交代清楚边界。第二个瞬间是误改无关代码。我让它修一个接口的超时问题它分析完问题之后顺手把另一个不相关文件的函数签名也改了。那个函数被十几个地方调用连锁报错一片红。也不是说完全不能约束但每次都要在对话里加一句不要动无关文件这种话讲多了自己都烦而且下次换了个新会话同样的交代又得重来一遍。第三个瞬间发生在团队协作的时候。同样是给我和同事两个人做辅助Claude Code 给 A 生成代码的风格和给 B 生成的完全是两套A 这边的接口返回 snake_case 字段B 那边返回 camelCase最后联调的时候两个人对着 JSON 字段名互相怀疑人生。这还不算完有的人让它用 pytest有的人让它写 unittest仓库里两套测试框架并存。这三个瞬间叠在一起我意识到问题的根源不在模型本身而在于每次对话的初始上下文都不一样。Claude Code 本身提供了一套机制——通过 CLAUDE.md 文件、Skills、权限配置来预设行为只是我一开始没好好用。于是我把每次用嘴交代的东西全部固化成了文件模板这就是 claude-code-templates 的雏形。它解决的核心问题很简单让 AI 在第一次打开项目的时候就具备我已经调教好的判断力而不是每次都从零开始。2. 模板体系设计三层规则加两层护栏而不是一个孤零零的文件很多人一听到模板就以为是一个文件顶多是一份 CLAUDE.md 复制到各个项目里。实际上要让模板真正稳定生效需要分层设计。我最终定下来的结构是三层规则加两层护栏全局层定义所有项目都适用的底线行为。项目层定义单个项目的技术栈、目录规范、术语表。会话层定义一次会话内部的临时约定。护栏一权限配置控制 Claude Code 能执行哪些命令。护栏二Hooks 脚本在危险操作发生前做拦截。下面展开讲每一层具体放什么。2.1 全局层约等于公司制度全局模板放在~/.claude/CLAUDE.md对所有项目生效。这一层只放违反一次就会出大事的规则比如修改文件之前必须先读取并理解现状不能凭空假设执行删除类命令前必须停下来跟用户确认不要一次做太多事情避免无关重构。内容必须短我控制在 30 行以内。因为 Claude Code 每次会话都会自动加载这个文件加载进上下文是要占用窗口的全局规则写太长会挤占项目相关的有效信息。全局层还有一种特殊用途约定 AI 的输出风格。比如我团队习惯用中文交流但代码注释和提交信息必须用英文这条规则放在全局层最合适因为它在任何项目里都不应该变。2.2 项目层约等于项目手册项目模板放在每个项目的./CLAUDE.md随仓库一起提交。这一层放的是跟项目强相关的内容技术栈和版本、目录结构、编码约定、常用命令、术语表。通常我会把最容易让 AI 犯错的几个点单独强调出来。比如一个 FastAPI 项目最容易犯的错是 service 层里直接写 SQLAlchemy 查询、接口返回 ORM 对象而不是 Pydantic schema。这些内容直接写成禁止性规则AI 一眼能看到。项目层还需要给 AI 提供常用操作路径。比如启动命令是什么、测试命令是什么、lint 规则是什么。AI 知道这些之后执行任务链的时候就不会反复猜测省掉很多来回确认的对话轮数。2.3 会话层约等于当日备忘会话层对应./CLAUDE.local.md这个文件不提交 Git写在.gitignore里。它的作用是记录一些临时性的约定比如本周正在重构用户模块所有涉及 User 模型的改动先跟项目负责人确认这类只对当前阶段有意义、不值得写进项目长期规则的内容。之所以单独拆一层是因为项目级 CLAUDE.md 一旦写进去就很难删——团队成员会默认它是长期约定你想临时加一条两周后作废的规则进去很容易造成理解混乱。用 CLAUDE.local.md 承载临时约定等约定稳定了、确认要长期执行了再提升到CLAUDE.md里。2.4 护栏权限配置与 Hooks权限配置在.claude/settings.json用来控制 Claude Code 能跑哪些 Bash 命令。我一开始没配结果它有一次真的执行了rm -rf来清理临时文件把我一份没提交的本地修改连带删了。从那以后我所有项目都默认带一份 settings.json把高频安全命令列入 allow把高危命令列入 deny。Hooks 是更强的一层护栏。我主要用它做破坏性操作确认当检测到 Claude Code 要执行rm、dropdb、git push --force这类命令时先弹一个确认提示AI 不能继续必须等人点了确认才放行。实际配置在后面的实例里会给到。2.5 组织模板仓库的目录结构把上面的设计落成目录大概是这样的~/.claude/ ├── CLAUDE.md ├── settings.json └── hooks/ └── pre_tool_use.sh project/ ├── CLAUDE.md ├── CLAUDE.local.md └── .claude/ ├── settings.json └── skills/ └── review/ └── SKILL.md我把模板按项目类型分目录维护后面专门讲。这里想强调一个理念模板不是一个文件而是一套初始化一个项目时该有的 AI 工作环境。全局规则管底座项目规则管个性会话规则管临时变化权限和 hooks 管安全边界。五件事都做齐了模板才真正称得上一套。3. 让 AI 真正听得懂的指令写法我沉淀出的五条原则模板文件写出来很简单难的是写出来的规则到底有没有效果。我最初几版模板写了一堆要写出高质量的代码保持代码整洁注意可读性这类话实际操作里几乎全被 AI 当成了耳旁风。后来我把所有无效规则拉出来复盘总结出五条写法原则。3.1 用行为描述不用形容词高质量代码这种词的问题在于无法被校验。AI 不知道你觉得什么叫高质量它的训练数据里对应这个描述的输出可能有上千种。但service 层函数禁止超过 60 行超过必须拆分就非常明确。60 是一个硬数字行数可以被检查如果它违反了你可以直接指出来并让它重写。举两个对照无效写法有效写法写出高质量的、可维护的代码函数超过 60 行必须拆分禁止使用全局可变状态注意数据库性能禁止在循环内查询数据库批量写入使用 bulk_create测试要全面新增 public 方法必须附带 pytest单测文件与被测模块一一对应3.2 给出正反例比讲道理有效模型对禁止 xxx的理解有时候不如应该这样写来得直接。我现在的模板里关键规则都是错误写法 正确写法成对出现。比如- 禁止在 service 层直接使用 db.query正确做法 - 错误db.query(User).filter(User.id uid).first() - 正确user_repository.get_by_id(uid)给出正反例之后AI 的命中率肉眼可见地提升。这其实跟人一样你跟新人说不要乱写他一脸茫然你给他看一份规范代码和一份反例代码他立刻知道边界在哪。3.3 把边界写清楚而不是只写目标很多模板里写确保接口安全AI 就真的只是在函数上加了requires_admin装饰器业务逻辑里的越权一点没管。问题在于安全对 AI 来说太抽象。你需要写的是具体的边界规则比如查询订单详情时必须校验 order.user_id 是否等于当前登录用户 id否则返回 404。这种规则拆到业务级别AI 才不会漏。所以我在模板里专门设了一节安全边界把项目里最容易出现越权、泄露、脏写的场景全列出。代价是要花时间写收益是 AI 生成的代码基本不用再返工安全 review。3.4 重要规则放前面内容宁短勿长Claude Code 加载 CLAUDE.md 之后规则并不是逐字执行而是作为上下文影响模型的判断。文件越长排在前面的内容权重越高后面写的内容可能被前面淹没。这导致一个常见问题模板 200 行AI 只遵守了前 30 行。我后来定了个规矩模板超过 80 行就是危险信号必须砍。怎么砍把操作规范类的内容拆到 Skill 里按需加载把背景知识类的内容拆到 docs 目录里用 显式引用。CLAUDE.md 里只留真正需要每次会话都生效的硬规则。3.5 为术语建立项目词典AI 在项目里经常搞混业务术语。我做过一个电商项目模型里同时有 User登录用户和 Account用户绑定的第三方账户AI 在生成接口时经常把两者交叉引用一会儿用 Account.id 查 User 的订单一会儿把两个模型的字段混在一起。这种问题靠一句注意区分 User 和 Account根本没用。正确做法是在 CLAUDE.md 里写一个术语表用最短的话把每个术语的定义和边界写清楚术语表 - User平台注册用户对应 users 表登录主体。 - Account第三方账号微信、GitHub绑定关系对应 accounts 表。 - 订单Order 属于 User不属于 Account。有了这个词典AI 在生成代码和查询语句时引用模型就准确多了。4. 一套可直接复用的模板实例FastAPI 订单服务的完整配置光讲原则不够我直接给一套现在正在用的模板骨架场景是一个 Python FastAPI 订单服务。你可以直接复制改改就能用。4.1 全局模板~/.claude/CLAUDE.md# Claude Code 全局行为约定 ## 沟通方式 - 使用中文回复代码和终端命令保持英文。 - 先给结论再给必要过程不要长篇大论。 - 不要重复用户已经说过的内容。 ## 工作方式 - 修改任何文件之前务必先读取文件当前内容确认与项目约定一致。 - 一次只完成一个目标不要顺手重构无关代码。 - 在执行删除、覆盖、数据库写入等风险操作前先说明影响范围并等待确认。 ## 输出规范 - 代码遵循项目现有风格不强行引入新风格。 - commit message 一律使用英文格式为 type(scope): summary。这 15 行定义了所有项目的底线不需要每个项目重复写。4.2 项目模板./CLAUDE.md# 项目订单服务Python FastAPI template: python-apiv2.3 ## 技术栈 - Python 3.11 / FastAPI 0.110 / SQLAlchemy 2.x / PostgreSQL 15 - 包管理使用 uv禁止新增 requirements.txt - 测试框架使用 pytest ## 目录结构 - app/api路由层只做参数校验与响应封装 - app/services业务逻辑层禁止直接访问数据库 - app/repositories数据访问层唯一允许写 ORM 查询的地方 - app/modelsSQLAlchemy ORM 模型 - app/schemasPydantic schema禁止在其他层直接返回 ORM 对象 ## 编码约定 - 行宽 100所有代码必须通过 uv run ruff check . - service 层函数超过 60 行必须拆分 - 禁止在循环内查询数据库批量操作使用 bulk_create / bulk_update - 涉及金额、库存的修改必须开启数据库事务 ## 安全边界 - 查询订单详情时校验 order.user_id 是否等于当前登录用户 id否则返回 404 - 所有写操作接口必须显式校验请求体 schema禁止使用 **request.body 这类展开 ## 常用命令 bash uv run uvicorn app.main:app --reload # 启动 uv run pytest # 测试 uv run ruff check . # Lint术语表User平台用户订单的归属主体。Account第三方绑定账号不属于订单模型。Order一笔交易记录属于 User。注意里面有一行 template: python-apiv2.3这是我自己定义的模板版本标记。出现行为异常时可以通过这行信息快速定位是模板问题还是项目定制问题。 ### 4.3 代码审查 Skill.claude/skills/review/SKILL.md markdown --- name: review description: 审查当前分支相对主分支的代码改动输出问题清单和修改建议。当用户要求review 代码、审查 PR、检查这次改动、code review时使用。 --- # Code Review 任务 按以下步骤执行 1. 运行 git diff main...HEAD --stat 获取改动文件清单。 2. 按文件逐个审查重点关注越权、未校验的输入、事务缺失、无测试覆盖。 3. 输出格式 - P0会导致线上事故的问题 - P1功能逻辑错误 - P2代码风格与规范问题 约束 - 只输出审查报告不要直接修改代码。 - 报告用中文代码标识符用英文。 - 每个问题必须给出对应的文件路径和行号。Skill 的好处是把这个流程从每次用嘴要求 AI 怎么审查变成了一个稳定的命令。用户只需要说帮我 review 代码Claude Code 就会自动加载这个 Skill 按流程执行。4.4 权限配置.claude/settings.json{ permissions: { allow: [ Bash(git *), Bash(ls *), Bash(cat *), Bash(uv run *), Bash(curl -I *) ], deny: [ Bash(rm -rf *), Bash(git clean *), Bash(git reset --hard *), Bash(dropdb *), Bash(psql *) ] } }allow 列表里的uv run *已经覆盖了 pytest、ruff、uvicorn不会因为权限卡正常开发流程。deny 列表把物理删除和数据库重建类命令全部挡掉AI 最多只能问你能不能执行不能直接执行。5. 多项目切换与模板版本管理我的实际目录与自动化脚本模板不是写了一版就结束实际用起来会面对两个问题多个项目类型怎么管理、模板更新后怎么同步。我的做法是把模板按项目类型拆开放在~/.claude/templates/下然后用脚本一键应用。5.1 按项目类型拆分模板~/.claude/templates/ ├── python-api/ │ ├── CLAUDE.md │ └── .claude/ │ ├── settings.json │ └── skills/review/SKILL.md ├── frontend-react/ │ ├── CLAUDE.md │ └── .claude/settings.json └──>#!/usr/bin/env bash # apply-template.sh —— 用法: ./apply-template.sh 模板名 目标项目路径 set -euo pipefail TEMPLATE_ROOT$HOME/.claude/templates NAME$1 TARGET$2 if [ ! -d $TEMPLATE_ROOT/$NAME ]; then echo 模板不存在: $NAME 2 exit 1 fi if [ ! -d $TARGET ]; then mkdir -p $TARGET fi cp -rn $TEMPLATE_ROOT/$NAME/. $TARGET/ echo 已应用模板 $NAME 到 $TARGET应用模板只需要一条命令./apply-template.sh python-api ./new-order-service脚本里的-n参数保证不会覆盖目标项目里已经存在的文件。如果你已经写了一段 CLAUDE.md又应用了一个新模板它不会直接把旧文件冲掉这是有意为之的安全措施。5.3 符号链接方案与复制方案的取舍我一开始用的是符号链接方案把模板仓库 clone 到本地然后ln -s到各个项目。好处是模板更新后所有项目同步生效不需要重新复制。坏处也明显一是团队其他成员 clone 项目之后符号链接指向的路径在他们机器上不存在直接坏掉二是终端和 git 工具在 Windows 上对符号链接的兼容性参差不齐。后来我换成了复制方案每个项目初始化时把模板会复制进仓库后续模板更新通过git pull模板仓库再手动合并或者干脆直接改项目里的 CLAUDE.md。对单人项目来说你甚至可以保持符号链接用得很爽但一旦涉及团队协作复制方案是更稳的选择。5.4 用 Git 管理模板版本我把~/.claude/templates整个目录放进了独立 Git 仓库模板的每次调整都有 diff 记录。每次改动模板后打 taggit add ~/.claude/templates git commit -m feat(python-api): add order query permission rule git tag python-apiv2.4项目 CLAUDE.md 第一行的 template: python-apiv2.3就是跟 tag 对应的。线上哪个项目的 AI 行为出了问题我只要看这行就知道它用的模板版本然后git diff python-apiv2.3 python-apiv2.4就能定位是不是模板变更引起的。6. 落地过程中踩过的四个坑从现象到根因的完整排查再完美的模板设计落地过程也会踩坑。我挑四个印象最深的写出来每个都是真实的排查链路不是直接给答案。6.1 坑一模板太长AI 反而失忆第一个版本我把项目模板写到 300 多行事无巨细全往里塞以为越全面越好。结果 Claude Code 在项目里执行任务时频繁忘记规则甚至在代码里用了项目明确禁止的模式。排查过程是这样的我第一反应是模型上下文不够换了更强的模型版本问题依旧。然后我在会话里直接问 Claude Code 一句这个项目的三条核心约束是什么它只答上来第一条另外两条给出的是写出高质量、可维护的代码这种空话。这已经是很明显的证据CLAUDE.md 确实被加载了但内容太长关键规则沉没在中间模型输出时根本没有引用到。修复方式把模板砍到 50 行以内只保留不遵守就会出事的硬约束把如何组织代码、架构怎么拆这类背景知识挪到 docs 里用 显式引用把代码审查这样的多步骤流程拆成 Skill按需触发。验证方法很简单重复上面的问题三条约束完整复述再跑一个实际变更任务行为符合预期。6.2 坑二deny 规则没兜住等价危险命令有段时间我的 settings.json 里 deny 了Bash(rm -rf *)以为安全了。但 Claude Code 有一次修完代码后主动执行了git clean -fdx这个命令会删除所有未跟踪文件行为上等同于一次范围更大的物理删除。我的本地未提交文件就这么被清掉了。排查后发现deny 列表写的是某个精确命令而不是某类危险操作。git clean -fdx不属于rm -rf的字符串匹配范围所以穿过了防线。修复方式是在 deny 里把所有等价危险命令都列进去git clean、git reset --hard、git checkout .、dropdb、truncate。我现在的准则是凡是可能导致数据丢失的命令一律进 deny 列表。验证方式也很直接在对话里让 Claude Code 执行一次git clean -fdx看它是否给出权限不足的反馈。顺便说一句权限配置改完后新会话才生效别像我一样以为它在当前会话里就能立刻拦住。6.3 坑三中英文规则互相覆盖输出风格漂移模板里我先写了一句使用中文回答问题后面的某个项目规则里又写了一句 always use English for commit messages。这个看起来不冲突但 Claude Code 在执行 commit 相关任务时会倾向于把整个回复切成英文团队成员经常收到大段英文分析阅读成本一下就上去了。排查链路比较曲折我先怀疑是全局模板不生效检查了好几遍后来把回复语言这条规则挪到 CLAUDE.md 第一行并把所有语言相关的规则统一成一条才解决。更准确地说问题出在多条语言规则在模型眼里形成了可选的解释空间它倾向于挑更具体的英文规则执行。修复后我在模板里明确写了一句回复语言跟随用户输入语言代码标识符与符号保持英文然后分别用中文和英文提问做回归测试输出语言稳定跟随。6.4 坑四Skill 注册了很多但从未被调用我往.claude/skills/里放了五六个 Skill包括代码审查、依赖升级、接口文档生成。结果实际使用的时候Claude Code 基本都是等我把 Skill 名念出来才执行从来不会主动触发。一开始我以为是机制问题后来翻到 Skill 规范文档才反应过来问题出在 SKILL.md 的 description 写得太泛。我最初写的是help review code这种描述对模型来说没有任何触发信号。改成当用户要求审查代码、review、检查 pull request、code review 时使用之后只要对话里出现与之匹配的意图Skill 就会被自动加载。这个改动让 Skill 的主动调用率显著提升也提醒我写模板不光是写规则连规则何时被触发都要写清楚。7. 模板的持续演进从个人工具到团队规范的体会现在这套 claude-code-templates 已经不只有我在用团队里几个项目都基于它做初始化。我的维护节奏是每两周抽一小时专门整理模板主要做三件事。第一翻出过去两周的 code review 记录如果 80% 的评论集中在同一类问题上——比如没做越权校验——就把对应规则升级进模板。第二删掉那些写了但从来没被触发过的规则。每条规则在模板里都有成本它会占用上下文、可能干扰其他更重要的指令无效规则越少越好。第三每次 Claude Code 版本升级之后专门跑一遍权限配置和 Skill 的回归测试确认配置项没有被意外废弃。最后再分享一个实际体会模板最珍贵的部分不是效率提升而是让新同学加入项目时不用再听人讲半小时背景。给他一份 CLAUDE.md他就能直接开始跟 AI 协作。这套东西的后续扩展方向我也想过——比如针对前端项目、数据管道项目沉淀专属模板——但会等团队实际需求出现再做现在设计得再完整不经过真实项目验证都是空中楼阁。