- Giải quyết vấn đề khối lượng lớn dữ liệu thô phát sinh khi gọi công cụ bên ngoài làm tiêu hao nhanh cửa sổ context
- Nằm giữa Claude Code và đầu ra công cụ để nén và lọc dữ liệu, giảm từ 315KB xuống 5.4KB (tiết kiệm 98%)
- Thông qua kiến trúc sandbox, cô lập từng lần thực thi và chỉ đưa stdout vào context, ngăn rò rỉ dữ liệu gốc như log, snapshot, v.v.
- Với knowledge base dựa trên SQLite FTS5, lập chỉ mục nội dung Markdown và áp dụng xếp hạng BM25 cùng Porter stemming để hỗ trợ tìm kiếm chính xác các khối mã
- Trong cùng giới hạn 200K token, thời lượng phiên tăng từ 30 phút lên 3 giờ, cho phép quản lý context hiệu quả cho AI agent
Vấn đề
- Lời gọi công cụ MCP trong Claude Code sẽ đổ trực tiếp dữ liệu thô vào cửa sổ context 200K ở mỗi lần gọi
- Snapshot Playwright 56KB, 20 issue GitHub 59KB, access log 45KB, v.v.
- Sau khoảng 30 phút sử dụng, 40% toàn bộ context đã bị tiêu hao
- MCP đã trở thành tiêu chuẩn để dùng công cụ bên ngoài, nhưng tồn tại giới hạn cấu trúc khi cả định nghĩa đầu vào lẫn dữ liệu đầu ra đều lấp đầy context
- Khi kích hoạt hơn 81 công cụ, ngay trước tin nhắn đầu tiên đã tiêu tốn 72% (143K token)
Cấu trúc của Context Mode
- Là một máy chủ MCP nằm giữa Claude Code và đầu ra công cụ, chuyển tiếp dữ liệu sau khi đã giảm thiểu phần thô
- Đầu ra 315KB được rút xuống còn 5.4KB (giảm 98%)
- Mỗi lệnh gọi
execute chạy trong subprocess cô lập, thực thi độc lập mà không chia sẻ bộ nhớ hay trạng thái
- Chỉ stdout được đưa vào context, còn log, phản hồi API, snapshot, v.v. được giữ trong sandbox
- Hỗ trợ 10 runtime ngôn ngữ: JavaScript, TypeScript, Python, Shell, Ruby, Go, Rust, PHP, Perl, R
- Tự động phát hiện Bun giúp tăng tốc thực thi JS/TS lên 3~5 lần
- Các CLI đã xác thực (
gh, aws, gcloud, kubectl, docker) truyền credential an toàn bằng cơ chế kế thừa biến môi trường
Knowledge base
- Công cụ
index chia Markdown theo đơn vị heading và lưu vào bảng ảo SQLite FTS5 trong khi vẫn giữ nguyên các khối mã
- Khi tìm kiếm, dùng thuật toán xếp hạng BM25 để tính độ liên quan dựa trên tần suất từ, tần suất tài liệu nghịch đảo và chuẩn hóa độ dài tài liệu
- Áp dụng Porter stemming để “running”, “runs”, “ran” được khớp cùng một gốc từ
- Khi gọi
search, trả về khối mã chính xác và phân cấp heading thay vì bản tóm tắt
fetch_and_index sẽ lấy URL, chuyển HTML sang Markdown rồi lập chỉ mục; trang gốc không được đưa vào context
Chỉ số hiệu năng
- Trong 11 kịch bản thực tế (triage test, chẩn đoán lỗi TypeScript, rà soát git diff, v.v.), tất cả đều giữ đầu ra dưới 1KB
- Snapshot Playwright: 56KB → 299B
- Issue GitHub (20 mục): 59KB → 1.1KB
- Access log (500 dòng): 45KB → 155B
- Phân tích CSV (500 hàng): 85KB → 222B
- Git log (153 commit): 11.6KB → 107B
- Khảo sát repository (subagent): 986KB → 62KB (5 lần gọi so với 37 lần)
- Tính trên toàn phiên, giảm từ 315KB xuống 5.4KB, thời lượng phiên tăng từ 30 phút lên 3 giờ
- Context còn lại sau 45 phút: từ 60% trước đây → 99%
Cài đặt và sử dụng
- Hỗ trợ hook định tuyến tự động và lệnh slash thông qua Plugin Marketplace
- Cũng có thể cài đặt riêng cho MCP
- Có thể dùng ngay sau khi khởi động lại Claude Code
Thay đổi trong thực tế
- Không cần thay đổi cách sử dụng, hook PreToolUse sẽ tự động định tuyến đầu ra
- Subagent dùng
batch_execute làm công cụ mặc định
- Bash subagent được nâng cấp thành
general-purpose, có thể truy cập công cụ MCP
- Kết quả là cửa sổ context không còn bị lấp đầy quá nhanh, cho phép duy trì phiên dài hơn với cùng số token
Bối cảnh phát triển
- Trong quá trình vận hành MCP Directory & Hub, đã phát hiện mẫu chung là mọi máy chủ MCP đều đổ dữ liệu thô vào context
- Lấy cảm hứng từ việc Code Mode của Cloudflare nén định nghĩa công cụ, rồi mở rộng theo hướng nén dữ liệu đầu ra
- Sau khi xác nhận có thể làm việc lâu hơn gấp 6 lần trong phiên Claude Code, dự án được công bố mã nguồn mở theo giấy phép MIT
- GitHub: mksglu/claude-context-mode
1 bình luận
Ý kiến trên Hacker News
Cách tiếp cận chỉ mục FTS5 được đề xuất ở đây là đúng, nhưng tôi nghĩ cần đi xa hơn một bước
Đầu ra của công cụ là hỗn hợp giữa dữ liệu có cấu trúc (JSON, bảng, cấu hình) và ngôn ngữ tự nhiên (chú thích, thông báo lỗi, docstring), nên BM25 thuần túy hoạt động kém
Tôi đã xây một bộ tìm kiếm lai để giải quyết vấn đề tương tự bằng cách kết hợp Model2Vec + sqlite-vec + FTS5. Gộp hai kết quả tìm kiếm bằng Reciprocal Rank Fusion (RRF) sẽ cho phép tận dụng đồng thời khả năng khớp từ khóa chính xác của BM25 và khả năng khớp ngữ nghĩa của tìm kiếm vector
Lập chỉ mục gia tăng cũng rất quan trọng. Bộ lập chỉ mục của tôi dùng cờ
--incrementalđể chỉ nhúng lại các chunk đã thay đổi. Lập chỉ mục lại toàn bộ 15.800 tệp mất 4 phút, còn cập nhật gia tăng hằng ngày thì dưới 10 giâyXét về caching, cách này cũng có lợi. Với cùng một truy vấn, đầu ra đã nén là deterministic, nên prompt cache hoạt động ổn định
Một điểm có thể bổ sung vào kiến trúc Context Mode là chạy chính bộ tìm kiếm đó bằng hook PostToolUse để đầu ra được nén trước khi đi vào cuộc hội thoại
Tôi là tác giả bài viết. Vài ngày trước tôi đã chia sẻ kho lưu trữ GitHub và nhận được phản hồi tốt. Bài này là phần giải thích kiến trúc
Ý tưởng cốt lõi là thay vì đưa dữ liệu thô do lời gọi công cụ MCP dump ra vào cửa sổ ngữ cảnh 200K, Context Mode sẽ tạo một subprocess cô lập và chỉ chuyển stdout vào ngữ cảnh. Không gọi LLM, hoàn toàn dựa trên thuật toán, dùng SQLite FTS5 + BM25 + Porter stemming
Gần đây tôi đã có 228 sao và dữ liệu sử dụng thực tế, đồng thời nhận ra định tuyến subagent quan trọng đến mức nào. Nếu tự động nâng cấp Bash subagent thành loại tổng quát để dùng batch_execute, bạn có thể tránh việc lấp đầy ngữ cảnh bằng đầu ra thô
Tôi không hiểu vì sao lại không dùng chế độ mcp-cli. Tôi đã tạo một bản fork bằng wener-mcp-cli
Công việc rất ấn tượng. Tôi nghĩ vẫn còn nhiều chỗ để cải thiện hơn nữa trong quản lý cửa sổ ngữ cảnh. Ví dụ, nếu model tìm ra đáp án sau nhiều lần thử, thì cách tiếp cận backtracking để loại bỏ các lần thử thất bại khỏi ngữ cảnh có vẻ sẽ hữu ích
Đọc bài này xong tôi mới nhận ra mình hoàn toàn không biết gì về mức sử dụng token của Claude Code, nên sáng nay đã làm một CLI tên là claude-trace
Nó phân tích
~/.claude/projects/*/*.jsonlđể thống kê mức sử dụng và chi phí theo phiên, công cụ, dự án và timeline, bao gồm cả đọc/tạo cacheNếu Context Mode giải quyết tốt việc nén đầu ra, thì đây sẽ là lớp đo lường để trực quan hóa mức tiêu thụ trước và sau thay đổi
Có thể giảm đáng kể lượng token dùng bằng cách sử dụng ứng dụng CLI thay vì MCP. Ví dụ, GitHub CLI làm cùng một việc với ít token hơn nhiều so với MCP
Các hook có vẻ quá mạnh tay. Việc chặn mọi curl/wget/WebFetch và tạo snapshot sandbox 56KB thì hay đấy, nhưng với trường hợp chỉ cần 200 byte như
curl api.example.com/healththì lại quá mứcNếu nén 153 commit git xuống 107 byte, model sẽ chỉ nhìn thấy dữ liệu nếu nó tự viết được script trích xuất hoàn hảo. Chỉ cần dùng sai lệnh là thông tin cần thiết sẽ biến mất
Benchmark đang giả định model lúc nào cũng viết đúng mã tóm tắt, nhưng thực tế không phải vậy
Không tệ, nhưng có tổn thất độ chính xác và rủi ro hallucination. Do dữ liệu không đầy đủ hoặc logic trích xuất sai, Claude có thể rút ra kết luận sai. Cách này giả định MCP đủ thông minh để vừa viết script trích xuất tốt vừa tạo truy vấn tìm kiếm phù hợp. Tôi nghĩ bảo toàn thông tin trên thực tế là vấn đề rất lớn
Tỷ lệ nén rất ấn tượng, nhưng tôi tò mò liệu với ngữ cảnh đã nén, model có còn tạo ra đầu ra với chất lượng tương đương hay không. Kéo dài một phiên từ 30 phút lên 3 giờ chỉ có ý nghĩa nếu chất lượng suy luận ở giờ thứ 2 vẫn được giữ nguyên
Hiệu quả kinh tế của cache mà esafak nhắc tới cũng rất quan trọng. Nếu prompt caching hoạt động tốt thì ngay cả ngữ cảnh dài dòng cũng gần như miễn phí. Nhưng nếu việc nén phá vỡ tính liên tục của cache thì chi phí có khi còn tăng
Vấn đề căn bản hơn là phần lớn công cụ MCP đang lấy toàn bộ dữ liệu bằng SELECT *. Đây là vấn đề thiết kế giao thức: cần hỗ trợ tóm tắt và drill-down
Tôi nghi ngờ có thực sự cần đưa hơn 80 công cụ vào ngữ cảnh hay không. Ngữ cảnh quý như vàng, nên càng nhét nhiều thứ không liên quan đến vấn đề thì kết quả càng tệ. So với nén dữ liệu, tách biệt subagent có lẽ là cách tiếp cận tốt hơn