CLAUDE.md 最佳实践:让 Claude Code 稳定执行的模板与检查方法
用一份精简模板、三个实务场景和可运行的检查脚本,写出真正能减少 Claude Code 返工的 CLAUDE.md。
同一条审查意见已经出现第三次:Claude Code 改对了功能,却漏跑项目规定的测试;它顺手改了任务范围外的数据库迁移;或者桌面端看起来正常,手机端却发生横向溢出。每次都把提示词写得更长,并不能解决这个问题。
真正缺少的通常不是又一段临时提示,而是一份短小、稳定、能够检查的项目规则。CLAUDE.md 的作用,就是在工作开始前告诉 Claude Code:这个仓库怎么运行、哪些地方不能随意改、结束前必须验证什么。它不需要复述整份 README,更不该塞进公司的所有制度。
本文从第一份可用文件开始,说明内容该放在哪里、哪些限制必须交给权限和 hooks,以及如何用一段可执行的 Node.js 脚本验证结果。
先看结论
一份有用的 CLAUDE.md 应当保存大多数任务都会用到的命令、修改边界和审查门槛。开始编写前,先记住以下五点:
- CLAUDE.md 是给 Claude Code 的持续性指导,不是访问控制系统。
- 团队共享规则放在仓库根目录;个人机器上的备注放在
CLAUDE.local.md;仅适用于特定路径的规则放在.claude/rules/。 - 尽量控制在 200 行以内。与其解释背景,不如写清文件路径、执行命令和通过条件。
- 涉及安全的禁止事项不能只靠文字,应同时使用 permissions 或 hooks 阻止危险操作。
- 新增规则后要拿一个真实的小任务验证,确认它确实改变了可观察的结果。
不要在第一天追求“终极版本”。先回看最近三次代码审查,找出重复出现的意见;只有以后还会影响判断的内容,才值得成为长期规则。
Claude Code 可以负责什么,哪些必须由人决定
仓库说明文件与权限边界解决的是两类问题。Claude Code 可以搜索已有代码、按照明确范围修改文件、运行指定检查并总结差异。产品政策、生产环境发布,以及涉及客户、金钱、隐私或法律义务的决定,仍然由人负责。
| 决策环节 | 交给 Claude Code | 必须由人判断 |
|---|---|---|
| 调查 | 查找相关文件、既有实现模式和测试 | 是否允许查看客户资料或合同数据 |
| 实现 | 在指定范围内修改代码与测试 | 价格、授权、法律条款和客户可见政策的变更 |
| 验证 | 运行 lint、类型检查、测试和构建 | 是否满足验收条件、是否批准发布 |
| 维护 | 报告修改文件与未解决风险 | 是否把某条经验升级为仓库长期规则 |
CLAUDE.md 表达的是“请按这个顺序检查”,无法保证破坏性命令绝不执行。如果必须阻止 git push --force、生产数据库访问或读取含密钥的文件,应配置 permission deny 规则,或在 PreToolUse hook 中确定性地拦截。具体做法可参考Claude Code 权限设置指南。
动笔前先确定规则的作用范围
文件放置位置决定规则会影响哪些工作。仓库根目录的 CLAUDE.md 适合团队共用规则;~/.claude/CLAUDE.md 会作用于该用户的多个项目;CLAUDE.local.md 适合不提交到 Git 的机器专用备注。大型 monorepo 则可以借助嵌套文件和路径规则,避免每个任务都加载无关内容。
repo/
CLAUDE.md # 团队共享的简短规则
CLAUDE.local.md # 个人备注;加入 .gitignore
.claude/
rules/
api.md # 只适用于 API 文件的规则
packages/
admin/
CLAUDE.md # 读取该子目录时追加的规则
启动时,Claude Code 会读取当前目录及其父目录中适用的说明文件。子目录里的 CLAUDE.md 会在 Claude 读取该目录下的文件时加载。因此,支付模块的专用规则应靠近支付模块,而不是全部堆在根文件里。
@docs/project-map.md 之类的 import 有助于整理结构,但不会节省上下文;被导入的内容仍会在启动时加载。根文件只保留始终需要的判断,详细资料则写成按需读取的路径。Windows 环境中 Claude Code 直接读取的是 CLAUDE.md;如果项目还维护 AGENTS.md,显式写入 @AGENTS.md 比依赖符号链接更可靠。
从这份 CLAUDE.md 模板开始
命令、边界和完成条件最好能在一个屏幕内看完。下面的模板没有“写出高质量代码”这类无法验收的口号,而是明确指出项目位置、检查命令、禁止范围和最终报告内容。
# Project Instructions
## Project map
- App: Next.js 15 + TypeScript
- API: src/app/api/**
- Database schema: prisma/schema.prisma
- Tests: Vitest for units, Playwright for checkout
## Commands
- Install: npm ci
- Type check: npm run typecheck
- Unit tests: npm test
- Lint: npm run lint
- Build: npm run build
## Change rules
- Follow nearby code before adding a new abstraction.
- Do not change auth, billing, or migrations unless the task names them.
- When an API handler changes, update validation and tests together.
- Never place secrets in code, fixtures, logs, or screenshots.
## Review checklist
- Run the checks related to the changed files.
- Test an error path as well as the happy path.
- Report changed files, commands run, and skipped checks.
团队完全可以用中文维护 CLAUDE.md,关键不是语言,而是另一位审查者能否得出相同结论。把“适当测试”改成 npm test;把“遵循现有架构”改成“API 响应统一使用 src/lib/api-response.ts”。规则越能被观察和验证,执行结果越稳定。
三个实务使用场景
下面三个场景都把输入、输出和人工审查分开。不要因为一句话听起来合理就立即写进长期规则;先用一个小任务运行一次,再判断它是否减少了返工。
使用场景 1:减少网站制作公司的重复审查意见
制作公司经常为不同客户维护不同的 CSS 命名、图片尺寸和浏览器支持范围。把整本公司手册复制进每个项目,只会把真正有用的规则淹没。每个客户仓库应只保留三到五条反复使用的检查条件。
输入: 最近三次审查讨论、任务涉及的文件、仓库现有的 lint 和 build 命令。
输出: 一份差异报告,列出复用的组件、修改的页面、执行过的检查,以及尚未覆盖的浏览器条件。
人工审查: 设计意图、图片版权、CTA 文案和手机端最终布局。可比较规则加入前后各十个任务的退回次数,而不是用 CLAUDE.md 的长度判断效果。
使用场景 2:安全修改 SaaS 咨询表单
表单外观看似正常,服务器端校验、通知邮件或错误处理却可能已经损坏。项目规则应指出:修改表单时,哪些文件与测试必须一起检查,而不是只要求“注意表单安全”。
输入: 表单组件、输入 schema、API handler、邮件模板和现有测试。
输出: 正常提交与非法输入的测试、用户可理解的错误信息,以及变更过的设置列表;最终报告还要确认个人信息没有进入日志。
人工审查: 收集字段是否必要、保存期限、通知收件人和生产发布。衡量结果时同时观察提交失败数、支持处理时间与转化率。
使用场景 3:避免内容网站发布不完整页面
一篇 MDX 文章即使正文正确,也可能因为缺少 description、内部链接、主图或可用的移动端代码块而影响搜索流量与广告收益。短小的发布清单能给 Claude Code 一个明确终点。
输入: MDX 文件、frontmatter schema、内部链接目标、build 命令与生产 URL。
输出: description 字数、失效链接结果、代码块检查、构建状态,以及在浏览器中检查过的 URL。
人工审查: 事实准确性、搜索意图、广告位置、阅读体验与发布批准。每周应同时查看搜索点击、有效阅读和 CTA 点击,不能只看 PV。
用可运行脚本检查 CLAUDE.md
下面的 Node.js 脚本检查文件行数、三个必需标题,以及几种高信号的密钥格式。将它保存为 check-claude-md.mjs,使用 Node.js 20 或更高版本运行。
import { readFile } from "node:fs/promises";
const filePath = process.argv[2] ?? "CLAUDE.md";
const text = await readFile(filePath, "utf8");
const lines = text.split(/\r?\n/);
const lineCount = text.endsWith("\n") ? lines.length - 1 : lines.length;
// Pass localized H2 names as the third argument, separated by "|".
const requiredHeadings = (
process.argv[3] ?? "Commands|Change rules|Review checklist"
)
.split("|")
.map((heading) => heading.trim())
.filter(Boolean);
const h2Headings = new Set();
let fenceMarker = null;
for (const line of lines) {
const fenceMatch = line.match(/^\s*(`{3,}|~{3,})/);
if (fenceMatch) {
const marker = fenceMatch[1];
if (fenceMarker === null) fenceMarker = marker;
else if (marker[0] === fenceMarker[0] && marker.length >= fenceMarker.length) fenceMarker = null;
continue;
}
if (fenceMarker !== null) continue;
const heading = line.match(/^##\s+(.+?)\s*$/)?.[1];
if (heading) h2Headings.add(heading);
}
const secretPatterns = [
["AWS access key", /AKIA[0-9A-Z]{16}/],
["GitHub token", /gh[pousr]_[A-Za-z0-9]{20,}/],
["assigned secret", /\b(api[_-]?key|password|token)\s*[:=]\s*["'][^"'\n]{8,}["']/i],
];
const failures = [];
if (lineCount > 200) failures.push(`too many lines: ${lineCount} (max 200)`);
if (requiredHeadings.length === 0) failures.push("required heading list is empty");
for (const heading of requiredHeadings) {
if (!h2Headings.has(heading)) failures.push(`missing h2: ${heading}`);
}
for (const [label, pattern] of secretPatterns) {
if (pattern.test(text)) failures.push(`possible secret: ${label}`);
}
if (failures.length > 0) {
console.table(failures.map((problem) => ({ problem })));
process.exitCode = 1;
} else {
console.log(`CLAUDE.md check passed: ${lineCount} lines`);
}
本地与 CI 都可以使用同一个命令:
node check-claude-md.mjs CLAUDE.md
# 使用中文H2标题时
node check-claude-md.mjs CLAUDE.md "命令|修改规则|审查清单"
这个脚本不是完整的密钥扫描器。实际项目还应配合 GitHub secret scanning 或专用扫描工具。发现真实凭据后,需要根据风险从历史记录中移除并立即吊销;只删除当前文件里可见的一行并不够。
常见陷阱:文件越来越长、规则无法验收、安全只靠文字
陷阱 1:每次审查后都继续加规则。 原因是还没确认问题会不会再次发生,就把所有意见都变成永久要求。修复方法是只记录重复出现的决定,添加前先删除过期命令,并把包专用内容移动到对应子目录。
陷阱 2:指令没有通过条件。 “保持高质量”或“遵循原有设计”无法让两位审查者做出同样判断。应写出目标路径、执行命令、期望的退出码、要检查的浏览器宽度或具体测试名。
陷阱 3:把 CLAUDE.md 当作安全边界。 “绝不修改生产环境”只是文字,并不会生成物理屏障。危险命令应加入 permission deny;必须确定性中止的操作应交给 PreToolUse hook。CLAUDE.md 只保留禁止原因和获准的替代流程。
陷阱 4:import 变成隐藏的知识仓库。 常见误解是“放在另一个文件就不占上下文”。实际上导入内容会在启动时加载。根文件只留下短判断规则,长说明则提供路径或 URL,让 Claude 在任务确实需要时再读取。
防止文档逐渐失效
维护 CLAUDE.md 应采用与代码相同的习惯:查看 diff、运行检查器,再用一个有代表性的小任务验证。命令、路径或架构已经不存在时,对应规则也要删除。
每月一次的轻量审查只需回答四个问题:
- 哪条审查意见重复出现过?
- 哪条指令被忽略,或被两个人解释成不同意思?
- 哪个命令或路径已经过期?
- 哪条警告应该升级为 permission 或 hook?
不要把 token 数量或文件长度当成主要绩效。更有用的指标是审查退回次数、合并前拦下的失败检查数量,以及重复解释仓库基础知识所花的时间。数字没有改善,就应重写或删除规则。
常见问题
CLAUDE.md 最多可以写多少行?
它没有严格的内容上限,但官方建议以少于 200 行为目标。先从约 100 行开始,足以放入项目地图、命令、修改边界和审查门槛。只有某个包需要的内容,应移到嵌套 CLAUDE.md 或 .claude/rules/。
执行 /compact 后规则还在吗?
根目录 CLAUDE.md 会在压缩后重新注入上下文。嵌套文件和路径限定规则,会在 Claude 再次读取匹配文件时加载。需要长期保留的决定应写进文件,不要只依赖可能被压缩的对话。
Auto memory 与 CLAUDE.md 有什么区别?
CLAUDE.md 是由人编写、审查并共享的指令。Auto memory 是 Claude Code 根据使用过程保存在本地的笔记,例如调试发现和个人偏好。团队共用命令与边界放在 CLAUDE.md;本地发现先留在 auto memory,除非人决定把它升级成团队规则。
第一版应该写什么?
先写安装、测试与构建命令,一份禁止修改的区域清单,以及任务结束时必须报告的项目。用真实任务运行一次,只补充造成明确返工的那条缺失决定。
用教材整理成项目专用模板
CLAUDE.md 只是稳定工作流程的一部分,permissions、测试、任务交接和审查规则还必须彼此一致。ClaudeCodeLab 教材目录提供可复用的清单与练习,适合把本文模板改造成团队自己的项目运行规范。
实际测试结果
2026 年 7 月 22 日,我们将本文的 check-claude-md.mjs 对两个临时 fixture 执行了测试。包含必需标题的 10 行有效样本以退出码 0 结束并显示通过信息;删除一个标题并放入测试 token 的负面样本以退出码 1 结束,共报告三项问题:一个缺失标题和两个匹配到的密钥模式。
本次审查还检查了 JavaScript 语法、官方来源 URL、内部链接、frontmatter、最终结果章节,以及全文只有一个主要商业 CTA。建议先对自己的 CLAUDE.md 运行检查器,再从第一条报告开始修复。产品行为已与 Claude Code 官方文档的 memory、context window、settings 和 hooks 交叉核对。
相关文章
Claude Code Permission Receipt Pattern:记录权限、证据和回滚方式
Claude Code 权限 receipt:记录允许动作、需要批准的边界、验证命令、回滚说明,以及 Gumroad 和咨询 CTA 检查。
把 Obsidian 旧笔记变成 Claude Code 工作指令的十分钟早间例程
Obsidian 攒的笔记每次都变成废料?把它拆成事实、决定、未知三类,整理成 Claude Code 能直接执行的工作指令,只要早上十分钟。
Claude Code 审批不再纠结:read/edit/run/deploy 判断日志怎么写
总在 Claude Code 的审批弹窗前犹豫?把读取、修改、执行、发布拆成四类,每天记下判断和理由,用实例教你写一份审批日志。
免费 PDF: Claude Code 速查表
输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。
我们会妥善保护你的信息,不发送垃圾邮件。
让 Claude Code 真正进入可验证的工作流
先用免费 PDF 固定基础,再用 Gumroad 教材复用工作流;如果涉及团队导入、权限或收入路径,可以直接咨询。
关于作者
Masa
专注 Claude Code 实务流程、团队导入和内容转化的工程师。