Tưởng tượng bạn đang làm việc với hai client cùng lúc. Client A dùng TypeScript, deploy lên Vercel, có quy ước commit riêng mà bạn đã dạy CC học thuộc. Client B dùng Python, deploy lên AWS, convention hoàn toàn khác. Buổi sáng bạn ngồi vào project của client B, hỏi CC một câu đơn giản, và nó bắt đầu gợi ý theo convention của client A.
Đó là memory leak. Và nó xảy ra khi bạn không cấu hình autoMemoryDirectory đúng cách.
Bài này giải thích cách autoMemoryDirectory hoạt động, tại sao default của nó có thể là bẫy với dev nhiều project, và ba use case để cấu hình cho đúng mục đích.
Memory mặc định ở đâu
Khi CC lưu một fact vào memory (qua tool MemorySave hoặc lệnh /memory save), nó cần biết ghi vào đâu. Nếu bạn không cấu hình gì, CC dùng đường dẫn mặc định:
~/.claude/projects/<workdir-hash>/memory/MEMORY.md
Trong đó <workdir-hash> là một hash của đường dẫn thư mục làm việc hiện tại. Ví dụ:
~/.claude/projects/a3f9c821/memory/MEMORY.md <- project A
~/.claude/projects/b71de043/memory/MEMORY.md <- project B
Nhìn qua thì có vẻ ổn: mỗi project một folder hash riêng, không trộn lẫn. Vấn đề nằm ở hai điểm.
Thứ nhất: folder này gitignored và nằm trên máy cá nhân, không sync ra đâu. Chuyển máy là mất sạch context.
Thứ hai: hash là hash của đường dẫn thư mục, không phải của repo. Nếu bạn clone repo project A vào hai vị trí khác nhau trên cùng máy (ví dụ ~/WORK/projectA và ~/WORK/backup/projectA), chúng sẽ có hash khác nhau và memory không chia sẻ nhau.
Với dev một project đơn giản, hai điểm này ít khi thành vấn đề. Với dev nhiều client, nhiều repo, cần sync giữa máy, đây là giới hạn cần vượt qua.
autoMemoryDirectory là gì
autoMemoryDirectory là một setting trong settings.local.json cho phép bạn chỉ định đường dẫn tùy ý thay vì dùng hash mặc định:
{
"autoMemoryDirectory": "~/.claude/memory/client-a/"
}
Khi có setting này, CC sẽ đọc và ghi memory vào ~/.claude/memory/client-a/MEMORY.md thay vì vào folder hash. Bạn kiểm soát được tên, vị trí, và có thể quản lý folder đó bằng git nếu muốn.
settings.local.json chứ không phải settings.json
Đây là điểm quan trọng nhất của bài.
settings.local.json là file gitignored, per-machine. Nó sống trong <project>/.claude/settings.local.json và không bao giờ được commit vào repo.
settings.json (không có .local) có thể được commit vào repo và chia sẻ với cả team.
autoMemoryDirectory nên nằm trong settings.local.json vì:
- Đường dẫn
~/.claude/memory/client-a/là đường dẫn trên máy cá nhân của bạn. - Teammate của bạn có thể không có cùng cấu trúc thư mục.
- Commit một đường dẫn cố định vào
settings.jsonsẽ phá cấu hình của mọi người trong team.
project-a/
├── .claude/
│ ├── settings.json <- commit được, không chứa autoMemoryDirectory
│ └── settings.local.json <- gitignored, chứa autoMemoryDirectory
└── src/
└── ...
Cấu trúc .gitignore của project cần có:
.claude/settings.local.json
Ba use case thực tế
Use case 1: tách memory theo client
Bạn có ba client, mỗi client một dự án riêng. Bạn muốn convention, context, và quyết định kiến trúc của client A không bao giờ xuất hiện khi làm việc với client B.
Cấu trúc thư mục:
~/.claude/memory/
├── client-a/
│ └── MEMORY.md <- convention, stack, quirks của client A
├── client-b/
│ └── MEMORY.md <- context của client B
└── client-c/
└── MEMORY.md <- context của client C
Trong repo của project client A:
// project-a/.claude/settings.local.json
{
"autoMemoryDirectory": "~/.claude/memory/client-a/"
}
Trong repo của project client B:
// project-b/.claude/settings.local.json
{
"autoMemoryDirectory": "~/.claude/memory/client-b/"
}
Mỗi khi bạn mở session trong repo client A, CC đọc context của client A. Khi chuyển sang repo client B, CC đọc context của client B. Không có gì chảy qua lại.
Use case 2: tách memory theo team
Trong cùng một repo lớn, nhiều developer làm ở các domain khác nhau. Team frontend có bộ convention riêng (component structure, styling pattern, naming), team backend có bộ riêng (API design, error handling, database pattern).
Mỗi người tự đặt autoMemoryDirectory trong settings.local.json của mình:
// settings.local.json của dev frontend
{
"autoMemoryDirectory": "~/.claude/memory/team-frontend/"
}
// settings.local.json của dev backend
{
"autoMemoryDirectory": "~/.claude/memory/team-backend/"
}
Cả hai làm việc trong cùng repo, nhưng mỗi người có context riêng phù hợp với domain mình đang làm.
Biến thể: bạn có thể dùng cùng autoMemoryDirectory cho cả team nếu muốn share context chung. Hai dev cùng trỏ vào ~/.claude/memory/team-frontend/ sẽ có cùng MEMORY.md. Nhưng lúc này cần cẩn thận về conflict khi cả hai cùng ghi vào file đó.
Use case 3: share memory qua git submodule
Đây là pattern nâng cao kết hợp với bài 13 về memory submodule.
Thay vì để memory trong một folder cục bộ không sync, bạn tạo một git repo riêng cho memory, clone nó thành submodule vào ~/.claude/memory/, rồi trỏ autoMemoryDirectory vào subfolder trong submodule đó.
~/.claude/memory/ <- git submodule (repo: your-org/claude-memory)
├── project-a/
│ └── MEMORY.md
└── project-b/
└── MEMORY.md
// project-a/.claude/settings.local.json
{
"autoMemoryDirectory": "~/.claude/memory/project-a/"
}
Lúc này MEMORY.md được track bởi repo claude-memory. Bất kỳ machine nào clone submodule đó đều có cùng context. git push từ một máy là máy khác có thể git pull để nhận context mới nhất.
Pattern này giải quyết đúng vấn đề “chuyển máy là mất context” mà default behavior không xử lý được. Chi tiết về cách dựng submodule memory có trong bài 13.
Pitfall: memo bị lạc vào wrong folder
Đây là pitfall phổ biến nhất khi mới dùng autoMemoryDirectory.
Tình huống: bạn đã set autoMemoryDirectory cho project A, nhưng sau đó làm việc trong một terminal khác, trong một thư mục khác, và lưu một fact về project A. CC lúc đó không đọc settings.local.json của project A vì bạn không ở trong thư mục đó. Fact đó được lưu vào folder mặc định (hash-based), không vào ~/.claude/memory/client-a/.
Lần sau mở session trong project A, CC không thấy fact đó.
Cách tránh: trước khi lưu fact quan trọng, verify xem CC đang dùng memory directory nào:
cat .claude/settings.local.json | grep autoMemoryDirectory
Nếu output trống, CC sẽ dùng folder hash mặc định. Nếu bạn muốn fact được lưu vào đúng chỗ, hãy chắc chắn mình đang trong thư mục project đúng với file settings.local.json đúng.
Biến thể khác của pitfall: bạn rename hoặc di chuyển folder memory mà quên update autoMemoryDirectory. CC không báo lỗi. Nó tạo một folder mới theo đường dẫn mới, và MEMORY.md cũ ở đường dẫn cũ trở nên orphan.
Diagram: luồng đọc memory khi mở session
CC mở session tại /projects/project-a/
|
v
Đọc .claude/settings.local.json
|
autoMemoryDirectory set?
|
YES | NO
|
v v
custom ~/.claude/projects/<hash>/memory/
folder (per-workdir default, local only)
|
v
Nạp MEMORY.md vào L4 auto-context
L4 là lớp auto-context trong 5 lớp prompt được dựng mỗi turn (xem bài 1). Memory là một phần của L4. Trỏ đúng autoMemoryDirectory là cách để đảm bảo L4 có đúng context thay vì đọc nhầm sang context của project khác.
Tóm tắt và bài tiếp theo
- Default memory của CC là per-workdir hash, gitignored, không sync. Phù hợp cho single-project, không đủ cho multi-client hoặc multi-machine.
autoMemoryDirectorytrongsettings.local.json(gitignored) cho phép chỉ định đường dẫn tùy ý cho memory của từng project.- Ba use case chính: tách theo client, tách theo team domain, share qua git submodule.
- Đặt setting trong
settings.local.json(không phảisettings.json) để tránh phá config của teammate. - Pitfall quan trọng: lưu memo khi không ở đúng thư mục sẽ ghi vào wrong folder. Verify bằng
cat .claude/settings.local.json | grep autoMemoryDirectorytrước khi lưu.
Bài 13 giải thích pattern dùng git submodule để track memory như source code, cho phép sync context qua nhiều machine và nhiều người trong team. Đó là nền tảng để use case 3 ở trên hoạt động đúng.
Bài thuộc series Claude Code từ zero. Series plan tại bài giới thiệu.