AI编程助手总忘事?用CLAUDE.md给模型一份入职手册
如果你日常用 AI 编程助手写代码大概率撞过这个场景刚打开终端时它比谁都懂你命令、路径、代码风格全都对聊到第五轮它开始凭想象造接口把一个不存在的模块说得有鼻子有眼。这不是模型突然变笨了而是上下文里少了关键的一页纸——CLAUDE.md。CLAUDE.md 不是什么新框架也不需要额外安装。它就是一个放在仓库根目录或者用户目录里的纯文本文件专门用来在每次对话开始时把项目的关键背景、常用命令、架构约定一次性喂给 AI。这篇文章面向所有被 AI 写错代码折磨过的开发者从原理讲到实战把 CLAUDE.md 的全局/项目配置、结构设计、动态注入技巧和踩坑实录一次讲透。读完你就能自己动手把 AI 从“偶尔靠谱”拉回“稳定靠谱”。1. 为什么 CLAUDE.md 这么重要先搞清楚 AI 编程助手“失忆”的根源1.1 上下文窗口是富贵病不能全怪模型很多人以为是模型智力不够实际上更常见的原因是对话太长前面的信息已经被挤出了上下文窗口。当前主流 AI 编程代理的上下文窗口虽然越做越大但每轮对话都在消耗 token。你让它改了十次文件之后早期提到的“项目根目录是 backend/”“测试要用 jest 而不是 mocha”这些信息很可能已经悄悄滑出了它的有效记忆范围。AI 编程助手和普通聊天机器人不一样。普通聊天聊错了可以重开写代码聊错了它可能直接给你删掉一个模块。所以关键思路不是“指望模型记住”而是“让它在每一轮对话开始时都能重新拿到最重要的信息”。CLAUDE.md 解决的就是这个前置机制它像系统提示词一样被自动注入到对话上下文的开头优先占住位置。1.2 CLAUDE.md 是给 AI 看的“入职手册”你可以把 CLAUDE.md 理解成一份只给 AI 看的入职手册。新同事入职第一天看 README 知道这个项目是干嘛的但不知道你惯用的命令别名、目录里哪块最容易踩雷、测试要跑哪几条。你也不会把“改完代码必须跑 lint”这种规矩写进 README因为 README 给人和外部协作看讲究的是清晰完整、不啰嗦。CLAUDE.md 恰好相反。它是给 AI 下指令用的要短、要直接、要可执行。它告诉 AI 的不是“我们通常怎么做”而是“你必须这么做”。这种语气上的差别直接决定了 AI 后续表现。我实测在同一个项目里把 README 里那套客气的描述改成 CLAUDE.md 里不带主语的祈使句之后生成代码的规范率明显上了一个台阶。1.3 它和 README、正式文档的分工很多团队的仓库里已经有 README、docs 目录、CONTRIBUTING 文档为什么还要单独搞一个 CLAUDE.md因为服务对象和使用场景完全不同。文件服务对象典型内容语气README.md人类新同事、外部用户项目简介、安装方式、快速上手介绍性、篇幅适中docs/人类长期使用者API 文档、架构设计、运维手册完整、严谨CLAUDE.mdAI 编程代理命令、约束、工作流、禁忌指令式、精简、只讲关键如果你把 CLAUDE.md 写成 README 的复述那基本是在浪费 token。它真正的价值是补充那些“除非你在这个项目里泡过三个月否则不可能知道”的信息哪个命令是假的但网上到处传、哪个目录结构改了会连锁爆炸、哪条规则是你上个月踩坑后才加的。这些内容写进正式文档显得太碎写进 README 又太长放在 CLAUDE.md 里刚刚好。2. 分清两种作用范围全局配置与项目配置2.1 用户级 CLAUDE.md沉淀你自己的开发习惯CLAUDE.md 不只存在于仓库里。在用户主目录下也可以放一份全局的作用范围覆盖你本机上的所有项目。我强烈建议你从这一份开始写因为它是你个人工作流的映射。比如你习惯用 neovim 而不是 vscode你写 TypeScript 时坚持不使用 enum你跑测试默认要加--runInBand避免并行资源冲突。这些个人偏好不一定适合写进团队的仓库文件但对 AI 来说又是极其重要的“操作约束”。全局 CLAUDE.md 就是用来沉淀这类信息的。我自己的全局文件里固定写了三条所有 shell 命令都按 zsh 语法给出涉及删除前必须二次确认不要生成项目里不存在的包名。这三条源自真实灾难现场写进去之后AI 的“手滑率”降了一大截。2.2 项目级 CLAUDE.md让 AI 按团队规矩办事项目级文件放在仓库根目录通常命名为CLAUDE.md随仓库一起提交团队所有人都共享同一份。它负责的是“这个项目的特殊规矩”启动命令是什么、测试用哪个框架、目录职责怎么划分、哪些代码风格是团队内部红线。我在一个中型 Node.js 后台项目里维护的项目级 CLAUDE.md核心内容只覆盖四块常用命令、目录指引、架构约束、工作流顺序。不到 60 行但 AI 在里面的表现像换了一个人——不会再用npm start去跑一个明明只有pnpm dev的项目也不会绕过 API 封装层直接在后端返回 SQL 片段。2.3 父子文件如何合并优先级怎么算这里有一个很多教程没讲透的点全局文件和项目文件不是二选一而是按顺序合并加载。机制上类似 CSS 的层叠具体实现的加载顺序通常是从通用到具体系统内置提示词 - 用户级 CLAUDE.md - 项目根目录 CLAUDE.md - 子目录 CLAUDE.md。后加载的会覆盖或补充先加载的同名约束。理解这个顺序之后有个实操技巧把“普遍的、所有项目都适用”的规则放全局把“只针对这个仓库”的规则放项目级。比如“不要创建虚拟的 npm 包名”放全局“这个仓库必须用 lodash 而不是 ramda”放项目级。一旦混了AI 在别的项目里就会拿着 A 项目的规则乱指挥。3. 写成什么样才有效CLAUDE.md 的结构与写作方法3.1 先记住三条铁律短句、祈使句、少废话写 CLAUDE.md 和写议论文完全相反。模型对长段落里的指令提取能力没有你想象中那么强尤其当一段话里既有背景解释又有要求时它很容易只记住前面修饰性的部分把真正的动作漏掉。我踩过的教训是一开始我把“由于此项目历史原因依赖管理使用 pnpm这是为了确保 node_modules 的一致性请所有命令都优先考虑使用 pnpm 而不是 npm”写进文件结果 AI 反复生成 npm 命令。改成“所有安装/运行命令一律用 pnpm”之后问题直接消失。人类需要背景来理解规则模型只需要指令本身。三条铁律具体来说每条规则尽量控制在 20 字以内能不用从句就不用。动词开头直接说“做什么”不要说“我们建议应该考虑做”。同一件事只写一次别在前言里客套又在后面重复强调。3.2 一套经过实测的结构骨架不同项目可以有自己的调整但下面这套骨架是我在四五类项目里试过之后效果最稳定的项目一句话说明让 AI 在最初就能判断这个问题属于这个项目还是答非所问。常用命令启动、测试、构建、lint、数据库迁移按使用频率排序。目录指引每个核心目录是干什么的哪些地方禁止动。架构约定与禁止事项这是 CLAUDE.md 的灵魂直接约束 AI 的设计决策。标准工作流比如“先查已有接口再写新接口”“改完必须跑测试”。常见陷阱把最容易让 AI 犯错的几个点写死比如“不要用 Date 构造字符串”。骨架不是模板是优先级清单。如果文件写出来之后超过 120 行先砍掉目录指引里那些废话描述再砍掉项目介绍。AI 读上下文是要花 token 的每一行都得有存在的理由。3.3 一个可直接抄作业的示例下面是我在一个虚构的中型 Node.js 后台项目里实际用的结构去掉了敏感信息你可以直接拿去改。# 项目某内部运营后台Node.js / TypeScript / React ## 一句话说明 这是一个面向运营团队的内部管理系统负责订单查询、用户管理、权限配置。 ## 常用命令 - 安装依赖npm ci - 本地启动npm run dev默认端口 3000 - 单元测试npm run test:unit - 代码检查npm run lint - 构建产物npm run build ## 目录结构 - src/api接口请求层所有后端调用必须走这里禁止在组件里直接 fetch - src/components/ui基础 UI 组件禁止混入业务逻辑 - src/pages路由页面只做页面组装不写数据请求 - src/store全局状态管理业务状态统一维护在这里 ## 架构约束 - 禁止在组件内部直接修改全局 store - 新增接口需要在 src/api 下统一维护并补充对应类型定义 - 时间处理一律使用 dayjs不要使用 Date 对象拼字符串 - 样式使用 CSS Modules禁止写全局 class ## 标准工作流 1. 先检查 src/api 是否已有现成接口优先复用 2. 开发前先补测试用例再写实现代码 3. 完成后必须运行 npm run lint 和 npm run test:unit 4. 全部通过后再请求提交 ## 常见陷阱 - 后端接口字段是下划线风格前端展示层再转驼峰不要在 api 层以外手动转换 - 权限判断必须走统一封装不要用 localStorage 里的角色字段直接判断 - 删除操作默认走软删除硬删除需要额外确认注意看里面几乎没有形容词每条都是“主语 动作 约束”的压缩结构。关键不是格式多漂亮而是每一条都能直接阻止一种 AI 常见骚操作。4. 进阶玩法让上下文跟上项目的变化4.1 用子目录 CLAUDE.md 隔离局部上下文当项目大到一定程度根目录那份 CLAUDE.md 会变得臃肿。这时可以在子目录里也放 CLAUDE.md用来描述这一块特有的约定。比如 monorepo 里packages/backend和packages/web用的构建工具完全不同与其在根文件里写一堆“如果你在 web 目录下则……”不如分别在两个子包里各放一份短小的 CLAUDE.md。AI 在处理具体路径下的文件时更容易命中附近子目录的上下文效率明显更高。这里的取舍是子目录文件不要和根文件重复。根文件里已经说过的“所有命令用 pnpm”子目录里就不要再复制一遍。子目录只写“本目录特有”的本地规则否则反而把模型搞糊涂。4.2 用环境变量或生成脚本注入动态信息CLAUDE.md 本身是静态的但项目是不断变化的。你可以用一个小脚本在关键操作前重新生成 CLAUDE.md 的某个片段让它带上当前分支、最新模块列表或者刚刚变更的接口清单。我常用的一种做法是维护一个scripts/update-claude-context.sh在切换分支或者 pull 之后跑一下自动更新 CLAUDE.md 底部的“当前环境状态”区块比如当前分支、本地依赖是否已安装、mock 服务地址。这一块内容不是给人看的但 AI 读到之后就不用再瞎猜部署环境。需要注意生成脚本本身不要塞进 CLAUDE.md 的主体里否则每次模型都会看到一堆和当前任务无关的 shell 片段。动态区块要放在文件末尾并用清晰的注释框起来方便识别。4.3 版本管理与团队评审CLAUDE.md 应该像代码一样走版本管理也要经过评审。我见过很多团队CLAUDE.md 是某个人悄悄写完就提交的结果别人发现 AI 行为不对又找不到原因最后只能靠删文件解决问题。正确的做法是把它当成一份“长期生效的接口契约”。新增任何架构禁止项都要在 MR 描述里注明理由至少让其他成员知道这条规则是从哪个事故里总结出来的。这样不仅文件本身质量高团队对 AI 编码行为的预期也会越来越一致。5. 常见问题与排查技巧实录5.1 写了 CLAUDE.md 却感觉完全没生效这是我在社区里看到最多的问题。绝大多数情况不是工具不支持而是路径或大小写没对上。CLAUDE.md 这个文件名是严格区分大小写的写成claude.md或者Claude.md很多实现就不会自动加载。另外有些项目把 CLAUDE.md 放在.github/或者docs/里但这只在特定的加载规则下才会被识别默认仍然以仓库根目录为准。还有一种可能会话是旧会话上下文里在文件写入之前就已经加载了旧的上下文信息。需要新开会话或者主动触发上下文重建改动才会生效。我习惯改完 CLAUDE.md 之后直接新开一个会话测试别闷在旧会话里反复踢死马。5.2 文件太大导致 AI 反而变笨CLAUDE.md 不是越详细越好。项目里上个月迁了某个依赖、上上个月改了某个接口命名规范这些历史信息如果全写进去AI 的注意力会被稀释真正重要的那几条规则反而成了噪声。经验上根目录 CLAUDE.md 控制在 100 到 200 行是甜点区。超过 300 行AI 在关键决策时经常漏读后半部分。如果内容实在太多优先拆到子目录文件里或者把不常用的“背景说明”挪到 docs 目录CLAUDE.md 里只留一句“背景细节见 docs/xxx.md”。5.3 怎么确认模型到底读到了文件想知道 CLAUDE.md 有没有生效最直接的方法是让模型复述其中的内容。你可以在新会话里直接问它“根据项目里的 CLAUDE.md这个项目的测试命令是什么”如果它答得上来说明加载成功了。如果它开始编造一个不存在的命令说明文件根本没进上下文。如果工具支持上下文检查命令也可以用。我的习惯是先把 CLAUDE.md 里某条规则写得稍微反直觉比如“所有文件名使用 kebab-case”然后随便问一个文件路径看它会不会按这个规则回答。这比问“你读到 CLAUDE.md 了吗”要可靠得多因为模型总会顺着你说“读到了”。5.4 排障速查表症状可能原因排除操作AI 完全不提 CLAUDE.md 里的规则文件名大小写不对或路径不对确认为CLAUDE.md放在仓库根目录改了文件但行为没变化旧会话上下文没有刷新新开会话再试规则被随机忽略文件过长重要内容被稀释精简到 200 行内删除重复描述拿全局规则套当前项目全局和项目级内容混在一起把项目特殊规则从全局移到项目级命令输出和项目实际不符合规则用了建议式句式改成祈使句去掉语气词6. 一点个人体会CLAUDE.md 不是银弹用了大半年 CLAUDE.md我最深的感受是它不会让 AI 从一个笨蛋变成天才但能让一个聪明的模型稳定发挥出它该有的水平。它更像是一个项目的“导航护栏”不负责替你开车但能保证车不往沟里开。我也走过弯路。最开始我把 CLAUDE.md 当成一个收纳箱什么觉得有用的都往里塞结果文件膨胀到几百行AI 反而不如不看的时候听话。后来我给自己定了一条规则每往里加一条约束就必须删掉一条已经过时的内容。这样一来文件永远保持在“当前项目最有效信息”的状态。最后分享一个小技巧别只在出问题时更新 CLAUDE.md。每次你发现 AI 做了什么让你眼前一亮的正确决定回想一下是什么信息帮了它如果这条信息还没写进去那就补上。反过来每次它犯了让你火大的错误也 check 一下是不是文件里缺了对应的禁止项。把它当成一本持续迭代的“AI 共事手册”而不是一份写一次就封存的文档它才真正值得存在仓库里。