学习目标:深入掌握Claude Code的四层记忆架构——从CLAUDE.md项目指令到Auto Memory自动学习,从模块化规则到上下文窗口管理,构建跨会话持续记忆的工程化工作流。
适用人群:已有Claude Code基础使用经验,希望解决"每次新会话都要重新教一遍"痛点的开发者。
前置条件:已安装Claude Code CLI(npm install -g @anthropic-ai/claude-code),至少完成过一个项目。
每个Claude Code会话都从一张白纸开始。200K token的上下文窗口在关闭终端的那一刻清空。上周花三小时解释的架构决策、昨天调试发现的构建参数、反复纠正的代码风格偏好——全部归零。
这不是Bug,是设计。LLM本身是无状态的。Claude Code的记忆系统,本质上是在无状态模型之上构建的有状态持久层。理解这一点,是从"每次都要重新教"到"开箱即用"的分水岭。
Claude Code提供了四个互补的记忆机制,每一层解决不同的问题:
graph TB
subgraph "Claude Code 四层记忆架构"
L1["第一层:CLAUDE.md<br/>项目级持久指令<br/>提交到Git,团队共享"]
L2["第二层:CLAUDE.local.md<br/>个人本地偏好<br/>不提交,仅自己可见"]
L3["第三层:Auto Memory<br/>自动学习积累<br/>存储在 ~/.claude/"]
L4["第四层:模块化规则<br/>.claude/rules/*.md<br/>按场景拆分指令"]
end
L1 --> |"会话启动时加载"| CTX["上下文窗口<br/>200K token"]
L2 --> CTX
L3 --> CTX
L4 --> CTX
CTX --> |"会话中动态管理"| TOOLS["管理工具<br/>/compact /clear /memory"]
style L1 fill:#4A90D9,color:#fff
style L2 fill:#7B68EE,color:#fff
style L3 fill:#20B2AA,color:#fff
style L4 fill:#FF8C00,color:#fff
CLAUDE.md是Claude Code的核心配置文件,放在项目根目录。每次会话启动时自动加载,相当于给AI助手的一份"入职手册"。它是团队共识的载体,应该提交到Git,让所有团队成员共享同一套项目知识。
Claude Code不是只读一个CLAUDE.md——它在五个层级上查找并合并:
| 层级 | 文件路径 | 作用域 | 是否提交Git |
|---|---|---|---|
| 全局用户级 | ~/.claude/CLAUDE.md |
所有项目 | 否 |
| 项目根级 | ./CLAUDE.md |
当前项目 | 是 |
| 项目本地级 | ./CLAUDE.local.md |
当前项目,仅自己 | 否 |
| 子目录级 | ./src/CLAUDE.md |
子目录范围 | 是 |
| 模块规则 | ./.claude/rules/*.md |
按文件匹配 | 是 |
加载顺序:全局 → 项目根 → 子目录 → 模块规则。后加载的覆盖先加载的同名配置。
新手最常犯的错误是把CLAUDE.md当成README来写。CLAUDE.md不是给人看的文档,是给AI执行的指令集。好的CLAUDE.md应该简洁、精确、可操作。
反面教材(冗长无用):
# My Project
This is a full-stack application built with React and Node.js.
We use TypeScript for type safety. The database is PostgreSQL.
Our team follows agile methodology with two-week sprints...
(200行项目介绍)
正面教材(精确可执行):
# Project Instructions
## Tech Stack
- Frontend: React 19 + TypeScript 5.x (strict mode)
- Backend: Node.js 22 + Fastify 5.x
- Database: PostgreSQL 16 + Drizzle ORM
- Package Manager: pnpm (NOT npm or yarn)
## Code Style
- Use functional components, no class components
- Named exports only, no default exports
- File naming: kebab-case for utilities, PascalCase for components
- Error handling: use Result<T, E> pattern from `src/lib/result.ts`
## Commands
- `pnpm dev` — start dev server (port 3000)
- `pnpm test` — run all tests
- `pnpm db:push` — sync schema to database
- `pnpm lint:fix` — auto-fix linting issues
## Architecture
- `src/features/` — feature modules (each has routes/, components/, hooks/)
- `src/lib/` — shared utilities
- `src/server/` — API routes and services
- NEVER modify `src/generated/` — auto-generated by Drizzle
## Critical Rules
- ALWAYS run `pnpm test` after modifying any file in src/server/
- NEVER commit .env files
- Database migrations go in `drizzle/migrations/` with timestamp prefix
CLAUDE.md提交到Git,团队共享。但有些偏好是个人的——你用vim、同事用VS Code;你习惯中文注释、团队用英文。CLAUDE.local.md解决的就是这个问题。
在项目根目录创建CLAUDE.local.md,把它加入.gitignore:
echo "CLAUDE.local.md" >> .gitignore
文件内容示例:
# Local Preferences
## Editor
- I use Neovim with lazyvim config
- When showing code snippets, prefer short form
## Language
- Respond in Chinese (中文回复)
- Code comments in English
## Workflow
- I prefer step-by-step explanations
- Show me the diff before applying changes
- Run tests after each modification
## My Common Paths
- Test data: ~/projects/test-data/
- Local config: ~/.config/myapp/
还有一层~/.claude/CLAUDE.md适用于你所有的项目。适合放通用偏好:
# Global Preferences
## Style
- Use Chinese for all responses
- Keep responses concise
- Code comments in English
## Git
- Never auto-commit
- Never push without asking
- Always check git status before committing
## Safety
- Never delete files without confirmation
- Never modify .env files
- Always read before editing
Auto Memory是Claude Code最被低估的功能。当你对Claude说"记住这个"或"以后不要这样做"时,Claude会自动将这个教训写入~/.claude/目录下的记忆文件。下次会话时自动加载。
关键特性: - 自动触发:不需要手动编辑文件,对话中自然积累 - 跨项目持久:存储在用户主目录,所有项目共享 - 分层存储:按主题自动分类到不同文件
使用/memory命令查看所有已加载的记忆:
# 在Claude Code会话中输入
/memory
输出示例:
Loaded memory files:
~/.claude/CLAUDE.md (global user instructions)
./CLAUDE.md (project instructions)
./CLAUDE.local.md (local instructions)
~/.claude/memory/auto-learned.md (auto memory, 47 lessons)
./.claude/rules/typescript.md (rule: typescript conventions)
./.claude/rules/api-design.md (rule: API design patterns)
在对话中直接告诉Claude记住特定信息:
> 记住:我们的staging环境数据库密码每天自动轮换,
> 测试时用 mock-db.sh 脚本生成临时连接
> 记住:修改 src/api/ 下的文件后必须运行
> pnpm test:integration
> 记住:不要用 axios,我们项目统一用 fetch +
> src/lib/http.ts 的封装
随着使用积累,Auto Memory会自动组织成主题文件:
~/.claude/
├── CLAUDE.md # 全局指令
├── memory/
│ ├── auto-learned.md # 通用教训(主文件)
│ ├── project-patterns.md # 项目模式
│ ├── debugging-notes.md # 调试经验
│ └── api-conventions.md # API约定
Auto Memory不是越多越好。过多记忆会消耗上下文窗口的token。建议每月清理一次:
> /memory
(查看记忆列表)
> 清理auto memory中过时的条目:
> - 删除关于旧版本React的规则(已升级到React 19)
> - 删除已解决的调试笔记
> - 合并重复的API约定
当CLAUDE.md超过150行时,Claude开始选择性忽略部分指令。解决方案是将规则拆分到.claude/rules/目录下的独立文件中。这些文件按场景条件加载,不是全部一次性灌入上下文。
mkdir -p .claude/rules
按技术栈拆分:
.claude/rules/typescript.md:
# TypeScript Conventions
- Strict mode enabled (tsconfig.json > strict: true)
- Prefer `interface` over `type` for object shapes
- Use `unknown` instead of `any`, narrow with type guards
- Generic naming: T for single, K/V for key-value, TInput/TOutput for transforms
- Branded types for domain primitives (UserId, OrderId, etc.)
.claude/rules/database.md:
# Database Rules
- Using Drizzle ORM with PostgreSQL
- Schema files in `src/db/schema/`
- NEVER write raw SQL — use Drizzle query builder
- Migrations must be reversible (always include down migration)
- Use transactions for multi-table operations
- Index foreign keys automatically
.claude/rules/testing.md:
# Testing Standards
- Framework: Vitest + React Testing Library
- File naming: `*.test.ts` or `*.test.tsx`
- Co-locate tests with source files
- Use `describe/it` blocks, not `test()`
- Mock external APIs with MSW (Mock Service Worker)
- Minimum coverage: 80% for src/server/, 70% for src/features/
.claude/rules/api-design.md:
# API Design Patterns
- RESTful endpoints under `/api/v1/`
- Use Zod for request/response validation
- Error response format: `{ error: { code: string, message: string, details?: unknown } }`
- Pagination: cursor-based for lists > 100 items
- Authentication: Bearer token in Authorization header
模块化规则的关键优势在于条件加载——只在相关场景时才被注入上下文。Claude Code会根据当前对话的上下文自动判断需要加载哪些规则文件。
例如,当你讨论数据库相关问题时,database.md会被加载;讨论前端组件时,typescript.md和testing.md会被加载。这避免了无用的token消耗。
Claude Code的上下文窗口约200K token。这看起来很大,但在处理大型项目时会迅速耗尽:
| 内容类型 | 大约Token消耗 |
|---|---|
| CLAUDE.md(150行) | ~500 tokens |
| 一个中等源文件 | ~2,000-5,000 tokens |
| 一个复杂文件+对话 | ~10,000-30,000 tokens |
| 命令输出(如test结果) | ~1,000-10,000 tokens |
| Auto Memory积累 | ~500-5,000 tokens |
一个典型的深度调试会话,可能在30分钟内消耗50K+ tokens。
当上下文窗口使用超过60%时,Claude Code会自动建议压缩。你也可以手动触发:
# 在会话中输入
/compact
/compact的行为:
- 保留:CLAUDE.md、当前文件内容、关键决策
- 压缩:对话历史被总结为要点
- 丢弃:中间的试错过程、已解决的错误信息
效果:一个消耗了120K tokens的会话,压缩后可能只占40K。
可以给/compact传入提示,指定保留什么:
/compact 保留所有架构决策和数据库schema变更,丢弃调试过程
当会话已经完全偏离方向,上下文充满错误信息时:
/clear
这会清空整个对话历史,但不会丢失CLAUDE.md和Auto Memory。相当于带着所有记忆重新开始对话。
graph LR
A["开始会话"] --> B{"完成任务?"}
B -->|"是"| C["结束"]
B -->|"否,上下文>60%"| D["/compact"]
D --> B
B -->|"否,完全偏离"| E["/clear + 简要重述目标"]
E --> B
style D fill:#FF8C00,color:#fff
style E fill:#DC143C,color:#fff
实践建议:
- 一个会话聚焦一个任务,不要在一个会话中切换多个不相关的任务
- 当Claude开始"忘记"你之前说的话(上下文溢出的标志),立即/compact
- 如果/compact后仍然表现不佳,/clear后重新开始
- 长任务(>1小时)至少使用2-3次/compact
以一个全栈项目为例,展示如何从头搭建记忆系统:
# 1. 创建项目
mkdir my-saas-app && cd my-saas-app
# 2. 初始化Git
git init
# 3. 创建目录结构
mkdir -p .claude/rules src/features src/server src/lib
# Project: MySaaS
## Tech Stack
- Next.js 15 (App Router) + TypeScript 5.x strict
- Tailwind CSS 4 + shadcn/ui components
- Drizzle ORM + PostgreSQL 16 (Neon serverless)
- Auth: Clerk
- Package manager: pnpm 9.x
## Commands
- `pnpm dev` — dev server on port 3000
- `pnpm build` — production build
- `pnpm test` — vitest unit tests
- `pnpm lint` — eslint + prettier check
- `pnpm db:push` — sync Drizzle schema to DB
- `pnpm db:studio` — open Drizzle Studio
## Architecture
src/ ├── app/ # Next.js App Router pages ├── components/ # Shared UI components (shadcn/ui based) ├── features/ # Feature modules │ ├── auth/ # Authentication │ ├── billing/ # Stripe integration │ └── dashboard/ # Main dashboard ├── lib/ # Utilities (cn, format, validators) ├── server/ # API route handlers + services └── db/ # Drizzle schema + migrations
## Critical Rules
- ALWAYS run `pnpm test` after modifying server/ or lib/
- NEVER modify src/db/schema without creating a migration
- ALWAYS use `cn()` utility for className merging
- Server Components by default; add 'use client' only when needed
- API errors use `errorResponse()` from `src/lib/api.ts`
# Git相关规则
cat > .claude/rules/git.md << 'EOF'
# Git Workflow
- Commit messages: conventional commits format (feat:, fix:, chore:, etc.)
- NEVER commit without running `pnpm lint` first
- NEVER push without explicit user approval
- Always check `git status` and `git diff` before staging
- Prefer creating new commits over amending
EOF
# 安全规则
cat > .claude/rules/security.md << 'EOF'
# Security Rules
- NEVER expose API keys in client-side code
- ALWAYS validate server-side inputs with Zod schemas
- Use Clerk's `auth()` for server-side auth checks
- Rate limit all API endpoints (use `src/lib/rate-limit.ts`)
- SQL injection prevention: use Drizzle parameterized queries only
EOF
# 性能规则
cat > .claude/rules/performance.md << 'EOF'
# Performance
- Use `next/dynamic` for heavy client components
- Implement loading.tsx for route-level Suspense boundaries
- Database queries: always select specific columns, never SELECT *
- Use React `use()` for data fetching in Server Components
- Cache expensive computations with `unstable_cache` from Next.js
EOF
cat > CLAUDE.local.md << 'EOF'
# Local Preferences
- Respond in Chinese
- I use Neovim + tmux, show code in terminal-friendly format
- When debugging, show me the failing test output first
- I prefer inline error handling over try/catch wrappers
EOF
echo "CLAUDE.local.md" >> .gitignore
cat > ~/.claude/CLAUDE.md << 'EOF'
# Global Preferences
## Language
- 默认使用中文回复,代码注释可用英文
- 回复简洁明了,避免冗长解释
## General Rules
- 不要自动commit,只在用户明确要求时执行
- 始终先读取文件再编辑
- 不要主动创建文档文件,除非明确要求
- 优先编辑现有文件而非创建新文件
## Safety
- 不要提交 secrets、credentials、.env 等敏感文件
- commit message 不要自动加版本号
EOF
# 只提交团队共享的配置
git add CLAUDE.md .claude/rules/ .gitignore
git commit -m "feat: add Claude Code memory system configuration"
由Ian Paterson提出的MEMORY.md模式,是在项目中维护一个结构化的状态日志,让Claude在每次会话时了解项目进展:
# Project Memory
## Current State
- Sprint: Week 3 of 4
- Focus: Billing integration (Stripe)
- Last deployed: 2026-05-20 (v0.4.2)
## Active Threads
- [ ] Webhook handler for Stripe needs idempotency
- [ ] Dashboard charts showing stale data (cache invalidation issue)
- [x] Auth flow refactored to use Clerk's new SSR helpers
## Lessons Learned
- Drizzle `jsonb` columns need explicit type casting for PostgreSQL
- Next.js 15 `cookies()` requires `await` — non-obvious breaking change
- shadcn/ui Dialog doesn't unmount on close — memory leak in long sessions
## Decisions
- 2026-05-15: Chose Neon serverless over Supabase for Postgres (cold start acceptable for our scale)
- 2026-05-18: Decided against tRPC — REST + Zod sufficient for our 12 endpoints
- 2026-05-21: Billing will use Stripe Checkout, not Stripe Billing (simpler for MVP)
配合/compact使用,在每次会话结束前让Claude更新MEMORY.md:
> 更新MEMORY.md:记录今天的进展和未完成的任务
来自Guatu Labs的开源方案,在四层基础上增加了两层:
graph TB
subgraph "六层记忆架构"
L1["Layer 1: 全局CLAUDE.md<br/>个人身份、通用偏好"]
L2["Layer 2: 项目CLAUDE.md<br/>技术栈、命令、架构"]
L3["Layer 3: CLAUDE.local.md<br/>个人工作流偏好"]
L4["Layer 4: .claude/rules/<br/>模块化场景规则"]
L5["Layer 5: MEMORY.md<br/>项目状态日志+教训"]
L6["Layer 6: Auto Memory<br/>自动积累的教训"]
end
L1 --> L2 --> L3 --> L4 --> L5 --> L6
style L5 fill:#9370DB,color:#fff
style L6 fill:#20B2AA,color:#fff
第六层是自动化维护:通过cron job或Hook,定期让Claude自己清理和更新记忆文件:
// .claude/settings.json
{
"hooks": {
"SessionEnd": [
{
"command": "claude -p 'Review and clean up MEMORY.md. Remove resolved threads, archive old decisions older than 30 days. Keep lessons learned concise.' --allowedTools 'Edit,Read,Write'",
"timeout": 60000
}
]
}
}
对于微服务架构的团队,Karun提出的Bootstrap Repo模式值得借鉴:
# 工作空间结构
workspace/
├── bootstrap/ # 引导仓库(记忆中心)
│ ├── CLAUDE.md # 全局工作空间说明
│ ├── REPOS.md # 所有仓库清单和关系
│ └── scripts/
│ └── sync-memory.sh # 同步记忆到各仓库
├── services/
│ ├── user-service/ # 用户服务
│ │ └── CLAUDE.md
│ ├── order-service/ # 订单服务
│ │ └── CLAUDE.md
│ └── payment-service/ # 支付服务
│ └── CLAUDE.md
└── shared-libs/ # 共享库
└── CLAUDE.md
REPOS.md内容示例:
# Repository Manifest
## Architecture
user-service → shared-libs (auth, logger) order-service → user-service (REST), payment-service (gRPC) payment-service → stripe-api, shared-libs
## Common Patterns
- All services: Fastify + TypeScript + Drizzle
- All APIs: REST with /api/v1/ prefix
- All use `@shared/logger` for structured logging
- Inter-service auth: JWT with shared public key
## Key People
- user-service: @alice (lead), @bob
- order-service: @charlie (lead)
- payment-service: @alice, @diana
当你在某个服务中启动Claude Code时,它会读取该服务的CLAUDE.md,同时通过REPOS.md了解整个工作空间的上下文。
定期检查你的记忆系统消耗了多少token:
> /memory
> 分析当前加载的所有记忆文件,估算总token消耗,
> 标记出可能过时或重复的内容
| 问题 | 表现 | 解决方案 |
|---|---|---|
| CLAUDE.md膨胀 | 超过200行,后半部分被忽略 | 拆分到.claude/rules/ |
| Auto Memory积累 | 加载了上百条教训 | 每月清理,合并同类项 |
| 重复指令 | CLAUDE.md和rules都说同一件事 | 单一来源,不要重复 |
| 过时信息 | 已迁移的技术栈仍写在内 | 建立更新机制 |
| 过于冗长 | "请尽量使用函数式组件" | 精简为"Use functional components" |
有效上下文 = 200K(总窗口)
- CLAUDE.md tokens
- local.md tokens
- rules tokens(按场景加载)
- auto memory tokens
= 可用于实际工作的token
目标:将固定记忆消耗控制在5K tokens以内(约占总容量的2.5%),为实际工作保留97.5%的上下文空间。
| 文件 | 提交? | 原因 |
|---|---|---|
CLAUDE.md |
是 | 团队共享的项目知识 |
.claude/rules/*.md |
是 | 团队共享的编码规范 |
.claude/settings.json |
是 | 团队共享的权限和Hook配置 |
CLAUDE.local.md |
否 | 个人偏好 |
~/.claude/CLAUDE.md |
否 | 全局个人偏好 |
~/.claude/memory/ |
否 | 个人学习积累 |
MEMORY.md |
看情况 | 如果是项目状态日志则提交 |
sequenceDiagram
participant D as 开发者
participant C as Claude Code
participant G as Git Repo
D->>C: 开始新会话
C->>C: 加载 CLAUDE.md + rules + auto memory
D->>C: 执行任务
C->>C: 发现新的项目知识
C-->>D: 建议更新 CLAUDE.md 或 rules
D->>C: 确认更新
C->>G: 提交更新的记忆文件
Note over G: 团队其他成员<br/>pull后获得新知识
新成员clone项目后,Claude Code自动获得: - 项目技术栈和架构(来自CLAUDE.md) - 编码规范和测试标准(来自rules/) - 安全规则(来自rules/security.md) - Git工作流(来自rules/git.md)
新成员只需补充自己的CLAUDE.local.md即可开始工作。这比任何onboarding文档都更有效——因为Claude Code会主动执行这些规范,而不仅仅是展示。
原因:通常是文件太长或规则太模糊。
解决: 1. 检查CLAUDE.md是否超过200行 2. 用NEVER/ALWAYS标记关键规则 3. 将非关键规则迁移到.claude/rules/ 4. 在对话中明确引用:"按照CLAUDE.md中的规则,使用pnpm而不是npm"
原因:之前对话中Claude学到了错误的教训。
解决:
> 打开auto memory文件,删除关于"使用axios"的错误记录,
> 我们项目用的是fetch
或直接编辑文件:
# 找到auto memory文件
ls ~/.claude/memory/
# 编辑清理
vim ~/.claude/memory/auto-learned.md
原因:大型文件、长对话、过多规则同时加载。
解决:
1. 频繁使用/compact(每20-30分钟一次)
2. 拆分大任务为多个小会话
3. 减少CLAUDE.md和rules的总量
4. 使用/clear重置后用一句话重新描述任务
原因:全局Auto Memory可能包含其他项目的教训。
解决: 1. 在项目CLAUDE.md中明确写明项目名称和技术栈 2. 全局CLAUDE.md只放真正通用的规则 3. 定期清理Auto Memory中特定于某个项目的条目
原因:不同开发者有不同的编码习惯。
解决: 1. CLAUDE.md只放团队已达成共识的规则 2. 有分歧的偏好放入各自的CLAUDE.local.md 3. 将CLAUDE.md纳入代码审查——修改需要PR批准
每月执行一次:
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
