FunTester Claude Code 三层记忆模型实践

FunTester · 2026年06月18日 · 130 次阅读

在了解使用 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 的上下文会更干净,也更接近一个真实工程师的工作方式。

FunTester 名片|万粉千文,百无一用
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册