十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

一条命令给Claude Code加团队记忆:用CLAUDE.md固化项目约定

一条命令给Claude Code加团队记忆:用CLAUDE.md固化项目约定 Claude Code 用久了你会发现一个挺尴尬的事每次新开会话它都不认识你。哪怕你昨天刚告诉过它“这个项目用 pnpm 不要用 npm”“测试命令是 npm run test:e2e”第二天一切归零它照样会用 npm 装出一堆依赖把 lockfile 搞乱。团队协作的时候更头疼五个人轮着跟它交代同一套背景交代的人烦它记的还未必对。这个问题的本质不是模型能力不够而是缺少一套能持续维护的上下文输入机制。我折腾出一套挺朴素的解法一条命令把团队约定固化进 CLAUDE.md让每个新会话自动带上团队记忆。这篇文章就把完整方案、命令拆解以及我实际用下来的坑都摊开讲。1. 先想清楚Claude Code 到底靠什么“记住”事情1.1 会话隔离带来的“失忆”问题Claude Code 的设计就是一个会话一个隔离环境有点像开一个临时虚拟机跑完就销毁。这种设计的好处是干净不串台坏处就是没有长期记忆。昨天你让它重构了一个模块它改的时候头头是道但今天打开终端重新claude它对这个项目的认知基本归零只能靠重新读目录、看代码来恢复上下文。团队场景下这个“失忆”会被放大。A 告诉过它“后端接口统一走 /api/v1”B 没说过等 B 开会话时它就可能直接写 /api。这类问题单靠模型本身解决不了必须有一个持久化的载体在每次会话启动时自动加载给模型看。Claude Code 里这个载体就是 CLAUDE.md。1.2 CLAUDE.md 是记忆的核心载体CLAUDE.md 是 Claude Code 启动时自动读取的 Markdown 文件可以理解为给模型的“项目说明书”。只要文件放在约定位置每次进入项目目录执行claude它就会把文件内容作为背景知识自动加载不需要你手动输入任何提示词。我自己用下来记忆文件分这么几个层级作用完全不一样文件路径作用域是否适合团队共享项目根目录CLAUDE.md整个项目适合应该提交到 Gitdocs/CLAUDE.md整个项目偏文档场景适合但路径偏深建议主要用于资料索引.claude/CLAUDE.md整个项目配置类适合通常放工具链相关约定CLAUDE.local.md仅当前开发者本机不适合个人草稿~/.claude/CLAUDE.md当前系统用户的全部项目个人通用偏好不适合团队核心思路是团队共同遵守的东西放项目根目录的 CLAUDE.md并纳入版本控制个人习惯和草稿放 CLAUDE.local.md并加进 .gitignore。这样团队拉到代码库时自动就拥有了同一套记忆基线。1.3 记忆写得越结构化效果越稳定Claude Code 对 Markdown 的理解能力很强但前提是你得写得有条理。我自己测试下来纯叙述的一大段文字模型经常抓不到重点但用标题、列表、短句组织过的内容它几乎每次都能在需要的时候引用出来。举个例子低效写法这个项目用 pnpm 因为速度更快反正不要用 npm 就对了高效写法包管理pnpm。安装依赖一律使用 pnpm add禁止使用 npm/yarn区别在于后者是可判定的规则模型在遇到“装依赖”这个场景时能明确知道自己该选什么、不该选什么。所以设计记忆内容的时候不要写“大约、应该、尽量”这类模棱两可的词要写“必须、一律、禁止”这种边界清晰的规则配合具体的命令示例效果会好很多。2. 一条命令搭建团队记忆先跑起来再说2.1 最小可用的初始化命令很多团队没建立记忆不是不想而是懒得手动创建文件、想结构、写模板。所以我把整套初始化过程压成了一条命令在项目根目录执行一次就拥有一个可用的团队记忆文件cat CLAUDE.md EOF # 项目记忆 ## 技术栈 - 前端: React 18 TypeScript Vite - 后端: Node.js 22 Fastify - 包管理: pnpm禁止 npm / yarn ## 常用命令 - 开发: pnpm dev - 测试: pnpm test - 类型检查: pnpm typecheck - Lint: pnpm lint ## 目录结构 - src/ 前端源码 - src/server/ 后端逻辑 - src/components/ 公共 UI 组件 - docs/ 设计文档 ## 团队约定 - 提交信息使用 Conventional Commits - 新增接口必须带 requestId - 环境变量统一放 .env.example不提交 .env EOF执行完这条命令项目根目录就多了一个 CLAUDE.md下一次claude启动时它就会自动读取。整条命令的核心逻辑其实只有四个字写文件。但因为它选对了文件名和位置就完成了“给 Claude Code 加团队记忆”这一步。2.2 命令拆解每一段在干嘛有人说这不过是一条 cat 加 heredoc 而已有什么好讲的其实这里有几个细节决定了命令是否可靠。首先是EOF这里的单引号。单引号的作用是告诉 Shell内容里的一切都是字面量不要做变量展开。如果你写成EOF而没有引号那模板里凡是出现$、反引号的地方都可能被当前 Shell 抢先解析结果可能跑出来一串空变量或者奇怪的执行结果文件内容就废了。其次是重定向符号。会覆盖写入所以这条命令适合在项目刚初始化、CLAUDE.md 还不存在的时候执行。如果文件已经存在不想覆盖历史内容可以把命令里的cat 改成cat 追加写入即可。我在下面会提供一个更安全的封装避免手滑覆盖。最后是模板内容的组织方式。我故意把“技术栈”“常用命令”“目录结构”“团队约定”拆成四个独立小节这是为了让 Claude 在回答不同类别问题时能快速定位。比如有人问“这个项目用什么装依赖”它先看到“技术栈”里的 pnpm有人问“提交代码有什么要求”它从“团队约定”里捞 Conventional Commits。结构本身就是一种检索索引。2.3 封装成 shell 函数重复使用不费手真实项目里团队记忆不可能只初始化一次后续会持续追加“上线流程”“代码评审注意事项”“某个模块的特殊坑”。只靠上面那条一次性命令用起来还是不够顺手。所以我强烈建议把它封装成一个 shell 函数放进.bashrc或.zshrccc-mem() { case $1 in init) if [ -f CLAUDE.md ]; then echo CLAUDE.md 已存在不会覆盖 return 1 fi cat CLAUDE.md EOF # 项目记忆 ## 技术栈 - 包管理: pnpm禁止 npm / yarn ## 常用命令 - 开发: pnpm dev - 测试: pnpm test ## 团队约定 - 提交信息使用 Conventional Commits EOF echo CLAUDE.md 已初始化 ;; add) shift printf -- - %s (%s %s)\n $* $USER $(date %Y-%m-%d) CLAUDE.md echo 已追加: $* ;; *) echo 用法: cc-mem init|add \内容\ ;; esac }用法很简单cc-mem init初始化团队记忆cc-mem add 该接口依赖 xxx 服务不可单独启动往记忆里追加一条带日期和作者的经验。init保证了不会覆盖已有内容add则是把“沉淀经验”这件事压缩到一条命令里。源一下配置就能立即生效source ~/.zshrc这一步做完你已经不是“给 Claude Code 加一次记忆”而是给团队建立了一个可持续生长的记忆仓库。3. 把“一条命令”升级成团队可同步的记忆仓库3.1 CLAUDE.md 必须进版本控制如果 CLAUDE.md 只存在你本地那它只能算个人笔记谈不上团队记忆。真正让团队受益的做法是把它提交进 Git 仓库这样所有成员拉取代码时自动就把这套背景知识拉到了本地。我建议在项目根目录的.gitignore里明确加上一行CLAUDE.local.md团队共享的 CLAUDE.md 正常提交个人本地记忆 CLAUDE.local.md 忽略掉。这样既保证了团队共识不丢又给每个人留了私人备注空间。你可以在本地 CLAUDE.local.md 里写“这个模块我重构过别再动”但不会污染队友的上下文。3.2 追加一条记忆的快捷命令团队记忆的维护频率往往比想象的高。有时候是线上事故复盘发现某条路径不能碰有时候是新人问了个问题老人才想起该把约定写下来。这时候如果还得打开编辑器定位到 CLAUDE.md 再写很多人就懒得做了。所以cc-mem add的意义是降低写入成本。不过我实际用下来直接往文件末尾追加容易把记录写得很乱。更推荐的做法是让 add 命令不是无条件追到末尾而是把新内容写到一个专门的“动态经验”小节方便定期整理。比如我们可以让函数自动定位到## 动态经验这个标题在它下面追加条目。Shell 里可以用awk实现但对大多数团队来说先简单追到末尾、每周用编辑器整理一次已经能跑得很好。另外如果团队里有用 Git 的钩子机制比如 commit-msg、pre-push可以写一个脚本在每次 push 前检查 CLAUDE.md 有没有改动有改动就提示成员“本次提交包含记忆更新请确认是否同步到需求文档”。这步属于锦上添花初期不必强求。3.3 记忆内容的分层与边界CLAUDE.md 不是越厚越好它本质上会占用每次请求的上下文窗口。把整个项目的历史、所有讨论、全部代码细节都塞进去只会让 Claude 变得迟钝甚至抓不住重点。我的分层经验是这样CLAUDE.md 里放“稳定共识”技术栈、目录结构、必守规范、常用命令这些内容几个月不变属于高价值低频变更。.claude/CLAUDE.md里放“工具链配置”比如 linter 规则、格式化工具、CI 相关约定方便做环境切换。CLAUDE.local.md 里放“个人临时备注”比如某个正在调试的分支、某个模块的个人理解。外部文档用路径方式引用如果细节太多可以在 CLAUDE.md 里写“数据库设计见 docs/database.md”让 Claude 需要时再去读文件而不是把所有内容平铺进去。这样既保证了上下文质量又不会让记忆文件膨胀失控。团队记忆的正确姿势是写索引、写规则、写边界而不是当 wiki 用。4. 实操复盘一次真实的团队记忆注入4.1 场景设定接手一个 pnpm monorepo上个月我帮朋友团队处理一个项目情况非常典型仓库里同时有 web、server、shared 三个包用 pnpm workspace 管理前端是 React TypeScript后端是 Fastify测试用 Playwright提交规范要求 Conventional Commits。但团队之前没有给 Claude Code 任何记忆导致每个成员都跑来跟我抱怨“Claude 写的代码跟项目风格完全不一致”。这个场景的痛点很明显靠模型临时读代码去猜项目规则既慢又不稳。我用前面说的方案在项目根目录执行cc-mem init再手动补全了几个团队成员补充的关键约定整个过程不到五分钟。4.2 命令执行后的 CLAUDE.md 长什么样执行完并补充后的文件长这样# 项目记忆 ## 技术栈 - 仓库: pnpm workspaceweb server shared - 前端: React 18 TypeScript Vite - 后端: Node.js 22 Fastify - UI: 自研组件库见 shared/ui禁止引入其他组件库 - 包管理: pnpm禁止 npm / yarn ## 常用命令 - 安装依赖: pnpm install - 启动 web: pnpm --filter web dev - 启动 server: pnpm --filter server dev - 测试: pnpm test - E2E: pnpm test:e2e ## 目录结构 - web/src 前端页面 - server/src 后端接口 - shared/ui 公共组件 - shared/utils 公共工具函数 - docs 设计文档 ## 团队约定 - 包名规范: scope/package-name - 接口错误必须返回统一结构 { code, message } - 新增共享逻辑放 shared不要随手复制到各包 - 提交信息使用 Conventional Commits几次迭代后团队又通过cc-mem add追加了几条经验比如“Playwright 跑 E2E 前必须先启动 mock 服务”“server 端新增路由必须在 routes 目录注册”。这些内容在官方文档里都不存在但恰恰是项目真正的坑。4.3 加了记忆前后Claude 行为的变化加入记忆前后同一个 Claude Code 的行为差异非常明显。之前它看到src/server下的文件会直接在自己认为合适的位置新建文件经常创建出src/server/controllers/xxx.ts这类目录而项目实际用的是src/server/routes/xxx.ts。加了目录约定后它所有新增路由都老老实实放进了 routes 目录没有再产生惊喜路径。包管理器就更典型。没有记忆时它偶尔会跑npm install xxx然后 pnpm 的锁文件就被 npm 的 package-lock.json 污染有了“包管理: pnpm禁止 npm / yarn”这条规则后它再也没自作主张跑过 npm。所以说CLAUDE.md 里的规则不是给模型“参考”的而是给模型“执行”的写清楚、写强硬效果立竿见影。此外团队的代码评审开始有了一致性。以前 A 让 Claude 写的提交信息风格和 B 让 Claude 写的提交信息风格会打架现在统一按 Conventional Commits标题格式、作用域写法都一致了。团队记忆的价值不是省一次两次的事而是让所有人都站在同一个上下文上协作。5. 常见问题与排查技巧实录5.1 改了 CLAUDE.md 却不生效先查这四处很多朋友第一次配置完发现 Claude 还是老样子就开始怀疑命令写错了。据我观察八成不是命令问题而是下面这四个位置出问题会话没重启。CLAUDE.md 是在会话启动时读取的如果你开着同一个会话改文件它不会热更新。退出重进claude再试。文件路径不对。注意是项目根目录的 CLAUDE.md不是src/CLAUDE.md也不是把内容写到CLAUDE.local.md里然后让队友拉代码——后者根本不会进 Git。文件名大小写不准确。一定是大写CLAUDE.md不是claude.md或Claude.mdLinux 和 macOS 的文件系统大小写敏感写错了就识别不到。有 BOM 或编码问题。如果用 Windows 自带的记事本编辑过文件可能带 UTF-8 BOM实测个别环境下会导致首行解析异常建议统一用 VS Code 或终端重写。验证是否生效也很简单新开会话后直接问它“这个项目的包管理器是什么”它如果能明确回答出 pnpm 并给出理由说明记忆已经加载了。5.2 多级目录项目的记忆该放哪一层有些项目是 monorepo根目录有一堆包每个包又有自己的子目录。这时候很多人会纠结CLAUDE.md 放根目录还是放某个包里面。我的建议是覆盖面最大的共识放根目录每个包独有的约定放在对应包目录下。比如根目录 CLAUDE.md 写“全局用 pnpm workspaces”“所有包禁止引入外部 UI 库”web 包里单独放一个 CLAUDE.md 写“页面路由用 react-router禁止用 client-side render 方式”server 包里写“中间件统一在 middleware 目录注册”。Claude Code 在特定目录启动时会向上查找多层记忆可以配合使用。5.3 记忆被改坏、规则被违反怎么办记忆也会腐化。团队里有人觉得某条规则没用直接删了或者让 Claude 自己“优化”了 CLAUDE.md结果它把关键约束改得面目全非。我的做法是CLAUDE.md 的变更必须走 Git review。任何人对它的修改都在 MR 里展示出来避免静默变更。至于规则被违反先别急着骂模型回头看看规则本身。如果规则写的是“代码风格要统一”这等于没写改成“字符串必须用单引号禁止双引号”“函数命名使用 camelCase禁止下划线”Claude 的执行准确率会明显高。记忆内容的颗粒度直接决定了执行效果。5.4 敏感信息如何避免进入记忆这里必须强调CLAUDE.md 不要写任何密钥、令牌、数据库连接串、内网地址。因为它可能被提交到 Git、被团队成员 fork、被 Claude 在回答时引用一旦泄露就是事故级问题。我见过有人把生产环境的数据库地址写进记忆本意是方便 Claude 理解部署拓扑结果每次会话都会加载最终出现在 AI 生成的文档或错误信息里。正确的做法是在记忆里写“数据库配置从 config/env.json 读取禁止硬编码”实际敏感值仍然走环境变量。规则和约定可以写入记忆真实凭据永远不要。5.5 刚引入时团队不习惯维护怎么办最后说一个项目落地层面的问题让大家习惯写记忆比技术方案本身难多了。初期建议指定一个负责人前两周由他把散落在聊天记录里的约定定期整理进 CLAUDE.md其他人只负责用。等大家尝到甜头发现 Claude 越来越懂项目自然会愿意自己追加内容。我个人还喜欢在 CLAUDE.md 顶部写一条小规则“如果你发现项目记忆有遗漏或过时请主动提醒用户补充。”这样 Claude 遇到它不理解的项目决策时会反过来引导使用者补充记忆形成正循环。这套“一条命令加团队记忆”的方案我前后跑了大概一个多月最大的体会是Claude Code 本身不缺能力缺的是项目上下文的供给。与其每次重复交代背景不如花五分钟把共识沉淀成文件让每个新会话自动继承。最后再分享一个小经验别一上来就追求记忆文件有多完整先让最痛的三条规则生效——包管理、目录结构、提交规范用起来之后再逐步迭代。你会发现它是越养越懂你的。
返回列表