Tuần trước, tôi đã đánh mất nguyên một buổi chiều làm việc quý giá. Bốn giờ đồng hồ miệt mài gỡ lỗi một hệ thống di chuyển cơ sở dữ liệu (database migration) phức tạp, với khoảng 30 lượt trao đổi qua lại cùng Claude Code về sự phát triển schema chính xác. Sau đó, tôi đóng terminal, quay lại sau bữa tối, và khi bắt đầu một phiên làm việc mới – Claude hoàn toàn không còn nhớ gì về những gì chúng tôi đã cùng nhau tìm ra. Tệp CLAUDE.md tôi viết thì quá mơ hồ. Các commit trên Git vẫn còn đó, nhưng câu chuyện đằng sau, cái “tại sao” của các quyết định đã biến mất.
Đây chính là vấn đề “mất trí nhớ” cố hữu của Claude Code, và nếu bạn thường xuyên lập trình với các công cụ AI, chắc chắn bạn đã từng gặp phải. Mỗi phiên làm việc mới giống như một trang giấy trắng. Ngữ cảnh bạn đã xây dựng – các quyết định quan trọng, những ngõ cụt đã thử, hay những câu như “chờ đã, chúng ta đã thử cách đó rồi và nó thất bại vì…” – tất cả đều tan biến vào không khí.
Trong vài tuần qua, tôi đã dành thời gian thử nghiệm ba cách tiếp cận khác nhau để giải quyết vấn đề này. Dưới đây là những gì tôi đã khám phá và điều gì thực sự mang lại hiệu quả.
Mục lục
Thấu Hiểu Vấn Đề “Mất Trí Nhớ” Của AI Lập Trình
Trước khi đi sâu vào các giải pháp, hãy cùng làm rõ bản chất của vấn đề tôi đang cố gắng giải quyết. Thực chất, có hai vấn đề riêng biệt mà nhiều người thường gộp chung:
Vấn Đề A — Tối Ưu Hóa Ngữ Cảnh Trong Phiên (Intra-session Compaction)
- Claude Code sẽ tự động rút gọn lịch sử cuộc trò chuyện trong một phiên làm việc dài để duy trì giới hạn ngữ cảnh. Điều này khiến bạn mất đi các chi tiết cuộc trò chuyện ban đầu ngay cả khi bạn vẫn đang viết code. Nó gây khó chịu, nhưng thường có thể quản lý được.
Vấn Đề B — Liên Kết Ngữ Cảnh Giữa Các Phiên (Cross-session Continuity)
- Bạn đóng terminal. Bắt đầu một phiên mới vào ngày hôm sau. Claude hoàn toàn không biết gì về các quyết định của ngày hôm qua. Đây chính là vấn đề gây tổn thất nghiêm trọng nhất cho tôi.
Bài viết này chủ yếu tập trung vào việc giải quyết Vấn Đề B. Hãy ghi nhớ điều này khi bạn đánh giá các phương pháp tiếp cận dưới đây.
Phương Pháp 1: Hệ Thống Ghi Chú Cấu Trúc CLAUDE.md
Đây là một trong những cách tiếp cận thủ công nhưng có tiềm năng, đòi hỏi sự kỷ luật cao từ phía người dùng.
Mô Tả Phương Pháp
Bạn duy trì một tệp CLAUDE.md tại thư mục gốc của dự án và đều đặn cập nhật một thư mục notes/ với các bản tóm tắt phiên làm việc sau mỗi buổi lập trình. Mục tiêu là tạo ra một “ngân hàng kiến thức” mà Claude có thể tham khảo.
Cách Thiết Lập
Tôi đã tạo các tệp notes/YYYY-MM-DD.md sau mỗi phiên, ghi lại 5-10 gạch đầu dòng về “những gì chúng tôi đã quyết định và lý do tại sao”. Tệp CLAUDE.md chính sẽ hướng dẫn Claude đọc các tệp này khi bắt đầu phiên mới. Ví dụ cấu trúc:
# CLAUDE.md
Chào Claude,
Chúng ta đang làm việc trên dự án X. Để hiểu ngữ cảnh các phiên trước, vui lòng xem xét các ghi chú sau:
- **2023-10-26:** Quyết định sử dụng optimistic locking thay vì row-level locking vì lý do hiệu suất Y.
- **2023-10-27:** Thảo luận về refactor module Z, quyết định chia nhỏ thành các hàm nhỏ hơn A, B.
- **2023-10-28:** Đã thử nghiệm giải pháp C cho vấn đề caching, không thành công vì lý do D.
Dưới đây là một ví dụ về tệp ghi chú cụ thể:
# notes/2023-10-26.md
- **Mục tiêu phiên:** Giải quyết vấn đề đồng bộ dữ liệu.
- **Quyết định quan trọng:** Sử dụng optimistic locking cho các bản ghi user profile để tránh xung đột ghi.
- **Lý do:** Hiệu suất cao hơn so với row-level locking trong môi trường có nhiều thao tác đọc/ghi.
- **Các phương án loại bỏ:** Deadlock issues với advisory locks.
- **Tác vụ tiếp theo:** Triển khai cơ chế kiểm tra phiên bản.
Ưu Điểm
- Claude khá tốt trong việc tiếp thu ngữ cảnh từ các ghi chú được viết rõ ràng và có cấu trúc. Nếu tôi dành 3 phút cuối phiên để viết “đã quyết định sử dụng optimistic locking thay vì row-level vì lý do X”, phiên tiếp theo sẽ bắt đầu với kiến thức đó được bảo toàn.
- Hoàn toàn thủ công, không yêu cầu công cụ bên thứ ba phức tạp.
Hạn Chế
- Sự kỷ luật: Đây là yếu tố then chốt nhưng cũng là điểm yếu lớn nhất. Tôi đã bỏ qua việc viết ghi chú khoảng 40% thời gian – thường là khi tôi mệt mỏi hoặc khi phiên làm việc kết thúc trong sự thất vọng. Và đó chính xác là những phiên mà ngữ cảnh lại quan trọng nhất.
- Thông tin bị mất mát (Lossy): Ghi chú chỉ ghi lại những gì tôi nghĩ là quan trọng, chứ không phải những gì Claude thực sự thấy quan trọng trong suốt cuộc trò chuyện. Nhiều chi tiết nhỏ, những đường dẫn đã thử nhưng không thành công, có thể bị bỏ qua.
Đánh Giá
Hoạt động hiệu quả nếu bạn là người có tính kỷ luật cao. Với tôi, sự kỷ luật không phải lúc nào cũng được duy trì.
Phương Pháp 2: Tầng Bộ Nhớ SQLite qua MCP
Cộng đồng lập trình viên trên các diễn đàn như r/ClaudeAI đã và đang phát triển các máy chủ bộ nhớ cục bộ được hỗ trợ bởi SQLite, hoạt động như các công cụ MCP (Multi-Modal Command Protocol). Ý tưởng ở đây là Claude sẽ ghi lại các dữ kiện quan trọng vào một cơ sở dữ liệu trong phiên làm việc và đọc chúng lại khi bắt đầu phiên mới.
Mô Tả Phương Pháp
Ý tưởng cơ bản là sử dụng một cơ sở dữ liệu bền vững (như SQLite) để lưu trữ thông tin mà Claude “học” được. Claude được cung cấp các công cụ đặc biệt để gọi hàm “ghi nhớ” (remember()) và “nhớ lại” (recall()) thông tin này.
Cách Thực Hiện
Tôi đã tìm thấy một vài triển khai mã nguồn mở, sau đó thiết lập một trong số chúng. Máy chủ MCP chạy cục bộ, Claude Code kết nối với nó và có quyền truy cập vào các công cụ kiểu remember() và recall(). Để Claude sử dụng hiệu quả, bạn có thể hướng dẫn nó trong CLAUDE.md hoặc trong prompt đầu phiên:
# CLAUDE.md (Thêm hướng dẫn sử dụng MCP)
Chào Claude,
Hãy nhớ sử dụng công cụ `remember(key, value)` mỗi khi chúng ta đưa ra một quyết định quan trọng hoặc khám phá một thông tin cốt lõi. Ví dụ: `remember("db_lock_strategy", "optimistic")`.
Khi bắt đầu phiên mới, hãy `recall("db_lock_strategy")` để xem lại các quyết định đã có.
Ưu Điểm
- Khi Claude nhớ sử dụng công cụ này, nó hoạt động khá tốt. Tôi có thể yêu cầu nó ghi nhớ một quyết định, và nó sẽ làm như vậy. Bộ nhớ được duy trì giữa các phiên vì SQLite là một cơ sở dữ liệu bền vững.
- Lưu trữ kiến thức rõ ràng, dễ dàng truy vấn.
Hạn Chế
- Tính tự động: Claude không phải lúc nào cũng tự động sử dụng công cụ bộ nhớ khi bạn muốn. Bạn phải nhắc nhở nó hoặc thêm hướng dẫn vào
CLAUDE.mdđể nhắc nó lưu lại các quyết định. Nó không hoàn toàn tự chủ. - Thiếu ngữ cảnh trạng thái mã: Điều này thực sự gây bất ngờ. Nó có thể nhớ “chúng ta đã quyết định sử dụng optimistic locking” nhưng không thể cho tôi biết “tại thời điểm chúng ta đưa ra quyết định này, schema trông như thế nào.” Không có sự kết nối giữa bộ nhớ ngữ nghĩa với trạng thái mã thực tế tại thời điểm đó.
Đánh Giá
Tốt cho việc lưu trữ kiến thức tường minh (explicit knowledge). Yếu trong việc liên kết bộ nhớ với trạng thái mã cụ thể.
Phương Pháp 3: Phát Lại Phiên Làm Việc Liên Kết Với Trạng Thái Git
Đây là giải pháp mà tôi cuối cùng đã lựa chọn và thấy hiệu quả nhất. Công cụ cụ thể mà tôi sử dụng là Mantra – nó ghi lại các phiên lập trình AI của bạn và liên kết mỗi tin nhắn với trạng thái Git tương ứng. Nhờ đó, bạn có thể xem lại một phiên làm việc trong quá khứ và thấy mã trông như thế nào ngay tại thời điểm một quyết định được đưa ra.
Mô Tả Phương Pháp
Mantra hoạt động như một “camera giám sát” cho phiên làm việc AI của bạn. Nó không chỉ ghi lại cuộc trò chuyện mà còn lưu trữ snapshot trạng thái mã của bạn (thông qua Git) tại mỗi bước. Điều này tạo ra một “dòng thời gian” hoàn chỉnh, cho phép bạn “du hành ngược thời gian” để xem lại mọi thứ.
Ưu Điểm
- Khả năng “Du hành thời gian”: Tính năng này thực sự hữu ích. Tôi đã từng gỡ lỗi một vấn đề tuần trước, gặp bế tắc, và đã tua ngược lại một phiên làm việc từ 3 ngày trước để tìm chính xác thời điểm chúng tôi refactor một hàm mà tôi nghi ngờ là nguyên nhân. Mất khoảng 2 phút để tìm ra. Nếu không có công cụ này, tôi sẽ phải đọc lịch sử Git và cố gắng tái tạo lại câu chuyện, tốn rất nhiều thời gian.
- Ghi lại ngữ cảnh toàn diện: Tính năng phát lại cũng nắm bắt được ngữ cảnh mà tôi sẽ không bao giờ nghĩ đến việc ghi lại vào ghi chú – những câu hỏi tôi đã hỏi, những đường dẫn Claude đã đề xuất nhưng tôi từ chối, chuỗi lý luận. Những thông tin này thường hữu ích hơn cả quyết định cuối cùng.
- Hiểu rõ “tại sao”: Bạn không chỉ biết cái gì đã xảy ra, mà còn hiểu tại sao nó xảy ra, với bằng chứng là trạng thái mã cụ thể tại thời điểm đó.
Hạn Chế
- Tập trung vào cục bộ và tối giản: Công cụ này ưu tiên hoạt động cục bộ và hiện tại khá tối giản. Nó không tự động ghi bộ nhớ ngược lại cho Claude – nó là một công cụ đọc/xem lại, chứ không phải một hệ thống tự động inject ngữ cảnh. Bạn phải tự mình xem lại thông tin.
- Chưa tự động hóa hoàn toàn: Để duy trì liên kết ngữ cảnh giữa các phiên, tôi vẫn phải bắt đầu các phiên làm việc bằng cách xem nhanh các phiên trước có liên quan, sau đó viết một prompt chặt chẽ hơn với những gì tôi tìm thấy. Nó vẫn là thủ công, nhưng ít nhất thông tin đã có sẵn và dễ dàng truy cập.
Đánh Giá
Là giải pháp tốt nhất để phục hồi ngữ cảnh sau khi sự việc đã xảy ra. Không tự động giải quyết vấn đề “Claude bắt đầu lại từ đầu” nhưng làm cho quá trình phục hồi thủ công nhanh hơn rất nhiều.
Cách Tôi Thực Sự Làm Bây Giờ: Một Cách Tiếp Cận Kết Hợp
Sau nhiều thử nghiệm, tôi đã tìm ra một cách tiếp cận kết hợp các ưu điểm của từng phương pháp. Đây là chiến lược tôi đang áp dụng cho hầu hết các dự án của mình:
- SQLite MCP xử lý những khoảnh khắc “ghi nhớ điều này” một cách rõ ràng. Khi tôi cần Claude nhớ một quyết định cụ thể, tôi yêu cầu nó lưu vào MCP.
- Mantra ghi lại toàn bộ lịch sử phiên làm việc, liên kết với trạng thái Git. Điều này giúp tôi xem lại và phục hồi ngữ cảnh chi tiết sau này, đặc biệt khi cần “du hành thời gian” để hiểu một quyết định cụ thể được đưa ra trong bối cảnh mã như thế nào.
- Tôi vẫn viết các ghi chú
CLAUDE.md, nhưng ngắn gọn và chọn lọc hơn nhiều – chỉ những thông tin không hiển nhiên, những điều quan trọng nhất mà tôi muốn Claude tập trung vào ngay từ đầu phiên.
Với hầu hết các dự án, cách kết hợp này mang lại cho tôi khoảng 80% sự liên tục ngữ cảnh mà tôi mong muốn. 20% còn lại là những thứ tôi thực sự không thể tái tạo: hướng đi tinh tế mà chúng tôi đang hướng tới, ba lựa chọn thay thế mà Claude đã trình bày chi tiết mà tôi đã nói “hãy để tôi suy nghĩ về điều đó.”
Phần đó, tôi đã chấp nhận mất đi. Bạn không thể có bộ nhớ hoàn hảo trong một công cụ được thiết kế để hoạt động theo từng phiên. Điều bạn có thể làm là phục hồi nhanh hơn khi cần.
Sự Thật Không Mấy Dễ Chịu
Thành thật mà nói, không có giải pháp nào trong số này là hoàn hảo. Chúng chỉ là những cách khắc phục tạm thời cho một hạn chế trong thiết kế của công cụ AI hiện tại.
Giải pháp thực sự triệt để sẽ là khả năng duy trì phiên bản gốc – nơi Claude Code có thể tùy chọn kéo lịch sử liên quan từ các phiên trước một cách tự động, mà không cần bạn phải tự quản lý các tệp CLAUDE.md hay máy chủ bộ nhớ MCP thủ công. Một số nhà phát triển đang hướng tới điều này, và một vài vấn đề trên GitHub repo của Claude Code đã được mở từ lâu, yêu cầu chính xác tính năng này.
Cho đến lúc đó, sự kết hợp các phương pháp trên là cách tốt nhất tôi tìm thấy. Nếu bạn có một thiết lập khác hoạt động hiệu quả hơn, tôi thực sự muốn nghe ý kiến của bạn trong phần bình luận.
Nếu bạn muốn thử phương pháp phát lại phiên làm việc: Mantra là công cụ miễn phí, không yêu cầu tài khoản, hoạt động với Claude Code, Cursor và Gemini CLI.
Các Câu Hỏi Thường Gặp (FAQ)
Mantra có hoạt động với Cursor không?
Có – Cursor v0.40.0+ được hỗ trợ đầy đủ. Gemini CLI và Codex cũng vậy.
Phương pháp SQLite MCP có hoạt động với các công cụ lập trình AI khác không?
Nếu công cụ đó hỗ trợ MCP, thì có. Claude Code có hỗ trợ MCP vững chắc. Hỗ trợ của Cursor đang được cải thiện.
Liệu tất cả những chi phí bổ sung này có làm chậm quá trình lập trình thực tế của tôi không?
Việc viết ghi chú cuối phiên mất khoảng 3-5 phút. Công cụ phát lại hoạt động thụ động – nó tự động ghi lại. Bộ nhớ MCP chỉ tốn thời gian khi bạn yêu cầu nó ghi nhớ điều gì đó một cách rõ ràng. Trên thực tế, chi phí bổ sung này là nhỏ so với thời gian tôi từng phải bỏ ra để tái tạo lại ngữ cảnh đã mất.



