用 Claude Code 跑了几个正式项目之后,我最想分享的不是某个炫技命令,而是一件特别朴素的事:命令模板和项目模板,才是决定它好用还是难用的分水岭。claude-code-templates 这类实践看起来只是把一堆 Markdown 文件放进了 .claude 目录,但真正把它用明白的人都会发现,这背后是一整套 Agent 协作规范——哪些事让主代理做、哪些事交给子代理、权限边界在哪、项目记忆如何沉淀、命令如何复用。这篇文章就围绕 Claude Code 的模板体系展开,覆盖 CLAUDE.md、自定义斜杠命令、子代理和钩子配置,既适合已经接触过 Claude Code、想把能力工程化的人,也适合刚入门但希望一开始就走对路的新手。
1. 先弄清楚 claude-code-templates 到底在模板什么
第一次使用 Claude Code 的人通常会有一个共同的困惑:我已经给了模型很详细的指令,为什么下一次开新会话它又全都忘了?原因很简单,你在会话里交代的背景、规则、代码库结构,都只存在于那一次的上下文窗口中,会话一关就清零。等到新项目、新需求、新成员加入,一切又要重来。模板化的本质,就是把这些容易流失的上下文,提前固化到仓库里,让模型每次启动时自动读取,而不是依赖你临时输入。
1.1 模板化的起点:告别“每次重新交代”
裸用 Claude Code 一段时间后,你会发现自己成了“复读机”。每个新任务都要重复说明项目技术栈、目录结构、编码规范、测试方式,甚至还要解释一句“遇到问题先看日志,别乱改配置”。这些信息不是不重要,而是每次都临时输入,既浪费时间,又容易遗漏,更麻烦的是每次表述的粒度还不一样——今天说得细一点,明天说得粗一点,模型的表现自然忽高忽低。
我自己的转变点出现在第三个项目。当时同时在维护两个仓库,一个用的 React 18 + TypeScript,另一个是纯 Node.js 服务。两边对话风格完全不同,我每天在会话里反复切换“心智模型”,经常出现我对着 React 仓库说“跑一下测试”,模型却执行了 npm run build 的尴尬局面。后来我把每个项目的技术栈、常用命令、关键约束分别写进各个仓库的 CLAUDE.md,这个问题瞬间消失了。
模板化解决的从来不是“某一次对话能不能成功”,而是“每次对话的基线在哪里”。当你把背景信息前置,模型更像一个熟悉项目的同事,而不是一个每次都等 briefing 的临时工。这也是 claude-code-templates 这类模板库最核心的价值:它把不可见的上下文,变成了可见、可审查、可版本化的文本文件。
1.2 四大核心模板类型:记忆、命令、分工、自动化
Claude Code 的模板体系并不是单一功能,而是由四类可定制组件共同组成的。我用一张表先把它们的关系铺开:
| 组件 | 存放位置 | 实际作用 | 一句话类比 |
|---|---|---|---|
| CLAUDE.md | 项目根目录、~/.claude、.claude/ 下 | 给模型提供长期记忆和项目规则 | 团队Wiki、新人手册 |
| 自定义命令 | .claude/commands/、~/.claude/commands/ | 把可复用的指令固化成斜杠命令 | 快捷键、预设脚本 |
| 子代理 | .claude/agents/ | 让模型在合适场景下调用专项角色 | 团队里的专项工程师 |
| Hooks | settings.json 中的 hooks 字段 | 在工具调用前后自动执行外部脚本 | CI 里的钩子、防火墙 |
这四类组件看起来各自独立,实际经常配合使用。比如你定义了一个 /review 命令,命令正文里可以呼叫 bug-hunter 子代理做深度检查;你还可以在 settings.json 里加一个 PreToolUse 钩子,让 Bash 执行前自动扫描敏感命令。模板库真正成熟的状态,是这四层都能互相衔接,像一个完整的工作流。
值得一提的是,很多人只把“提示词”当模板,这是不够的。真正的模板库还需要考虑模型能用哪些工具、不能碰哪些目录、什么时候触发子代理、命令执行前做什么安全检查。Claude Code 之所以值得模板化,就是因为它给了这些配置一个统一的落盘位置,而不是靠你每次在对话里用自然语言约束。
1.3 模板库的边界感:不是越多越好
claude-code-templates 这类项目看上去很丰富,但如果你盲目模仿,把所有见过的模板都塞进 .claude 目录,很快就会失控。我自己就见过一个“豪华”模板库:CLAUDE.md 写了 300 行,十几个命令覆盖从代码生成到周报撰写的所有场景,结果模型每次启动都要先读一大段规则,命令调用时反而变得犹豫不决。
我建议在搭建模板库之前,先建立边界意识。适合模板化的东西有三个特征:重复出现、规则稳定、流程可预测。比如代码审查、提交信息生成、单元测试补全、新模块初始化,这些都是高频且模式固定的任务。不适合模板化的则是另一类:一次性的探索研究、频繁变化的临时任务、需要大量人工判断的开放性问题。把这些塞进模板,只会让模型用一套死板框架去处理灵活问题,效果反而更差。
边界感的另一个含义是分层。个人习惯和项目规范不要混在一起写,通用命令和项目专属命令也要分开目录。否则就会出现一种尴尬情况:你在 A 项目里顺手加了一个“解析日志”的命令,换到 B 项目时它依然存在,而 B 项目并没有这种日志格式。模板库不是收藏夹,它的价值在于精确匹配场景,而不是追求“什么都有”。
2. 三块最核心的模板:CLAUDE.md、命令、子代理
如果你只想先搭一个最小可用的模板库,不用贪多,把三样东西做好就够了:一份 CLUDE.md、两三个高频命令、一个子代理。这三样东西分别解决记忆、操作和分工的问题,已经能覆盖大部分日常工作。下面的内容我会逐一拆开讲,并给出可以直接改用的模板文本。
2.1 CLAUDE.md:先定项目记忆,再谈效率
CLAUDE.md 是 Claude Code 的项目记忆文件。模型在每次会话开始前会主动读取它,你可以把它理解为“给 AI 同事看的新人手册”。这份文件写得好不好,直接决定模型对项目的理解程度,也决定你后面每一句指令的执行质量。
我见过不少团队把 CLAUDE.md 当成需求文档来写,堆砌大量背景介绍和业务术语,其实这恰恰违背了它的用途。模型不需要一篇漂亮的项目简介,它需要的是“在这个仓库里做事时,有哪些约束和流程”。我的写法通常包含这几个板块:项目定位与技术栈、常用命令、目录结构、编码规范、工作流、明确禁忌。
# 项目记忆 ## 项目定位 这是一个面向中小团队的任务协作系统,核心模块包括任务看板、消息通知和成员权限。 ## 技术栈 - 前端:React 18 + TypeScript + Vite - 状态管理:Zustand - 后端:Node.js + Fastify - 数据库:PostgreSQL 15,ORM 使用 Prisma - 测试:Vitest + Testing Library ## 常用命令 - 启动开发环境:npm run dev - 运行测试:npm run test - 代码检查:npm run lint - 数据库迁移:npx prisma migrate dev ## 目录结构 - src/api:后端接口层 - src/components:通用组件 - src/features:按业务模块划分的功能代码 - prisma:数据库模型与迁移文件 ## 编码规范 - 组件必须显式定义 props 类型,禁止使用 any - 新接口必须附带错误码定义,不允许返回裸字符串错误 - 数据库迁移文件必须独立提交,不能与业务代码混在一起 - 所有用户可见文案统一放在 messages 配置中 ## 工作流 1. 新需求先拆解任务,再动手改代码 2. 提交代码前必须跑一遍 lint 和 test 3. 涉及数据库结构变化时,先检查迁移脚本再写业务逻辑 ## 禁忌 - 不要直接修改 lock 文件 - 不要在生产环境开关调试日志 - 不要把第三方 API 密钥写入代码这段示例的核心思路是把“模型最容易搞错的事”前置。技术栈和命令是为了让它在执行 shell 时少猜;目录结构是为了让它读写文件时走对地方;工作流和禁忌则是为了让它不要自作主张。注意,示例里没有写任何空话,每一条都是可执行的动作。
关于篇幅,我的经验是:整份 CLAUDE.md 最好控制在“三分钟内能读完”的体量。模型每次读取并理解它的时间是有限的,内容越长,有效信息密度反而越低。如果项目特别复杂,可以用 @ 导入子文件,把某个模块的详细说明拆分到独立文档里,主文件只保留索引和核心约束。
2.2 自定义命令模板:把斜杠命令当成微服务
如果说 CLAUDE.md 是模型每天要读的“员工手册”,那么自定义命令就是你可以随时调用的“快捷工具”。Claude Code 支持自定义斜杠命令,方式很简单:在 .claude/commands 目录下放一个 Markdown 文件,文件名默认为命令名,例如 review.md 对应 /review。文件内容的头部是 YAML 格式的 frontmatter,正文就是你希望模型执行的指令文本。
--- description: 对当前改动发起一次代码审查 argument-hint: <改动范围,例如 src/features/login> allowed-tools: Read, Bash, Grep --- 请以资深代码审查者的身份,对 $ARGUMENTS 指定的改动进行审查。重点检查以下几个方面: 1. 安全性:是否引入越权访问、注入风险、敏感信息泄漏 2. 可维护性:命名是否清晰,函数是否过长,是否存在过度嵌套 3. 性能问题:是否存在明显的 N+1 查询、无谓的重复计算 4. 边界情况:是否处理了空值、并发、失败重试 输出时按以下结构组织: - 严重问题(必须修改) - 建议问题(可以优化) - 做得好的地方 如果 $ARGUMENTS 为空,先执行 git diff HEAD 查看当前改动,再开始审查。这段模板里有几个设计点,值得展开说。
frontmatter 中的 description 不只是给人看的,模型会依据它来判断“什么时候该建议用户使用这个命令”。如果你把 description 写成“代码审查”,太宽泛;写成“当用户准备提交代码或合并请求时,对指定范围进行安全性、性能和可维护性审查”,模型就能更准确地匹配场景。
argument-hint 是给用户的参数提示。它在命令调用时提醒用户输入什么内容,避免出现“命令打开了却不知道填什么”的尴尬。allowed-tools 则是权限边界,它限制了模型执行这条命令时能使用的工具。我特意只给了 Read、Bash、Grep,而没有给 Write,目的是让审查过程保持“只读”,防止模型在审查中顺手改写代码。
正文部分的核心是“给模型一套确定的工作语言”。如果你只说“请审查代码”,模型可能输出一大段抽象评价;当你要求它按“严重问题、建议问题、亮点”三分法输出,并且明确检查维度时,结果立刻变得可操作。这就是模板和普通对话的最大区别:模板是在帮你固定输出质量。
2.3 变量传递与参数处理:$ARGUMENTS 的写法与坑
上面的 review 命令里用到了$ARGUMENTS,这是 Claude Code 命令模板里的关键变量,它代表用户在斜杠命令后面输入的内容。比如你敲/review src/features/login,那么$ARGUMENTS的值就是src/features/login。这个机制让一个模板可以被重复用于不同对象,而不需要为每个文件单独建一个命令。
使用$ARGUMENTS时最常踩的坑,是把它写进了 Bash 代码块里,结果被 shell 先解析了。Claude Code 的命令模板本身是 Markdown 文本,但里面如果包含 bash 代码块,模型可能会把变量当成 shell 变量处理,于是$ARGUMENTS在执行时被展开成空字符串或直接被 shell 报错。我习惯的做法是:在正文里用自然语言描述“用户输入的内容是 $ARGUMENTS”,并让模型自己根据需要把这段内容拼接到命令里,而不是把$ARGUMENTS硬塞进代码块。
--- description: 查看指定文件的近期改动历史 argument-hint: <文件路径> --- 运行 git log -p -- <文件路径> 查看该文件的提交历史,其中文件路径来自用户输入:$ARGUMENTS。 请用通俗的语言总结最近的变更,重点标出影响其他模块的风险点。在这个示例中,$ARGUMENTS出现在自然语句里,模型读取后会把实际路径替换进去执行。这样既避免了 shell 展开问题,也让模型有机会对参数做合法性和路径校验。部分场景下你也可以用\$ARGUMENTS进行转义,但我的经验是“尽量让模型理解意图,而不是让模板去做字符串拼接”。
另外,Claude Code 还提供了一些内置环境变量,比如与当前项目目录、操作系统平台相关的变量。不同版本支持情况不同,最可靠的办法是在你安装的版本里输入/help或查看官方 CLI 的帮助输出,确认当前版本支持哪些变量。模板里的依赖越少,跨版本迁移时的兼容性越好。
2.4 子代理模板:给 AI 分工,而不是让它什么都干
子代理是模板体系中容易被忽略、但价值极高的一块。它允许你定义一个“拥有独立角色、独立上下文、独立工具权限”的专用 AI 执行者。主模型在对话过程中,可以根据场景把任务转发给合适的子代理。你可以把子代理理解为团队里的专项工程师,比如专门抓 Bug 的人、专门整理 API 文档的人、专门做重构的资深工程师。
在 .claude/agents 目录下创建一个 Markdown 文件,例如 bug-hunter.md:
--- name: bug-hunter description: 当需要定位 Bug、分析异常堆栈、排查测试失败或复现问题时使用。不要在处理普通功能开发时调用。 tools: Read, Grep, Bash model: claude-3-5-sonnet-20241022 --- 你是一名专注的缺陷猎人。你的职责是在代码中找到问题的根因,而不是给出临时的补丁。 工作步骤: 1. 先复现问题,理解触发条件 2. 沿着调用链追踪数据流向,找到异常来源 3. 查看相关测试和日志,寻找线索 4. 输出结论时说明:根因在哪、哪个改动引入的、影响范围、建议修复方向 注意: - 如果没有看到实际报错信息,不要凭空猜测 - 不要为了找 Bug 而大范围重构代码 - 输出要简短,直接说结论这段模板里最关键的是 description。主模型会依据这段文字判断“什么时候调用 bug-hunter”,所以不能写得太宽泛。如果你写的是“帮助解决代码问题”,那几乎每个编码任务都可能触发调用,子代理反而变成干扰。如果你明确写出“当需要定位 Bug、分析异常堆栈、排查测试失败时使用,不要在处理普通功能开发时调用”,主模型就能更精确地做出判断。
子代理的 tools 字段同样重要。bug-hunter 我只给了 Read、Grep、Bash,这三个工具足以完成排查,又不至于让它有机会乱改文件。有些资料把 agents 当成“多模型协作”来宣传,实际使用中最直接的价值其实是专注力隔离:子代理在自己的上下文窗口里工作,不会把大量无关日志和代码片段塞进你主会话的上下文中。模板化的子代理不是让 AI 数量变多,而是让每个 AI 的上下文变得更纯粹。
3. 实操:从零搭一套 claude-code-templates 目录
理论讲再多,不如直接搭一套目录。下面我给出一个经过两个项目验证的模板库结构,你可以直接照搬,再按自己的技术栈调整。这套结构遵循一个原则:个人习惯不进项目,项目规范不进个人,命令与代理分离,钩子单独管理。
3.1 目录结构:用户级、项目级、命令与代理分开
Claude Code 的配置可以分为两个作用域:用户级和项目级。用户级配置放在~/.claude/下,适合放你的个人常用命令和通用习惯;项目级配置放在仓库根目录的.claude/下,随 git 一起提交,团队每个人拉下来都能共享。这里我展示一套完整的目录骨架:
~/.claude/ └── CLAUDE.md # 个人通用习惯与全局规则 <你的项目根目录>/ └── .claude/ ├── CLAUDE.md # 项目记忆,随仓库提交 ├── commands/ │ ├── review.md # /review 代码审查 │ ├── commit.md # /commit 生成提交信息 │ ├── test.md # /test 生成并运行测试 │ ├── fix.md # /fix 定位并修复问题 │ └── init.md # /init 初始化新模块 ├── agents/ │ ├── bug-hunter.md # 缺陷排查专用子代理 │ └── docs-writer.md # 技术文档撰写子代理 └── settings.json # hooks 与输出配置这样分层的最大好处是场景清晰。个人 CLAUDE.md 里写的可能是“我习惯用中文回复”“我偏好使用 pnpm 而不是 npm”,这些属于个人偏好,不该要求每个协作者都遵守。而项目 CLAUDE.md 里写的是这个仓库的技术选型、目录规范、工作要求,这些需要所有人共用,所以必须随仓库走。命令也一样,通用的 commit 模板可以放用户级,和某个项目强相关的“初始化本项目模块”命令就应该放项目级。
我建议新人在最初一个月只维护项目级配置,不要急着往用户级塞东西。因为个人习惯还没定型,过早固化可能会让你迁就模板而不是让模板服务你。等你在两三个项目里稳定使用某一套命令后,再把它提升到用户级,这才是更稳健的节奏。
3.2 几个最高频的命令模板:review、commit、test、init
review、commit、test 和 init 是我在项目中最常用的四个命令,它们背后的设计思路也各不相同。我逐个给出模板,并解释每一处设计意图。
第一个是 commit.md,它的作用是帮你生成符合约定式提交规范的提交信息。
--- description: 根据暂存区内容生成符合 Conventional Commits 规范的提交信息 argument-hint: <可选:本次提交的说明> --- 请先运行 git diff --staged 查看暂存区的改动,然后生成一份提交信息。 要求: 1. 使用 Conventional Commits 格式:type(scope): subject 2. type 取值优先级:feat / fix / refactor / docs / test / chore 3. subject 简洁,不超过 50 个字符 4. 正文按原因、影响、验证结果三个部分展开 如果暂存区为空,先提示我运行 git add,不要强行生成。这个模板的设计点在于“先看暂存区再生成”,并且明确要求“暂存区为空时不要强行生成”。很多模型在生成提交信息时会脑补改动内容,加上这条约束后,它就会先去检查真实差异,避免了“提交信息写得漂亮,实际改动完全不匹配”的尴尬。同时,它把提交信息的格式、长度、结构全部固定,你每次提交都有一致体验。
第二个是 test.md,它的目标是快速为模块补上测试。
--- description: 为指定模块生成/补全单元测试 argument-hint: <模块路径,例如 src/features/task> --- 请读取 src/features/task 目录下的代码,基于 Vitest 和 Testing Library 为该模块补充单元测试。 测试覆盖要求: 1. 核心逻辑的 happy path 和错误分支 2. 关键工具的边界输入(空值、超长、非法格式) 3. 涉及异步请求的部分使用 mock,不发起真实网络调用 输出测试文件路径,并运行 npm run test 验证。这个模板的价值在于把“测试策略”前置了。如果你只让模型“写测试”,它可能只补几个 happy path 用例自娱自乐。当你在模板里明确写出“错误分支”“边界输入”“异步 mock”这几个要求时,生成的测试质量会明显提升。最后还要求它实际运行测试验证,把“写完”和“通过”绑定在一起。
第三个是 init.md,适合在开始一个新模块时快速建立骨架。
--- description: 按项目惯例初始化一个新业务模块 argument-hint: <模块名称> --- 请为 $ARGUMENTS 这个新模块创建以下骨架: 1. 在 src/features 下创建对应目录 2. 生成 index.ts 作为统一导出入口 3. 生成 types.ts 放置接口定义 4. 生成组件目录,并放置空的规范示例组件 5. 生成该模块的测试文件占位 创建前先阅读 CLAUDE.md,遵循项目既有的目录命名和代码规范。init 命令的好处是把“项目惯例”从一句话变成可执行的结构。新模块该有哪些目录、哪些文件、哪些规范,模型不需要猜,模板已经把答案告诉它了。这也体现了模板库的复利效应:你最初为了自己方便写下的 init 模板,之后每个新成员都能用到。
3.3 把模板接上 hooks:关键动作前自动执行
hooks 可以理解为模板体系的自动化层。它们不像命令那样由你手动触发,而是在特定事件发生时由 Claude Code 自动执行外部脚本。一个最常见的用途,是在模型调用 Bash 工具之前做安全检查。
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "node .claude/hooks/check-bash.js" } ] } ], "PostToolUse": [ { "matcher": "Write", "hooks": [ { "type": "command", "command": "node .claude/hooks/check-todos.js" } ] } ] } }在这个配置里,PreToolUse 会在模型执行任何 Bash 命令前先运行 check-bash.js。这个脚本可以扫描命令中是否含有危险操作,比如强制删除目录、输出密钥等,一旦命中就返回错误码,直接阻止模型执行。PostToolUse 则会在模型写完文件后运行 check-todos.js,比如检查是否在注释里留下了 TODO、HACK 等标记。
hooks 和模板命令是互补的。命令负责“你让模型做什么”,hooks 负责“模型做事时不能越界”。当你把两者结合起来,模板库才真正具备工程化基因。尤其是多人协作时,模型误删文件或者写入错误配置的代价很高,一个简单的 PreToolUse 钩子能把大量低级事故拦截在发生之前。
3.4 如何保持模板库干净,而不是成为垃圾场
模板库最忌讳“贪多”。我见过有人一口气建了二十多个命令,最后自己都记不清每个命令的差异,模型调取时也会因描述重叠而选择困难。我的经验是,新增一个模板前先回答三个问题:这个任务我重复了几次?它的流程是否已经稳定?它是否有明确的输入和输出?如果三个问题的答案都是肯定的,再考虑添加。
模板库还应该像代码一样接受审视。我要求自己在合并模板前做一次“命令评审”:挑出命令正文里含糊的表达,删掉与现有模板重复的部分,确认允许使用的工具没有过度授权。这听起来有点繁琐,但坚持下来后模板越多越不混乱。
另一点是定期清理。每两到三周我会检查一次:哪些命令从来没被调用过?哪些 CLAUDE.md 规则实际上没帮到模型,只是自我安慰?与其保留这些“僵尸模板”干扰模型判断,不如果断删除。模板库的维护本质上是权限管理,不是资产积累。
4. 模板库维护中的常见问题与避坑清单
再好的模板库,也会在实际使用中遇到各种问题。我把自己踩过和见过的坑整理成了几类,并给出排查思路。这些问题大多藏在细节里,不看日志很难发现,但一旦弄清楚,后面的使用就会顺畅很多。
4.1 命令不加载、不生效怎么排查
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 斜杠命令不存在 | 文件没有放在 commands 目录下 | 确认路径是 .claude/commands/ 或 ~/.claude/commands/ |
| 文件名带空格 | 命令名解析失败 | 文件名使用小写字母和连字符,避免空格 |
| frontmatter 格式错误 | YAML 解析失败 | 检查 key 是否拼写正确,不要用 tab 缩进 |
| 命令内容没更新 | 会话还保留旧上下文 | 新开一个会话再测试命令 |
| 项目级与用户级冲突 | 同名的项目命令覆盖了用户命令 | 查看两边文件内容,确认哪个是预期的 |
| 描述过于模糊 | 模型无法判断何时调用 | 把 description 改得更具体,写清触发场景 |
排查这类问题有一条通用路径:先确认文件路径是否被正确识别,再看 frontmatter 是否有语法错误,最后看命令正文是否需要依赖特定的变量。大部分“命令不生效”其实都不是代码问题,而是路径和文件格式问题,这类错误通过claude的诊断信息或直接查看目录列表就能定位。
4.2 提示词“变笨”了?模板过载是元凶
随着模板库膨胀,一个很微妙的问题会出现:模型的行为开始变得奇怪,明明是很简单的需求,它却犹豫不决,或者非要套用某条规则。这往往不是模型能力的问题,而是你的模板过载了。CLAUDE.md 越长、规则越多,模型的注意力就越分散,优先级也越难以判断。
更糟糕的是规则冲突。比如你的 CLAUDE.md 写着“所有改动必须补测试”,但某个高频命令模板里却写着“这是快速原型,不需要测试”。这两个规则同时出现在上下文中时,模型并不知道哪个优先级更高,只能随机选择一个执行。这种冲突比没有规则更危险。
我解决冲突的方法是给规则分级:在 CLAUDE.md 里明确“命令模板中的指令优先于全局规则”“本项目内部的 init 命令可以跳过测试生成,手动提交时仍需要测试”。同时定期把 CLAUDE.md 通读一遍,凡是发现两条表述相抵触的规则,立刻合并或删除一条。规则越少,每条规则在模型决策时的话语权就越大。
4.3 变量展开、工具限权与子代理误调的实战教训
变量问题我前面已经提过,这里再说一个真实场景:有一次我在命令正文里写了$ARGUMENTS,但那段文字被放在了 bash 代码块中,模型执行时把变量当作 shell 变量,展开成了空值。命令看似运行成功,实际上根本没拿到用户输入。从那以后再写命令,我都会反着检查一遍:这段文本如果被当成 shell 脚本执行,会不会出错?如果会,就把它改成自然语言描述。
工具限权的教训来自一次“好心办坏事”。原本我只是让命令生成一段测试代码,结果允许了 Write 工具,模型“顺手”把现有测试文件也重写了一遍,还改了配置文件。虽然这些改动可能不是恶意的,但完全超出了我的预期。从那以后,凡是只读类命令,我只会给 Read、Grep、Bash;只有明确要求写文件时才会放 Write。权限不是摆设,它是模板库的最后防线。
子代理误调也很常见。我给第一个子代理写的 description 是“帮助分析代码”,结果主模型几乎在每个任务里都优先调用它,导致子代理频繁接手、上下文被浪费。后来我把 description 改成更严格的触发条件:“当用户明确要求定位 Bug 或分析异常堆栈时调用,常规功能开发不要使用”,误调率立刻降了下来。子代理的设计原则是让主模型容易判断“这件事不该我干,该它干”,而不是“这件事它也能干”。
4.4 迭代节奏:模板库是养出来的,不是搭出来的
模板库不需要第一次就完美,它更适合在真实项目中慢慢养起来。我的习惯是在每个功能开发完成后问自己一句:“刚才这个过程,是不是可以沉淀成一个模板?”于是 commit、review、test 这些命令都是在重复中出现并逐渐成形的。真正好用的模板一定是从你自己的工作流里长出来的,而不是从别人仓库里复制过来的。
我还会在项目迭代到一定阶段后做一次“模板复盘”:对照最近两周的对话历史,看看哪些命令被高频调用,哪些规则在模型自我修正时确实起了作用。保留有效的部分,删掉从未触发或触发后反而造成干扰的部分。模板的版本记录也值得做,我会在命令文件里加一段注释说明“这个模板为什么存在、为哪个场景服务”,这样三个月后再回头整理时不至于忘记当初的设计意图。
这个习惯带来一个非常实际的好处:当你换新项目时,带过去的不是一堆无脑复制的文件,而是一套经过验证的协作约定。你只需要花十几分钟改改 CLAUDE.md 里的项目信息,剩下的命令和代理可以原封不动地复用,因为它们本身就是从真实工作流里提炼出来的,换个项目照样适用。
我自己现在接手一个新项目,第一件事通常就是拷贝一套 .claude 目录进去,再花十分钟把 CLAUDE.md 里的项目定位和技术栈填完。这样做的作用不是让 Claude Code 变聪明,而是让每一次对话的起点都站在同一个语境上:模型知道技术栈、知道工作流、知道什么叫做好,也知道什么不能碰。真正省下来的时间,不是某一次点击命令省出的几秒,而是后面几十次会话里不再重复交代背景、不再被反复纠正习惯。模板库这个东西,一开始维护会觉得麻烦,坚持两三个项目之后,你就再也回不去了。