Recall: thêm memory local cho Claude Code trên VPS
Recall 0.4.0 ghi log và tạo tóm tắt Markdown local cho từng project, không gọi network hay tốn API token. Cài trên VPS và đo phần token tiết kiệm.
Recall làm gì cho memory của Claude Code
Recall là một plugin của Claude Code, cung cấp memory cho từng project qua nhiều session. Plugin ghi 2 file markdown vào thư mục .recall/ bên trong project: một log chỉ ghi thêm về những gì đã xảy ra và một bản tóm tắt ngắn về nơi bạn đã dừng lại. Cả 2 file đều được tạo trên máy bạn đang làm việc bằng một local Python summarizer, nên bản thân memory không tốn API token nào.
Nó giải quyết một khoảng trống nhỏ nhưng thường xuyên xảy ra. Bạn đóng một session trên VPS vào thứ Ba. Đến thứ Tư, một session mới không tự động tải lại cuộc trò chuyện của thứ Ba, dù auto memory tích hợp của Claude Code có thể giữ lại ghi chú giữa các session. Nếu những ghi chú đó không cho biết bạn đã dừng ở đâu, bạn phải tự giải thích lại project, hoặc để model đọc lại một nửa repository để tự xác định. Cả 2 cách đều tốn token, và cách thứ hai tốn rất nhiều token.
Recall version 0.4.0, phát hành ngày 18 July 2026, vẫn là bản release mới nhất tính đến October 2026, và project được cấp phép theo MIT. Đây là một plugin. Nó không thực hiện network call nào.
Bạn cần gì trên VPS
Các capture hook của Recall là những script Python đi kèm với plugin. Chúng không có dependency bên thứ ba, nên yêu cầu thực tế duy nhất là một interpreter.
python3 -VUbuntu 24.04 đáp ứng Python 3.12.3. Recall hỗ trợ Python 3.9 trở lên. Một số container image tối giản hoàn toàn không có interpreter, khi đó shell trả về python3: command not found. Hãy cài một interpreter trước khi tiếp tục.
sudo apt update && sudo apt install -y python3NumPy là accelerator tùy chọn cho một bước trong summarizer. Bạn không cần cài nó.
python3 -c "import numpy"ModuleNotFoundError: No module named 'numpy' là câu trả lời chấp nhận được ở đây. Summarizer có một đường xử lý bằng pure Python, và test suite của dự án kiểm tra để bảo đảm cả hai đường xử lý đều chọn cùng các câu.
Session memory quan trọng trên server hơn trên laptop, vì công việc trên server thường diễn ra trong những lần truy cập ngắn, cách nhau nhiều ngày. Nếu bạn đã có Claude Code chạy trong tmux trên VPS, Recall là thành phần đưa session của ngày hôm qua vào ngày hôm nay.
Cài đặt Recall từ marketplace của plugin
Hai lệnh được nhập trong một phiên Claude Code:
/plugin marketplace add raiyanyahya/recall
/plugin install recall@recallLệnh thứ hai đọc plugin@marketplace. Cả hai tên đều là recall ở đây. Điều này trông giống lỗi copy-paste nhưng thực ra không phải.
Kiểm tra cài đặt bằng một trong các lệnh của chính plugin:
/recall:show/recall:show in bản tóm tắt hiện tại. Với một project hoàn toàn mới, chưa có gì để in, nên điều bạn thực sự kiểm tra là lệnh có tồn tại hay không. Nếu Claude Code không nhận diện /recall:show, plugin chưa được load và không có hook nào chạy.
Nếu muốn chạy từ một checkout, hãy clone repository rồi kiểm tra trước:
git clone https://github.com/raiyanyahya/recall ~/recall
cd ~/recall && claude plugin validate .claude plugin validate . đọc manifest trong .claude-plugin/ và báo plugin có đúng cấu trúc hay không. Sau đó khởi động Claude Code từ thư mục project bằng claude --plugin-dir ~/recall.
Nội dung các hook ghi lại và thời điểm chạy
Recall đăng ký 3 hook cho Claude Code. Mỗi hook chạy một Python script từ thư mục plugin.
SessionStartchạy khi khởi động, tiếp tục và xóa session. Nó hiển thịcontext.mdđể session mở ra với phần tóm tắt ngay trước mắt bạn.Stopchạy mỗi khi Claude hoàn tất một phản hồi. Nó thêm lượt đó vào log.SessionEndchạy khi session đóng và có thể tạo lại phần tóm tắt.
Các hook này tạo ra 2 file, đều nằm trong .recall/.
history.mdlà bản ghi chỉ ghi nối thêm: prompt, phản hồi, file đã truy cập và command đã chạy.context.mdlà bản tóm tắt được tạo tự động: mục tiêu, tóm tắt, các bước tiếp theo, file đã truy cập, command đã chạy và ngữ cảnh git.
Sau một session thực tế, hãy xem thư mục.
ls -la .recall/Khi capture được bật, không có pause marker và transcript khả dụng, bạn sẽ thấy history.md có nội dung. Bạn có thể không thấy context.md nào, và đó là hành vi mặc định chứ không phải lỗi. auto_save_context là off nếu bạn không thiết lập, nên phần tóm tắt chỉ được ghi khi bạn yêu cầu:
/recall:saveCommand đó chạy summarizer cục bộ trên history.md và ghi đè context.md. Thuật toán sử dụng điểm TF-IDF (term frequency, inverse document frequency), sau đó xếp hạng câu bằng TextRank. Kết quả có tính xác định và mang tính trích xuất, nghĩa là nó chọn các câu đã có trong log. Không có model nào được gọi, nên bước này không mất phí và hoạt động được khi máy offline.
Cấu hình Recall cho một project
Cấu hình nằm trong file recall.config.json ở thư mục gốc của project. Đây là các giá trị mặc định đi kèm:
{
"output_dir": ".recall",
"capture_history": true,
"summary_sentences": 8,
"redact": true,
"include_git": true,
"max_input_chars": 200000
}output_dirxác định vị trí của hai file. Hãy giữ chúng bên trong project.capture_historybật hoặc tắt loghistory.md.auto_save_contextnhậnoffhoặcon_end, và mặc định làoff.summary_sentencesxác định số câu được giữ lại trongcontext.md. Tăng giá trị này sẽ tạo bản tóm tắt dài hơn và làm tăng nhẹ tải khi bắt đầu session.redactloại bỏ các mẫu secret phổ biến trước khi ghi bất kỳ dữ liệu nào vào disk.include_gitthêm thống kê diff hiện tại và các commit gần đây vào bản tóm tắt.max_input_charsgiới hạn lượng dữ liệu từhistory.mdmà summarizer đọc trong một lần.
Với project chạy trên VPS, thay đổi hữu ích là bật tính năng tự động lưu, vì session trên server thường kết thúc khi terminal bị đóng thay vì khi bạn chủ động dừng.
{
"auto_save_context": "on_end",
"summary_sentences": 12
}Để tạm dừng việc capture mà không sửa config, hãy tạo pause marker. Xóa marker này để bắt đầu capture lại.
touch .recall/.capture-pausedHãy làm việc này trước session xử lý credential production, vì redaction chỉ là một bộ lọc và không phải cơ chế bảo đảm. Lý do tương tự cũng áp dụng cho việc không đưa secret vào AI agent nói chung: secret an toàn là secret mà agent không bao giờ nhìn thấy.
Recall tiết kiệm bao nhiêu token?
Điều này phụ thuộc vào phương án thay thế. Nạp một bản tóm tắt khi bắt đầu session có chi phí thấp. Nội dung mà nó thay thế có thể tốn nhiều hơn, vì model không có memory về project sẽ phải đọc các file để tìm hiểu lại project.
Dữ liệu đằng sau biểu đồ này
[
{
"label": "Recall context.md",
"char_count": "4,800",
"est_tokens": "1,200"
},
{
"label": "Hand-written CLAUDE.md",
"char_count": "3,200",
"est_tokens": "800"
},
{
"label": "Re-reading the repo",
"char_count": "120,000",
"est_tokens": "30,000"
},
{
"label": "Full transcript replay",
"char_count": "340,000",
"est_tokens": "85,000"
}
]Đây là các con số điển hình cho một project quy mô trung bình, không phải số đo của bạn. Một bản tóm tắt Recall được nạp với khoảng 1,200 token, phù hợp với tuyên bố của project là resume cần từ một đến hai nghìn token. Phát lại toàn bộ transcript trước đó sẽ nạp lại toàn bộ conversation, khoảng 85,000 token. Để model tự tìm hiểu lại project bằng cách đọc các file có chi phí nằm giữa hai mức này, khoảng 30,000 token, và con số đó tăng theo repository. Dòng CLAUDE.md được đưa vào để làm mốc so sánh: nó rẻ hơn vì ngắn và tĩnh, đồng thời cho model biết các quy tắc cố định của bạn thay vì những gì đã xảy ra tối qua.
Hãy tự đo các con số của bạn. Một token tương đương khoảng bốn ký tự trong văn xuôi tiếng Anh và ít hơn một chút đối với code. Nếu bạn cũng cấp bản tóm tắt cho local model trên cùng VPS, hãy kiểm tra window mà bản tóm tắt được đưa vào trước khi tin dùng resume, vì context length mặc định của Ollama phụ thuộc vào VRAM khả dụng.
wc -c .recall/context.md .recall/history.md
echo $(( $(wc -c < .recall/context.md) / 4 ))Trong một session, /context hiển thị nội dung đang được nạp vào context window, còn /cost báo cáo tổng số token của session. Hãy khởi động một session trong trạng thái hoàn toàn mới, sau đó khởi động session tiếp theo với bản tóm tắt có sẵn và so sánh hai kết quả. Để xem đầy đủ token của một session thực sự được dùng vào đâu, cách Claude Code sử dụng token có phần phân tích chi tiết.
Có một điểm cần lưu ý để nhận định này vẫn chính xác. Bản tóm tắt được nạp khi bắt đầu mỗi session, nên bản tóm tắt mà bạn không sử dụng chỉ là một khoản chi phí nhỏ chứ không phải khoản tiết kiệm. Hãy giữ summary_sentences gần giá trị mặc định trừ khi session của bạn chạy trong thời gian dài. Session ít thay đổi cũng giúp ở phía còn lại của bài toán, vì agent được hướng đến thay đổi nhỏ nhất nhưng vẫn hoạt động sẽ tạo ra log ngắn hơn để trình summarizer xếp hạng.
Dựng lại bản tóm tắt mà không cần session
Nếu bạn đã clone repository, summarizer có entry point riêng trên command line. Tính năng này hữu ích trên VPS khi session kết thúc cùng terminal nhưng bạn vẫn muốn có bản digest.
python3 ~/recall/scripts/make_context.py --helpPhần output trợ giúp liệt kê các flag mà nó chấp nhận: --cwd để chỉ định project root, --transcript để chỉ định rõ file transcript, --quiet để ẩn output và --harness để chọn giữa claude và opencode. Trỏ nó vào một project:
python3 ~/recall/scripts/make_context.py --cwd /srv/projects/apiNó đọc transcript của session và history.md, sau đó ghi context.md vào directory bạn đã truyền vào. Nếu cài qua marketplace, plugin nằm trong directory do Claude Code quản lý, và /recall:save là cách được hỗ trợ để thực hiện cùng công việc.
Vì sao không có gì được ghi
Không có thư mục .recall/ sau một phiên làm việc hoàn chỉnh. Kiểm tra xem capture có bị tắt không, thư mục đầu ra có được cấu hình ở nơi khác không, hoặc có transcript nào được tìm thấy không, rồi mới kết luận rằng các hook chưa chạy. Nhập /recall:show để xác nhận plugin đã được nạp, sau đó chạy python3 -V. Lệnh hook thử python3 trước và python sau, nên máy không có cả hai lệnh này sẽ lỗi với stderr và exit status 127. Claude Code hiển thị thông báo lỗi hook không chặn thao tác, trong đó có dòng đầu tiên của stderr.
history.md tăng nhưng context.md không bao giờ thay đổi. Theo mặc định, auto_save_context là off. Chạy /recall:save, hoặc đặt key thành on_end rồi để hook SessionEnd thực hiện việc đó.
Các file xuất hiện dưới sai project. Recall ghi theo đường dẫn tương đối với thư mục nơi Claude Code được khởi động, nên nếu bắt đầu phiên từ thư mục home thì memory sẽ được lưu ở đó. Hãy khởi động từ project root và dùng ls -la .recall/ để tìm vị trí thực tế của các file.
Capture dừng nhưng không có cảnh báo. Kiểm tra pause marker bằng ls -a .recall/. File .capture-paused do bạn tạo từ tuần trước vẫn đang có tác dụng.
Bản tóm tắt quá sơ sài sau một phiên dài. max_input_chars giới hạn input của summarizer ở 200000 ký tự, nên log rất dài sẽ bị cắt. Hãy rotate log.
mv .recall/history.md .recall/history-2026-07-30.mdSau đó chạy một phiên ngắn và kiểm tra lại ls -la .recall/ để xác nhận một history.md mới đã xuất hiện.
Recall dừng ở đâu
Recall là một log kèm bộ tóm tắt. Cần nói rõ những gì cách này không bao quát.
Bộ tóm tắt dùng phương pháp trích xuất. TextRank chọn các câu đã có sẵn trong history.md, nên không bao giờ đánh giá một quyết định là đúng hay sai. Một hướng xử lý sai được ghi lại vào thứ Ba sẽ có hình thức giống hệt một quyết định đúng vào thứ Tư. Khi vấn đề có rủi ro thực tế, hãy đọc context.md và sửa thủ công. Đây là một file markdown, và không có gì ngăn bạn chỉnh sửa nó.
Không có chức năng tìm kiếm. Mỗi project chỉ có một bản tóm tắt hiện tại và một log tăng dần, không có bộ nhớ có thể truy vấn giữa các project. Nếu câu hỏi là bạn đã quyết định gì về database vào ba tuần trước, bạn phải grep history.md. Recall cũng không hỗ trợ phối hợp theo thời gian thực: hai session trong cùng một project dùng chung file log, nhưng Recall không đẩy các entry log mới vào context của session còn lại. Vì vậy, khi một session cần biết session kia đang làm gì, các session có thể truyền trực tiếp văn bản cho nhau trong lúc chạy.
Recall không hỗ trợ bên trong một session. Context window bị đầy giữa session là một vấn đề khác, với cách xử lý khác. Quản lý context window trong một session là bài viết đi kèm với hướng dẫn này.
Theo thiết kế, summary được xem là input không đáng tin cậy. context.md được chèn vào trong fenced block và có nhãn, sau đó Claude sẽ hỏi trước khi dựa vào nội dung đó. Thiết kế này cần thiết vì thư mục .recall/ đã commit là nơi bất kỳ ai có quyền commit cũng có thể ghi văn bản mà agent của bạn sẽ đọc. Agent dừng lại để hỏi về nội dung đã đọc ở mức nào phụ thuộc vào permission mode mà session sử dụng khi khởi động. Với Claude Code v2.1.283 trở lên, auto mode đã là mode khởi động tích hợp sẵn cho các session terminal tương tác và VS Code trên mọi plan và provider, nên một classifier sẽ xem xét phần lớn action thay cho bạn; các tổ chức dùng cấu hình HIPAA vẫn khởi động ở Manual mode. Hãy quyết định một lần xem .recall/ là dữ liệu cá nhân hay dùng chung: thêm nó vào .gitignore để lưu bộ nhớ cá nhân, hoặc commit nó rồi review như mọi đóng góp khác. Nếu agent chạy không cần giám sát, chạy Claude Code an toàn trên VPS trình bày phạm vi rộng hơn.
Redaction chỉ mang tính tương đối. Nó nhắm đến các mẫu phổ biến như API key, token, block PEM và các assignment .env. Hãy đọc .recall/ trước khi commit nó.
Số phiên bản phản ánh đúng mức độ hoàn thiện. Ở phiên bản 0.4.0, vẫn là release mới nhất vào tháng 10 năm 2026, các config key và layout file vẫn có thể thay đổi giữa các release. Vì vậy, hãy đọc changelog trước khi nâng cấp một setup mà bạn phụ thuộc vào.
FAQ
Recall có gửi code hoặc transcript đi đâu không?
Không. Các capture hook và summarizer là những Python script chạy trên máy của bạn, plugin không giữ API key và không thực hiện network call nào. Việc tạo summary dùng TF-IDF và TextRank thay vì model, nên bước này không tốn phí và vẫn hoạt động khi máy offline. Đổi lại, summary có tính extractive: nó chọn các câu từ log của bạn thay vì viết câu mới.
Vì sao .recall/context.md bị thiếu hoặc đã lỗi thời?
auto_save_context mặc định là off, nên summary chỉ được tạo lại khi bạn chạy /recall:save. Đặt "auto_save_context": "on_end" trong recall.config.json để summary được ghi lại khi mỗi session kết thúc. Nếu history.md cũng bị thiếu, hãy kiểm tra capture_history, marker .capture-paused và xem có transcript của session hay không: các hook đang chạy sẽ bỏ qua việc ghi history trong những trường hợp đó. Xác nhận plugin đã được load bằng /recall:show, rồi xác nhận python3 -V trả lời trên máy đó, vì các hook là Python script.
Recall tiết kiệm bao nhiêu trong mỗi session?
Việc load summary tốn khoảng 1,200 token, so với khoảng 30,000 token khi model phải đọc lại repository để xác định đang ở đâu. Đây là các con số điển hình. Hãy đo trên hệ thống của bạn bằng wc -c .recall/context.md và command /context trong một session, rồi so sánh cold start với lần khởi động tiếp tục từ summary.
Tôi vẫn cần file CLAUDE.md chứ?
Có, và hai thứ này đảm nhiệm các vai trò khác nhau. CLAUDE.md là nội dung bạn chủ động viết: các quy tắc áp dụng lâu dài và các lệnh build. context.md được tạo từ những gì thực sự xảy ra trong session trước, nên nó chứa cả migration đang làm dở mà bạn sẽ không bao giờ nghĩ đến việc ghi lại. Hãy giữ cả hai.
Một VPS có thể lưu memory cho nhiều project không?
Có. Recall lưu memory trong .recall/ bên trong thư mục của từng project, nên hai project trên cùng server giữ các log và summary riêng biệt. Luôn khởi động Claude Code từ project root, vì các file đi theo working directory chứ không đi theo user account.