在了解使用 AI 记忆模型的之后,我们要解决一个非常实际的问题:既然已经有 CLAUDE.md,为什么还需要 claude-mem?
或者反过来说:
既然已经用了 claude-mem,CLAUDE.md 还应该写什么?
这是很多 Claude Code 用户都会遇到的问题。我的建议很简单:
CLAUDE.md 管规则,claude-mem 管经验。
不要把 CLAUDE.md 写成项目百科
很多人刚开始使用 Claude Code,会认真维护 CLAUDE.md。这是好习惯。
CLAUDE.md 可以告诉 Claude Code 当前项目的基本信息,比如技术栈、常用命令、代码风格、测试方式、目录结构、禁止事项。这些信息会在 Claude Code 工作时持续影响它的行为。
比如:
# Project Guide
## Tech Stack
- Node.js
- TypeScript
- PostgreSQL
- pnpm
## Common Commands
- pnpm install
- pnpm lint
- pnpm test
## Rules
- Do not use npm
- Do not modify generated files
- Add tests for business logic changes
这样的 CLAUDE.md 很有价值。它能帮助 Claude Code 快速进入项目,不用每次都重新问这个项目怎么跑测试、包管理器用什么、哪些文件不能改。
但问题也很容易出现。
随着使用时间变长,很多人会不断往 CLAUDE.md 里加内容。今天发现一个 Bug,加进去;明天排查一个线上问题,加进去;后天某个方案失败了,也加进去。再后来,测试注意事项、临时 workaround、历史决策、模块说明、接口兼容问题,全都塞进去。
最后,CLAUDE.md 变得越来越长。
表面上看,这是在补充上下文。实际上,这很可能是在制造上下文污染。
因为 CLAUDE.md 通常会在项目会话中被优先读取,它里面的内容越长,Claude Code 每次任务都要承受越多背景噪声。很多历史信息并不是每次都相关,但它们仍然会进入模型注意力范围。
结果就是:规则被经验淹没,稳定约束和临时状态混在一起,过期内容和当前事实混在一起。Claude Code 看似知道更多,实际更容易分不清重点。
所以,CLAUDE.md 不应该写成项目百科。
它应该保持克制。它不是项目历史档案,也不是 Bug 复盘合集,更不是所有开发经验的垃圾桶。它更像项目宪法:短、稳、明确、长期有效。
CLAUDE.md 适合保存稳定规则
判断一条信息是否应该写进 CLAUDE.md,可以问一个问题:
这条信息是否应该在几乎每一次 Claude Code 工作时都生效?
如果答案是肯定的,它就适合进入 CLAUDE.md。
比如技术栈:
## Tech Stack
- Frontend: React + TypeScript
- Backend: Node.js + NestJS
- Database: PostgreSQL
- Package manager: pnpm
这类信息长期稳定,几乎所有任务都相关。
比如常用命令:
## Common Commands
- Install dependencies: pnpm install
- Run lint: pnpm lint
- Run unit tests: pnpm test
- Run e2e tests: pnpm test:e2e
Claude Code 修改代码后,经常需要验证。把命令写清楚,可以减少它乱猜命令的概率。
比如代码规范:
## Code Style
- Use TypeScript strict mode.
- Prefer explicit return types for exported functions.
- Do not introduce new dependencies without approval.
- Keep business logic out of controllers.
这些规则会影响 Claude Code 的实现方式,适合长期保留。
比如禁止事项:
## Do Not
- Do not modify files under generated/.
- Do not commit secrets or credentials.
- Do not call real payment gateway in tests.
- Do not use npm or yarn in this repo.
这类内容尤其适合写进 CLAUDE.md,因为它们是强约束,不应该依赖 Claude Code 临时检索记忆。
比如重要路径:
## Important Paths
- src/modules/order: order domain logic
- src/modules/payment: payment and callback handling
- tests/e2e: end-to-end tests
- scripts/db: database migration scripts
这些信息能帮助 Claude Code 快速定位项目结构。
总结一下,CLAUDE.md 适合保存四类内容:
| 类型 | 特点 | 示例 |
|---|---|---|
| 项目事实 | 长期稳定 | 技术栈、目录结构 |
| 工作命令 | 高频使用 | 测试、构建、Lint |
| 强约束 | 每次都应遵守 | 禁止修改生成文件、禁止真实调用外部服务 |
| 通用规范 | 影响实现风格 | 代码风格、测试要求、依赖管理 |
这些内容的共同特点是:稳定、通用、强约束、高频使用。
只要一条信息不满足这些特点,就要谨慎放进 CLAUDE.md。
claude-mem 适合保存动态经验
和 CLAUDE.md 不同,claude-mem 更适合保存动态经验。
所谓动态经验,是指那些不一定每次任务都相关,但在特定任务中非常有价值的信息。
比如历史 Bug:
订单取消接口历史上出现过库存重复释放问题。根因是取消操作缺少幂等保护。后续修改订单状态流转时,必须覆盖重复取消、并发取消、已取消订单再次取消。
这条信息不需要每次 Claude Code 工作都看到。你让它改登录模块时,这条记忆就是噪声。但当它处理订单取消、库存释放、订单状态流转时,这条记忆价值很高。
所以它适合 claude-mem,不适合 CLAUDE.md。
再比如失败方案:
支付回调曾尝试通过请求时间戳去重,但由于第三方网关存在重试延迟,时间戳不能作为可靠幂等依据。后续应使用 callback_id + order_id 做幂等键。
这类信息非常重要,但它是经验,不是全局规则。只有在处理支付回调时才需要出现。
再比如测试策略:
优惠券金额计算修改后,必须回归满减券、折扣券、会员价、退款重算、活动叠加五类场景。历史缺陷主要集中在活动叠加和退款重算。
这类内容对测试开发很有价值,但也不该默认出现在所有任务里。它应该在处理优惠券、价格计算、退款、活动叠加时被检索出来。
再比如模块历史:
权限模块没有直接依赖组织架构服务,是为了避免权限校验链路引入远程调用。后续修改权限判断逻辑时,应优先使用本地缓存的组织关系快照。
这条记忆能解释为什么代码现在这样写。它对相关模块很重要,但不属于全局项目规则。
所以 claude-mem 适合保存这些内容:
| 类型 | 特点 |
|---|---|
| 历史 Bug | 真实发生过,未来可能复发 |
| 失败尝试 | 防止重复走错路 |
| 模块历史 | 解释当前设计原因 |
| 测试策略 | 记录风险场景和回归重点 |
| 排查结论 | 保存根因和排除项 |
| 临时阶段状态 | 支持长任务连续推进 |
这些内容的共同特点是:动态、局部、经验性、按需使用。
它们不应该常驻上下文,但应该在相关任务中被召回。这正是 claude-mem 的价值。
推荐三层上下文模型
如果把 Claude Code 的上下文系统分层,我建议使用三层模型:
| 层级 | 角色 |
|---|---|
CLAUDE.md |
项目规则层 |
| claude-mem | 项目经验层 |
| 当前会话 | 当前任务现场 |
这三层各自承担不同职责。
CLAUDE.md 是项目规则层。它回答的是:这个项目长期遵守什么规则?
比如用什么技术栈,怎么运行测试,哪些文件不能改,代码风格是什么,外部服务测试怎么 mock。
claude-mem 是项目经验层。它回答的是:这个项目过去发生过什么,哪些经验会影响当前判断?
比如哪些模块出过 Bug,哪些方案失败过,哪些场景必须回归,哪些设计是历史原因导致的。
当前会话是任务现场层。它回答的是:这次具体要做什么?当前看到的代码、日志、测试结果是什么?
比如这次要修哪个 Bug,刚刚读了哪些文件,当前测试为什么失败,最近一次命令输出是什么。
这三层不要混用。
不要把所有历史经验写进 CLAUDE.md。不要把长期稳定规则丢给 claude-mem 临时检索。不要把当前会话里的临时日志沉淀成长期记忆。
一个更合理的分工是:
| 信息类型 | 放在哪里 |
|---|---|
| 技术栈、测试命令、代码规范 | CLAUDE.md |
| 禁止事项、强约束 | CLAUDE.md |
| 历史 Bug、失败方案 | claude-mem |
| 模块设计原因、测试策略 | claude-mem |
| 当前报错、当前命令输出 | 当前会话 |
| 临时探索过程 | 当前会话,必要时总结后进入 claude-mem |
这样做的好处是,Claude Code 既能稳定遵守项目规则,又能在需要时想起项目经验,同时不会让上下文被无关历史淹没。
可直接复用的模板
最后给一个比较实用的模板。
CLAUDE.md 可以保持简洁,重点写长期稳定规则:
# Project Guide
## Tech Stack
- Runtime:
- Language:
- Framework:
- Database:
- Package manager:
## Common Commands
- Install:
- Lint:
- Unit test:
- E2E test:
- Build:
## Code Style
-
-
-
## Testing Rules
-
-
-
## Do Not
-
-
-
## Important Paths
-
-
-
注意,这里不要写太多历史 Bug,也不要写大量模块复盘。CLAUDE.md 的目标是让 Claude Code 快速理解项目基本规则,而不是承担长期记忆系统。
claude-mem 则可以沉淀类似这样的经验:
订单取消接口历史上出现过库存重复释放问题。根因是取消操作缺少幂等保护。后续修改订单状态流转时,必须覆盖重复取消、并发取消、已取消订单再次取消,重点验证库存只释放一次。
支付回调曾尝试通过请求时间戳去重,但由于第三方网关存在重试延迟,时间戳不能作为可靠幂等依据。后续应使用 callback_id + order_id 做幂等键,并覆盖重复通知和乱序通知。
权限模块没有直接依赖组织架构服务,是为了避免权限校验链路引入远程调用。后续修改权限判断逻辑时,应优先使用本地缓存的组织关系快照,并关注缓存刷新延迟。
当前会话则保留当下正在发生的任务信息:
当前任务:修复订单取消后库存偶发不一致。
已读文件:order.service.ts、inventory.service.ts、cancel-order.spec.ts。
当前发现:重复取消请求会进入库存释放逻辑,但缺少幂等拦截。
下一步:补充并发取消测试,并验证库存释放次数。
如果当前会话最终形成了稳定结论,再让它进入 claude-mem。否则就只停留在当前任务现场,不要污染长期记忆。
所以,这一篇的核心结论可以压缩成一句话:
CLAUDE.md 写稳定规则,claude-mem 记动态经验,当前会话处理即时现场。
这样分工之后,Claude Code 的上下文会更干净,也更接近一个真实工程师的工作方式。