你有没有过这种体验:昨天刚让 Claude Code 把一个模块从同步改成异步,顺手在对话里约定了“以后新代码一律用 async/await,不要回调”,今天打开终端重启会话,它第一句话是“这个项目是做什么的”,第二句话是“我们是不是第一次聊”。你盯着屏幕,满脑子只有一个念头:又失忆了。
这不是个例。Claude Code、Codex、VS Code 里的各种 AI 编程插件,以及 Qoder 这类 AI IDE,本质上都是“金鱼记忆”——每次新会话,它对项目一无所知,你的技术栈、架构决策、进行中的任务、踩过的坑,全部清零。这篇文章我想聊的就是:怎么用两分钟时间,给这四个工具装上一套统一的长期记忆,让它们记住你的项目背景、代码规范、当前进度,甚至让记忆跟着项目一起成长。方案不需要改代码,只需要建两个规则文件加一个记忆文档,适合所有用 AI 工具写代码的人,无论你是刚入坑的小白还是老手。
先说明一点:这套东西不是玄学,就是利用这些工具本来就支持的规则文件机制,再加一份由 AI 自己维护的动态记忆。下面我从原理到落地,一步步拆开讲。
1. 会话工具的“金鱼记忆”,到底丢掉了什么
1.1 每一次新会话,都是把模型打回“出厂设置”
先想一个问题:大语言模型本身是没有任何状态的。你问它一个技术问题,它能回答,靠的是训练时学到的“通用常识”。但“你的项目用什么框架”“你刚把订单模块的重构做到哪一步”“你之前和它约定的代码风格”,这些信息只存在于对话上下文里,不存在于模型权重里。
Claude Code、Codex 这类 Agent 工具看起来能连续完成任务,其实每次启动会话时,它们会重新加载系统提示词、注入项目规则、扫描相关代码,再加上你最近的对话,拼成一份“临时记忆”。这份临时记忆是短命的——会话一结束就没了。下一次打开终端,它又是全新的自己。
很多人第一次用这类工具时会有一个错觉:它能读我的代码,它应该什么都懂。其实它只是在利用工具读取文件,然后把这些文件内容塞进上下文窗口临时理解而已。你昨天在对话里告诉它的那些约定、背景、取舍,它根本没“记住”,除非你把这些内容写进某个它每次启动都会读取的文件里。
1.2 原生规则文件,其实只能算“半个记忆”
Claude Code 有 CLAUDE.md,Codex 有 AGENTS.md,它们是什么?它是一份纯文本的规则说明书。工具每次启动时,会自动读取项目根目录下的这份文件,把它当作“项目背景”注入上下文。
这就是所谓的“静态记忆”:你手动在里面写“这是一个 Go 微服务项目,分三个模块”,AI 每次启动都会读到,所以它不会每次都问你这个项目是干嘛的。
但它也有明显的局限:这份文件不会自己更新。今天你换了 ORM、重构了目录结构、把 Redis 换成了 KeyDB,如果你不手动改规则文件,AI 拿到的还是那份过期的说明书。也就是说,光有 CLAUDE.md / AGENTS.md,你还是得手动维护,一旦项目演进速度超过维护频率,AI 又会开始犯“半失忆”的毛病。
1.3 四个工具混用的放大效应
更麻烦的是,很多人并不是只用一个工具。命令行里跑 Claude Code 做重构,Codex 在另一个终端里处理批改任务,VS Code 里装着一堆 AI 插件,Qoder 又是另一套带 AI 的 IDE。它们看着在同一个项目里工作,实际上各自维护各自的上下文。
如果你只在 CLAUDE.md 里写了规则,切到 Codex 就失效;只在 AGENTS.md 里写了,Claude Code 也不一定认。更别说 VS Code 的插件体系和 Qoder 的 IDE 级规则了。四套工具,四个记忆位点,各记各的,等于没记。这也是我后来必须做统一方案的根本原因:与其记每个工具的特性,不如让它们都去读同一个“真相源”。
2. 先摸清各自的“记忆插座”,再谈统一供电
2.1 Claude Code:CLAUDE.md 是主入口
Claude Code 的记忆机制相对成熟。它优先读取项目根目录下的CLAUDE.md,也支持在子目录里放CLAUDE.md做局部覆盖。如果你想给所有项目加一份通用规则,可以把文件放在~/.claude/CLAUDE.md。
一些较新的版本也开始兼容AGENTS.md,不过我不建议完全依赖这种兼容性,最稳妥的做法仍然是使用CLAUDE.md作为唯一主入口。
另外,Claude Code 的规则文件还支持通过@路径的方式引用其他文件,比如在CLAUDE.md里写一行@docs/PROJECT_MEMORY.md,它会把这个文件也读进上下文。这让“规则文件”和“记忆文件”分离成为可能:规则文件放不变的准则,记忆文件放每天都在变的状态。
还有一个不太被注意的机制:CLAUDE.local.md。它是本地个人配置,不会提交到版本库,适合放“我喜欢注释用中文写”“提交信息用 Conventional Commits”这类纯个人偏好。
2.2 Codex:认 AGENTS.md,结构同样重要
OpenAI 的 Codex CLI 和编辑器扩展,主要读取项目根目录下的AGENTS.md文件,全局偏好则可以放到~/.codex/AGENTS.md。
AGENTS.md的内容组织方式讲究一些:它跟系统提示词直接拼接,前几行的权重最高。我习惯把最重要的“身份设定”和“必须遵循的全局准则”放在文件前几行,把具体的项目技术栈信息放到后面的记忆文档里,避免一份文件既要当规则又要当百科,最后两样都没干好。
2.3 VS Code 与 Qoder:插件级规则和 IDE 级规则
先说 VS Code。VS Code 本身只是编辑器,没有 AI 记忆。但你在里面装的各种 AI 扩展,比如 Claude Code 扩展、Codex 扩展、Cline 等,都会在打开项目时去读项目根目录下的规则文件。所以,只要你在项目根目录里放了CLAUDE.md和AGENTS.md,这些插件大概率都能读到。此外,.vscode/settings.json可以放一些编辑器级的项目配置,但它不是 AI 记忆,别指望它能告诉 AI “这个项目当前进行到哪”。
Qoder 作为 AI IDE,内置了自己的 Agent 规则体系,同时因为底层兼容 VS Code 生态,很多基于文件的规则也能被识别。最保险的做法是:除了在项目根目录放通用规则文件,再把同样一句话写进 Qoder 的项目规则面板:“项目状态以 docs/PROJECT_MEMORY.md 为准”。
2.4 一张表看清四个记忆位点
| 工具 | 项目级记忆位点 | 全局记忆位点 | 生效方式 |
|---|---|---|---|
| Claude Code | ./CLAUDE.md | ~/.claude/CLAUDE.md | 会话启动时自动注入 |
| Codex | ./AGENTS.md | ~/.codex/AGENTS.md | 会话启动时自动注入 |
| VS Code AI 扩展 | 随插件读取上述项目文件 | 各插件自己的全局配置 | 打开项目/启动会话时读取 |
| Qoder | 项目规则 / AGENTS.md 等 | 全局规则 | IDE 加载项目时读取 |
这张表的结论很简单:项目根目录,是所有工具的交集。只要把记忆放在项目根目录,并按各自约定的文件名放一份,四个工具就都能读到。这也为后面的“两分钟统一方案”打下了基础。
3. 两分钟,搭一套“静态规则 + 动态记忆”统一底座
3.1 第一步:建规则入口文件(约 20 秒)
在项目根目录创建CLAUDE.md,内容控制在二十行左右。它的作用是给 AI 一个清晰的身份和一套稳定的行为准则,不要放太多具体状态。
# 项目规则 ## 角色定位 你是一位在这个项目里长期工作的资深工程师。你拥有完整记忆能力,信息源在 docs/PROJECT_MEMORY.md。 ## 必读记忆 每次会话开始时,先读取 docs/PROJECT_MEMORY.md,了解项目当前状态。 ## 记忆维护 每次任务完成或遇到关键决策时,更新 docs/PROJECT_MEMORY.md,保留历史痕迹,不要覆盖性重写。 ## 代码规范 遵循项目记忆文档中记录的代码风格和工程约定。 ## 回复风格 简洁、直接,给出结论后再补充理由。这里的核心是“必读记忆”和“记忆维护”这两条。前者解决“失忆”,后者让 AI 自己写记忆。
3.2 第二步:给 Codex 也建一个入口(约 20 秒)
创建AGENTS.md。最省事的办法是直接复制一份CLAUDE.md的内容过来。既然都是 Markdown 规则文件,保持一致的目的是避免两个工具的行为分叉。
如果你不想维护两份一模一样的文件,可以在AGENTS.md里做一个“转发”:
# Codex 规则 你是一个长期在此项目工作的工程师。 先阅读 docs/PROJECT_MEMORY.md 了解项目状态。 完成任务后更新该文件。 详细规则见 CLAUDE.md,若有冲突,以本文件为准的约定需谨慎处理。注意,我不建议在AGENTS.md里写“以 CLAUDE.md 为准”就完事,因为你不能确定 Codex 的底层提示会真的去追读另一个文件。最好还是让两个入口文件都直接指向同一个记忆文档,这样最稳。
3.3 第三步:创建动态记忆文档(约 40 秒)
创建docs/PROJECT_MEMORY.md。这个文件是整个方案的灵魂,它记录的是项目“当前的真实状态”。模板可以直接拿去用:
# 项目记忆 ## 项目概述 一句话说明这个项目是做什么的。 ## 技术栈 - 语言/框架: - 关键库: - 基础设施: ## 工程约定与代码规范 - 命名风格: - 目录结构: - Git 提交规范: - 其他: ## 进行中的任务 - [ ] 任务1(当前焦点) - [ ] 任务2 ## 已完成的关键决策 | 日期 | 决策内容 | 原因 | | --- | --- | --- | | 2024-01-01 | 订单模块改为异步 | 降低数据库压力 | ## 踩坑记录 | 现象 | 原因 | 解决方式 | | --- | --- | --- | | 并发下偶发超时 | 连接池过小 | 调大连接池 | ## 未来待办/灵感 - placeholder ## AI 与人的约定 - 不要在我没有要求时重构无关代码。 - 提交信息使用英文。你不用把所有字段一次填满,刚开始只需要把“项目概述”“技术栈”“进行中的任务”这三段写上,其余留空,让 AI 在后面的协作中慢慢填。
3.4 第四步:验证记忆是否已经生效(约 30 秒)
规则文件和记忆文件都建好之后,验证一下是否真的生效。
先打开 Claude Code,问一句:“根据项目记忆,告诉我这个项目目前的技术栈和进行中的任务。”如果它回答的内容和你写在docs/PROJECT_MEMORY.md里的一致,说明它成功读取了记忆。
再打开 Codex,问同样的问题。接着你可以故意在记忆文档里把“进行中的任务”改一行,再重新开一个会话问它,看它是否拿最新的信息回答。如果它还在用旧的记忆,大概率是没读到文件,检查一下文件路径和名称是不是对的。
算下来,四个步骤加起来大概两分钟。第一次操作可能需要多一点时间,但当你把模板固化成自己的常用结构之后,新建项目时基本就是复制粘贴的事情。
4. 让记忆自己长大:AI 自主维护记忆的关键设定
4.1 只“读”不“写”,记忆迟早变成废纸
静态的规则文件需要人肉维护,这不够“长久”。真正的做法是让 AI 在每轮任务中自己更新记忆文档。
核心是在规则文件里把“写”的要求写清楚。我在CLAUDE.md里用了这样一段:
## 记忆维护 每次任务完成或遇到关键决策时,更新 docs/PROJECT_MEMORY.md,保留历史痕迹,不要覆盖性重写。这条指令看起来简单,但其中“保留历史痕迹”这几个字很重要。它告诉 AI:不要把旧的记录直接删掉重写,而是在“已完成的关键决策”表格里追加新行,在“进行中的任务”里勾掉已完成项。这样记忆文档就像一份持续演进的日志,而不是每次被 AI 随意改写的临时笔记。
4.2 记忆文档里到底该记录什么
有些人不确定该往记忆文档里写什么,于是什么都往里丢:让 AI 把整个项目的代码结构也整理进去,最后文档膨胀到几百行,反而拖累上下文效率。
我的建议是只记录跨会话有价值的五类信息:
- 技术决策:比如“从关系型数据库切到 ClickHouse,原因是分析查询性能不足”。这类信息最容易被遗忘,也最影响后续开发方向。
- 项目状态:进行中的任务、当前焦点、被阻塞的事项。
- 踩坑记录:遇到什么问题、根因是什么、怎么解决的。这个对 AI 犯错率的降低立竿见影。
- 代码风格与工程约定:命名方式、目录组织、commit 风格。
- 待办和灵感:暂时不做但以后可能做的事。
一个推荐的记忆条目格式是:日期 + 事件 + 背景/原因 + 结论。比如:
2024-01-15 把用户列表接口从同步改为异步流式返回。背景:单次全量返回慢。 结论:后续新增列表接口默认用流式。影响模块:api/user、web/src/pages/user。这种格式比一句“用户列表接口改了”有价值得多,因为 AI 不仅能记住“改过”,还能理解“为什么改”,遇到类似场景时也知道怎么决策。
4.3 给“自动回写”设定边界,防止记忆被写脏
AI 自动维护记忆,听起来省事,实际上如果不管,它也可能会把记忆写坏。最常见的两个问题:一是一股脑把对话里的临时猜测当成事实写进记忆;二是为了“更新”而更新,把原来的信息覆盖成错误的。
所以我额外规定了三条边界:
- 只能追加和标记,不能覆盖性重写。要修改历史记录前,先说明“这是变更,原因是什么”。
- 拿不准的信息,标注为“待确认”,不要直接写成事实。
- 涉及密钥、Token、密码的信息,一律不写,直接忽略。
这三条可以写在CLAUDE.md的记忆维护小节里,也可以直接写进记忆文档的“AI 与人的约定”里。实测下来,Claude Code 和 Codex 都会遵循这套关于“写作纪律”的指令。
5. 我踩过的坑,和一些该避开的边界
5.1 规则文件不是越长越好
刚开始的时候,我恨不得把项目所有信息全写进CLAUDE.md:完整的 API 列表、数据库表结构、历史背景……结果发现一个严重问题:上下文窗口是有限的,规则文件越长,模型能分配给真正代码分析的注意力就越少。
尤其当规则文件超过一定长度后,模型对规则后面部分的“遵从度”明显下降。它记得最清楚的永远是前几行。
所以我现在把规则入口控制在 60 行以内,只放身份、必读记忆、记忆维护、代码规范四块。详细的历史、决策、踩坑记录全部放进docs/PROJECT_MEMORY.md,让 AI 按需读取,而不是把所有信息一次性塞进每次会话。
5.2 两个入口文件内容打架,行为就会混乱
有一次我在CLAUDE.md里写“提交信息用中文”,在AGENTS.md里忘了写,结果 Codex 跑出来的提交信息全是英文。还有一次两边写的内容矛盾,Claude Code 做完一个操作后,Codex 又改回去了。
这类问题的根源就是“多个真相源互相干扰”。我的解法是:项目里只保留一个“记忆真相源”,也就是docs/PROJECT_MEMORY.md,CLAUDE.md和AGENTS.md只是两个读者入口,内容保持基本一致。任何会随项目变化的状态,都不进规则文件,只进记忆文档。
5.3 记忆文档也会膨胀,需要定期归档
记忆文档不是越大越好。当PROJECT_MEMORY.md长到几百行时,AI 每次读取的负担会越来越大,一些旧决策反而会干扰当前的开发判断。
我一般按月归档:把“踩坑记录”移到独立的docs/lessons.md,把“已完成的关键决策”里比较久远的内容移到docs/archive/目录下的文件,主记忆文档只保留最近一两个月内仍然有参考价值的信息。如果不需要了,就只留一行“历史决策见 docs/archive/2024-01.md”。
5.4 配置类报错,先别急着甩锅给记忆
在折腾这些 AI 工具的过程中,很多人会遇到配置相关的报错。比如 Codex 启动时报“本地模型服务切换失败”“模型提供方不匹配”之类的信息。遇到这类问题,不要急着怀疑规则文件或记忆文档。
我的排查习惯是先分三类:
- 模型服务地址没配对:打开配置文件,检查模型提供方和请求地址是否一致。
- 本地服务没启动或端口不对:如果配置指向本机服务,确认服务进程是否正常运行。
- 全局默认配置被覆盖:检查是否有全局配置或环境变量抢先覆盖了项目级配置。
先把这三类问题排除掉,再回来测记忆。很多时候这些报错和 AI 的记忆能力没半点关系,纯粹是配置项没对准。
5.5 密钥和敏感信息,永远别进记忆库
这一点再怎么强调都不为过。记忆文档是要提交到版本库、会跟着项目走的,如果你把某云服务的 API Key、生产环境的 Token 写进PROJECT_MEMORY.md,一旦仓库泄露,后果很严重。
我在规则文件里会明确写:
禁止打印、记录、输出任何密钥、Token、连接串密码。 上下文里出现敏感信息时,忽略并提醒用户用环境变量管理。密钥该放的位置是环境变量、本地.env文件(并且加进.gitignore)、系统钥匙串或专门的密钥管理服务。记忆文档只记录“用什么服务”,不记录“怎么认证”。这条也是我后来才对很多朋友反复强调的:AI 记性太好,不一定是好事,得让它忘记该忘记的东西。
这套方案我用了大半年,最早只是想解决“Claude Code 隔天就忘”的痛点,后来把 Codex 和 Qoder 也拉进同一套记忆体系之后,换工具的成本明显降低了。现在我不管用哪个工具打开项目,只要让它先读一遍docs/PROJECT_MEMORY.md,它就能立刻进入状态,不再反复问我项目背景。
最后分享一个我自己的原则:工具可以换来换去,但项目里永远只有一个真相源,谁读它谁就获得记忆。两分钟搭好底座,剩下的事情交给 AI 定期回写,长期记忆就是真的“长”出来了,而不只是一句口号。