1. 为什么你的 Claude Code 总在“失忆”
Claude Code 记忆系统是围绕CLAUDE.md构建的一套分层上下文加载机制,它能在每次会话启动时自动把项目规范、技术栈、常用命令注入模型上下文,让 Claude Code 不用你反复解释“我们用什么框架、目录怎么分、命令怎么跑”。它适合所有用 Claude Code 做日常开发的人,尤其是维护 Monorepo、多服务、多人协作项目的开发者。我见过太多人抱怨 Claude Code “每次开新会话就像换了个人”,其实根因往往不是模型不行,而是CLAUDE.md没写好或者根本没写。
典型症状是这样的:你打开一个新会话,Claude Code 上来就问“这个项目用什么包管理器”“测试命令是什么”,你耐着性子解释一遍;第二天再开会话,它又问一遍。更糟的是它开始“自由发挥”——你项目里明明用的是 MobX,它给你写 Redux;你后端统一响应格式是{ code, data, msg },它给你返回裸对象。这些都不是模型能力问题,而是上下文缺失。
CLAUDE.md解决的就是这件事:一次编写、每次会话自动读取、永久生效。它本质上是给 Claude Code 的“项目交接文档”,让模型打开项目就知道该怎么干活。这篇文章我会从记忆系统的层级结构讲起,给出可直接复制的CLAUDE.md骨架和settings.json配置片段,再演示怎么用终端命令验证记忆是否真的生效,最后把常见的坑一个个排掉。全程可跟做,不需要你从零手写。
2. TaoToken 前置:把模型接入这一步先跑通
在折腾记忆系统之前,得先确保 Claude Code 能正常调用模型。如果你用的是官方直连,这一步可以跳过;如果你希望通过统一入口管理模型调用、方便切换和计费,可以用 TaoToken 作为接入层。它的官网是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。
接入的核心是拿到 API Key,然后配置到 Claude Code 的环境变量里。先去控制台创建 Key:
https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=console创建完 Key 之后,在 API Keys 页面可以随时查看和轮换:
https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=api-keys如果你对 Claude Code 的接入方式还不熟,官方文档里有完整的配置说明:
https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=doc配置方式很简单,在终端里设置环境变量即可。以 macOS/Linux 为例,写入~/.zshrc或~/.bashrc:
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的Key"Windows PowerShell 用户这样设置:
$env:ANTHROPIC_BASE_URL="https://taotoken.net/api" $env:ANTHROPIC_API_KEY="sk-你的Key"设置完执行source ~/.zshrc让配置生效,然后跑一句claude --version确认 CLI 正常。这一步跑通之后,后面所有关于记忆系统的配置才有意义——模型都调不通,CLAUDE.md写得再好也白搭。
注意:环境变量里的 Key 不要提交到 Git,也不要写进项目里的任何配置文件。用系统环境变量或本地 shell 配置管理。
3. 记忆系统的四层结构:从全局到项目
Claude Code 的记忆不是“一个文件”,而是四层由远及近、叠加生效的记忆栈。理解这个层级关系,你才知道什么规则该放哪里。
第一层是全局CLAUDE.md,位置在~/.claude/CLAUDE.md。它跟人走,不管你打开哪个项目都会加载。适合放“我所有项目都希望 Claude 这样做”的规则,比如默认用中文回答、代码注释用英文、缩进用 2 空格。
第二层是项目CLAUDE.md,位置在项目根目录./CLAUDE.md。这是四层里最重要的一层,也是日常维护的重点。项目专属的技术栈、目录结构、编码规范、常用命令都放这里,提交到 Git 团队共享。
第三层是CLAUDE.local.md,位置在项目根目录./CLAUDE.local.md。它和项目CLAUDE.md同步加载,但只在你本地生效,绝不提交 Git。适合放个人偏好和本地环境特有的配置,比如你的数据库端口和别人不一样、你想让 Claude 先给方案再写代码。
第四层是 Auto Memory,位置在~/.claude/projects/<项目名>/memory/。这是 Claude 自己记的笔记,自动维护,你不需要手动管。它会在会话启动时加载MEMORY.md的前 200 行,记录调试经验、踩过的坑、发现的特殊模式。
加载顺序是从第一层到第四层依次叠加,冲突时越具体的层级优先级越高。所有层级同时生效,不是覆盖关系。你可以用一张表把分工看清楚:
| 层级 | 文件位置 | 作用范围 | 是否提交 Git | 典型内容 |
|---|---|---|---|---|
| 全局 | ~/.claude/CLAUDE.md | 所有项目 | 否 | 语言偏好、通用编码风格 |
| 项目 | ./CLAUDE.md | 当前项目 | 是 | 技术栈、目录结构、命令 |
| 本地 | ./CLAUDE.local.md | 当前项目本地 | 否 | 个人偏好、本地环境 |
| 自动 | ~/.claude/projects/<项目>/memory/ | 当前项目 | 否 | 调试经验、踩坑记录 |
这里有个容易踩的坑:CLAUDE.local.md一定要加进.gitignore,否则个人偏好会被提交到仓库,团队其他人拉下来就乱了。在项目根目录的.gitignore里加一行:
CLAUDE.local.md4. 可复制的 CLAUDE.md 骨架与 settings.json 配置
这一节给你可以直接抄的骨架。先看项目CLAUDE.md的完整结构,我以一个 Monorepo 全栈项目为例:
# Blog - 全栈博客平台 ## 项目描述 Monorepo 单代码仓库多系统架构,前端 H5 移动端 + 后端多微服务 + 跨系统共享包。 ## 核心技术栈 - 前端:React 19 + Vite + TypeScript + MobX + Ant Design Mobile - 后端:NestJS 11 + Prisma ORM + Redis - 构建工具:Turborepo ## 系统架构 - apps/web/ — 前端 H5 移动端 - services/auth-service/ — 认证授权服务 - services/backend/ — 主业务服务(文章、评论、用户) - services/log-service/ — 日志服务 - packages/shared-logging/ — 跨系统共享包 ## 常用命令 - 全项目开发:npm run dev(根目录) - 前端单独开发:cd apps/web && npm run dev - 单个后端服务:cd services/auth-service && npm run start:dev - 全项目构建:npm run build ## 通用编码规范 - 前端页面 5 文件拆分:index / useStore / handle / constant / types - 状态管理用 MobX 双轨架构 + useObserver Hook - 后端接口统一响应格式 - 共享包禁止包含业务逻辑 - 导入排序:第三方库 → @/ 别名 → 相对路径 - 禁止使用 any,用 unknown 替代 - 异步操作必须处理错误,禁止空 catch ## 验证流程 1. 在修改的子项目目录执行 npm run lint 2. 前端目录:npx tsc --noEmit 3. 参照 .claude/commands/review.md 自我审计 ## 规范入口 - 通用规则:.claude/rules/typescript-common.md、security-common.md - 前端特有:.claude/rules/frontend-components.md - 后端特有:.claude/skills/nestjs-backend-developer/关键原则是:CLAUDE.md里只放“每次会话都需要的信息”。技术栈和版本号放,具体某个 API 的字段设计不放;项目结构和职责边界放,某个模块的详细实现逻辑不放;高频编码规范放,低频规范拆到rules/按需加载。控制在 100 到 150 行以内,写太多反而降低 Claude 对每条规则的遵循度。
再看settings.json的配置。它放在.claude/settings.json,用来控制权限、环境变量和默认模型:
{ "permissions": { "allow": [ "Bash(npm run lint)", "Bash(npm run build)", "Bash(npx tsc --noEmit)" ], "deny": [ "Bash(rm -rf *)", "Read(.env)" ] }, "env": { "NODE_ENV": "development" } }allow里放你希望 Claude 不用每次确认就能执行的命令,deny里放绝对禁止的操作。这样既减少打断,又守住安全底线。如果你想让 Claude 在特定文件类型上加载特定规则,可以用rules/目录配合 frontmatter:
--- globs: ["apps/web/src/**/*.tsx", "apps/web/src/**/*.ts"] --- # 前端组件开发规范 - 页面 5 文件拆分:index / useStore / handle / constant / types - 公共组件放在 src/components/,用 PascalCase 命名 - 样式使用 SCSS + CSS Modules,禁止全局样式污染这份规则只在 Claude 操作匹配apps/web/src/**/*.tsx的文件时才加载,不会占用其他场景的上下文。
5. 验证记忆生效的终端命令与成功结果
配置写完不代表生效,得验证。最直接的方式是启动 Claude Code 后问它一个只有读了CLAUDE.md才知道的问题。
先确认文件确实在正确位置:
ls -la ~/.claude/CLAUDE.md ls -la ./CLAUDE.md ls -la ./CLAUDE.local.md然后启动 Claude Code:
cd your-project claude进入交互界面后,直接问:
我们这个项目的前端状态管理用的是什么?页面文件是怎么拆分的?如果记忆生效,Claude 会回答“MobX 双轨架构 + useObserver Hook”和“5 文件拆分:index / useStore / handle / constant / types”。如果它答不上来或者开始猜,说明CLAUDE.md没被加载。
另一个验证方式是让 Claude 复述项目结构:
列出这个项目的核心目录和各自的职责。生效时它会准确列出apps/web/、services/auth-service/等目录及职责。你还可以用/init命令反向验证——如果项目里已经有CLAUDE.md,/init会提示已存在而不是重新生成。
对于 Auto Memory,你可以主动让 Claude 记住一件事:
记住:Prisma 的 BigInt 时间戳字段在 JSON 序列化时要用 .toString(), 否则前端拿到的会是科学计数法,数字精度丢失。然后检查记忆文件是否写入:
cat ~/.claude/projects/your-project/memory/MEMORY.md看到这条记录被追加进去,就说明 Auto Memory 正常工作。下次会话里问它“BigInt 时间戳序列化要注意什么”,它应该能回忆起来。
6. 本篇常见错排查
问题一:CLAUDE.md写了但 Claude 不遵守。先检查文件位置对不对。项目级必须是项目根目录的./CLAUDE.md,不是src/CLAUDE.md也不是.claude/CLAUDE.md。全局级必须是~/.claude/CLAUDE.md。位置错了就不会被加载。
问题二:规则太多,Claude 反而记不住。这是最常见的坑。CLAUDE.md超过 150 行后,每条规则的遵循度会明显下降。解决办法是把低频规则拆到.claude/rules/目录,用 frontmatter 的globs指定作用范围,按需加载。CLAUDE.md里只留规范入口的引用。
问题三:CLAUDE.local.md被提交到 Git 了。检查.gitignore里有没有CLAUDE.local.md。如果已经提交了,执行git rm --cached CLAUDE.local.md从版本控制移除,再补上.gitignore。
问题四:改了CLAUDE.md但当前会话没生效。记忆是在会话启动时加载的,改完文件需要退出当前会话重新进。执行/exit或按 Ctrl+C 退出,再claude重新启动。
问题五:Auto Memory 不写入。检查~/.claude/projects/<项目名>/memory/目录是否存在且可写。如果项目名带特殊字符导致路径不对,可以手动创建目录。另外 Auto Memory 只在 Claude 认为信息值得记时才写入,不是每句话都记。
问题六:多个项目之间记忆串了。全局CLAUDE.md是所有项目共享的,如果你在里面写了某个项目特有的规则,其他项目也会加载。项目特有的规则一定放项目级CLAUDE.md,不要放全局。
排障时如果怀疑是模型接入层的问题,可以先去模型对话页面单独测一下模型是否正常响应:
https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=model-chat接入配置的细节可以对照文档再核一遍:
https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=doc7. 长期编码与 Agent 场景的下一步
如果你只是偶尔用 Claude Code 写点小脚本,项目级CLAUDE.md加本地CLAUDE.local.md就够了。但如果你打算把 Claude Code 当成日常主力开发工具,长期跑编码任务、搭 Agent 工作流,那记忆系统的维护就得当成一件正经事来做。
我的建议是:CLAUDE.md用出来的,不是写出来的。每次你和 Claude “磨合”后发现它又犯了同样的错,就说明CLAUDE.md里缺了这条信息,补上;每次它做了一件你不想它做的事,就加一条明确的禁止规则。经过几轮调试,它会越来越懂你的项目。
对于需要长期跑编码任务、管理多个 Agent 会话的场景,可以了解一下 Coding Plan:
https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding-plan如果你用的是 Claude Code 的 Anthropic 兼容模式,接入说明在这里:
https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=claude-code-anthropic最后留一个实用技巧:把踩坑记录统一维护在.claude/project-memory.md,格式固定成“错误场景 / 错误现象 / 原因分析 / 正确解决方法 / 记录日期”。这比 Auto Memory 更可控——你来决定什么值得记,格式统一方便回溯。当用户说“添加到项目记忆”时,让 Claude 按这个格式写入。这样你的项目记忆会随着时间越积越厚,而 Claude Code 也会越来越像团队里那个“什么都懂的老员工”。