- Để khắc phục các giới hạn của tìm kiếm dựa trên RAG hiện có, đã chuyển sang cấu trúc hệ thống tệp ảo tổ chức tài liệu thành tệp và thư mục
- Đã triển khai ChromaFs dựa trên cơ sở dữ liệu Chroma, cho phép thực thi các lệnh
grep, cat, ls, find mà không cần sao chép tệp thực tế
- Với cách này, thời gian tạo phiên được rút từ 46 giây xuống 100 mili giây, còn chi phí tính toán bổ sung giảm xuống gần như 0 USD
- Kiểm soát truy cập được xử lý bằng lọc RBAC trên metadata đường dẫn tệp, nên không cần container riêng hay quản lý nhóm người dùng
- Kết quả là trợ lý tài liệu Mintlify có thể vận hành như một dịch vụ quy mô lớn với phản hồi tức thì, chi phí thấp và kiến trúc không trạng thái
Cách tiếp cận hệ thống tệp ảo vượt qua giới hạn của RAG
- Truy xuất tài liệu dựa trên RAG truyền thống chỉ trả về các đoạn văn bản khớp với truy vấn, nên khó trả lời nội dung trải dài qua nhiều trang hoặc tìm kiếm chính xác theo cụm từ
- Để giải quyết, cấu trúc tài liệu được chuyển sang dạng có thể duyệt như hệ thống tệp, ánh xạ mỗi trang tài liệu thành một tệp và mỗi mục thành một thư mục
- Tác nhân có thể trực tiếp duyệt tài liệu bằng các lệnh
grep, cat, ls, find, tạo nên cấu trúc cho phép tìm kiếm tài liệu như cách lập trình viên xử lý codebase
Vấn đề nghẽn cổ chai của container
- Cách tiếp cận phổ biến là tạo môi trường sandbox cô lập và sao chép kho lưu trữ để cung cấp hệ thống tệp thực cho tác nhân
- Tuy nhiên, ở trợ lý frontend, độ trễ tạo phiên trở thành vấn đề nghiêm trọng, với thời gian tạo phiên p90 khoảng 46 giây
- Với 850 nghìn cuộc hội thoại mỗi tháng, ngay cả cấu hình tối thiểu (1 vCPU, 2GiB RAM, duy trì phiên 5 phút) cũng phát sinh hơn 70 nghìn USD chi phí hạ tầng mỗi năm
- Để loại bỏ nút thắt này, cần một hệ thống tệp ảo phản hồi tức thì và vận hành với chi phí thấp
Triển khai shell ảo — ChromaFs
- Thay vì hệ thống tệp thực, chỉ cung cấp ảo giác về một hệ thống tệp ảo
- Dữ liệu tài liệu hiện có vốn đã được lập chỉ mục trong cơ sở dữ liệu Chroma, nên từ đó xây dựng ChromaFs
- ChromaFs chặn các lệnh UNIX và chuyển chúng thành truy vấn Chroma
- Kết quả là thời gian tạo phiên được rút từ 46 giây xuống 100 mili giây, còn chi phí tính toán bổ sung giảm xuống gần như 0 USD
| Metric |
Sandbox |
ChromaFs |
| P90 Boot Time |
~46 giây |
~100ms |
| Marginal Compute Cost |
~$0.0137/cuộc hội thoại |
~$0 |
| Search Mechanism |
quét đĩa |
truy vấn metadata DB |
| Infrastructure |
sandbox bên ngoài như Daytona |
tái sử dụng DB hiện có |
- Được triển khai dựa trên just-bash (Vercel Labs), hỗ trợ các lệnh
grep, cat, ls, find, cd
- Tận dụng giao diện
IFileSystem của just-bash để chuyển các lời gọi truy cập tệp thành truy vấn Chroma trong khi vẫn giữ nguyên xử lý pipe và logic cờ
Bootstrapping cây thư mục
- Vì ChromaFs cần biết những tệp nào tồn tại trước khi chạy, toàn bộ cây tệp được lưu trong collection Chroma dưới dạng JSON nén (
__path_tree__)
- Khi khởi tạo máy chủ, dữ liệu này được lấy về và khôi phục thành hai cấu trúc bộ nhớ
Set<string> của các đường dẫn tệp
Map<string, string[]> của danh sách phần tử con theo từng thư mục
- Sau đó, các lệnh
ls, cd, find được xử lý tức thì trong bộ nhớ cục bộ mà không cần gọi mạng, và các phiên tiếp theo trên cùng một site sẽ tái sử dụng cây đã cache
Kiểm soát truy cập
- Cây đường dẫn bao gồm các trường
isPublic và groups, và chỉ giữ lại các tệp mà người dùng có quyền truy cập dựa trên token phiên
- Các tệp không có quyền truy cập sẽ bị loại bỏ hoàn toàn khỏi cây, nên tác nhân không thể nhận biết sự tồn tại của những đường dẫn đó
- Trong sandbox truyền thống, việc này đòi hỏi quản lý nhóm người dùng Linux,
chmod, tách container..., còn trong ChromaFs có thể triển khai RBAC chỉ bằng logic lọc đơn giản
| Path |
Access |
Visible |
| /auth/oauth.mdx |
public |
✓ |
| /auth/api-keys.mdx |
public |
✓ |
| /internal/billing.mdx |
admin, billing |
✗ |
| /api-reference/users.mdx |
public |
✓ |
| /api-reference/payments.mdx |
billing |
✗ |
Ghép lại các mảnh tài liệu
- Tài liệu lưu trong Chroma được chia thành nhiều mảnh để phục vụ embedding
- Khi chạy
cat /auth/oauth.mdx, hệ thống lấy tất cả các mảnh có cùng slug page, sắp xếp theo chunk_index rồi hợp nhất lại
- Kết quả được cache để tránh truy vấn lại DB ngay cả trong các workflow
grep lặp lại
- Các nội dung lớn như đặc tả OpenAPI được đăng ký dưới dạng lazy file pointer, chỉ lấy từ S3 khi được truy cập
- Mọi thao tác ghi đều trả về lỗi
EROFS (hệ thống tệp chỉ đọc), giúp duy trì cấu trúc an toàn không trạng thái
Tối ưu hóa Grep
- Lệnh
grep -r sẽ rất chậm nếu chỉ quét qua mạng, nên được tối ưu bằng cấu trúc lọc hai bước
- Bước 1: dùng truy vấn Chroma (
$contains, $regex) để chọn các tệp ứng viên
- Bước 2: nạp trước vào cache Redis, sau đó
just-bash thực hiện lọc chính xác trong bộ nhớ
- Nhờ vậy, ngay cả tìm kiếm đệ quy trên quy mô lớn cũng có thể hoàn tất ở mức mili giây
Kết luận
- ChromaFs đang vận hành trợ lý tài liệu Mintlify với hơn 30 nghìn lượt mỗi ngày và hàng trăm nghìn người dùng
- Bằng cách thay thế sandbox, hệ thống đạt được khởi tạo phiên tức thì, chi phí bổ sung gần bằng 0, RBAC tích hợp sẵn và kiến trúc không trạng thái
- Có thể sử dụng trực tiếp trên mọi website tài liệu của Mintlify (mintlify.com/docs)
1 bình luận
Ý kiến trên Hacker News
Lý do việc tìm kiếm dựa trên hệ thống tệp lại được chú ý trở lại là vì chúng ta đang tái khám phá một dạng tìm kiếm ngữ nghĩa không dựa trên embedding
Cũng như thủ thư sắp xếp sách lên kệ theo chủ đề, cách tổ chức tệp theo từng miền dễ diễn giải hơn
Đây là phương thức tìm kiếm đã tồn tại từ lâu, nhưng giờ chúng ta mới lại nhận ra giá trị của nó
Bài blog liên quan
Khái niệm này cũng được thể hiện khá rõ trong Ralph Wrecks The Internet của Pixar
Tweet tham khảo 1, Tweet tham khảo 2
Thay vào đó, khi để agent tự duyệt cây thư mục, nó chỉ mất 30 giây để hiểu cấu trúc module và bắt đầu yêu cầu đúng tệp cần thiết
Tôi đã quên rằng bản thân hệ phân cấp thư mục vốn đã là một đồ thị tri thức do con người tạo ra
Đây cũng chính là khái niệm inverted index của Google, nên thật ra không hoàn toàn mới
Với tôi, RAG không cho tôi cách để trực tiếp đọc nội dung
Vì vậy giờ tôi hợp nhất tri thức thành các trang tĩnh dựa trên Markdown, rồi sau khi chỉnh sửa sẽ build thành tệp JSON để agent truy vấn nguồn này
Liên kết giải thích
Lập luận rằng tìm kiếm bằng hệ thống tệp tốt hơn RAG nghe khá khó hiểu
Tìm kiếm từ khóa kiểu grep là phương pháp cũ, còn RAG dùng tìm kiếm vector
Nhưng trong cơ sở dữ liệu, nội dung có thể được đánh chỉ mục theo phân cấp, thẻ, hoặc cấu trúc tùy ý
Tìm kiếm cũng có thể kết hợp nhiều cách như từ khóa, vector, tf-idf, BM25
Quay lại hệ thống tệp tạo cảm giác như đang quay về công nghệ từ thập niên 60
Các coding agent chạy trên CLI hành xử thông minh hơn nhiều khi được truy cập theo dạng tệp
Điểm cốt lõi là agent có thể tự thực thi nhiều truy vấn ad-hoc khác nhau
Nếu agent được tự do truy vấn trong một DB hỗ trợ cả embedding lẫn full-text search thì như vậy đã đủ agentic rồi
Dùng hệ thống tệp như DB không phải chuyện mới
Phép tính cho rằng 850.000 cuộc trò chuyện mỗi tháng dẫn tới chi phí hơn 70.000 USD mỗi năm nghe khá lạ
Tôi thắc mắc CPU và bộ nhớ được dùng vào đâu nhiều như vậy, và hóa ra là do ChromaFs dựa trên just-bash của Vercel Labs
Tôi đang rất thích thời kỳ phục hưng của các ứng dụng CLI
Tôi đã tạo một hệ thống tệp ảo mirror hệ thống tệp thật trên Mac bằng FUSE, rồi giới hạn agent chỉ trong cây đó
Mỗi repo có một agent chạy lâu dài riêng, và quyền hạn được kiểm soát bằng hệ thống tệp ảo
Dự án bashguard
Chúng tôi dùng cả hệ thống tệp ảo (VFS) lẫn RAG
Cốt lõi của RAG là chất lượng dữ liệu: tài liệu được chia theo đơn vị ngữ nghĩa và tạo metadata cùng liên kết
Mỗi chunk được embedding cùng với tài liệu bằng voyage contextual embedding
Khi tìm kiếm, agent có thể đi theo các liên kết hoặc phân tích nguyên văn
Chất lượng reranking ảnh hưởng lớn tới hiệu năng
Nó hỗ trợ grep, bm25, jq, công cụ preview..., và chạy trên Pydantic AI
Việc mô phỏng POSIX shell bằng TypeScript để thực hiện tìm kiếm phân cấp trông như một kiểu thiết kế quá mức
Mỗi lần chạy ls hay grep đều làm tăng số chu kỳ suy luận, nên độ trễ (latency) cũng tăng lên
Tôi không rõ lắm về stack kỹ thuật, nhưng tôi đã thắc mắc vì sao lại phải làm một shell giả
Giải pháp FUSE có vẻ tự nhiên hơn
Họ không cần tương thích POSIX đầy đủ, mà chỉ cần duyệt tài liệu ở chế độ chỉ đọc
Vì vậy cách chỉ hỗ trợ một phần các lệnh bash đơn giản hơn
Trong bối cảnh làm cho tài liệu có thể truy cập bằng các công cụ hệ thống tệp, AI SDK của Vercel khá thú vị
Nó đưa tài liệu .mdx vào root của gói npm để dẫn agent ưu tiên grep trên tài liệu cục bộ trước
Ví dụ SKILL.md
Đây là cách tiếp cận tốt với các startup như Mintlify, nhưng trong tổ chức phức tạp thì có thể kém thực tế
Trong môi trường có cấu trúc phi phân cấp hoặc tài liệu lẫn lộn, RAG sẽ hữu ích hơn
RAG không phải vạn năng, và đội ngũ Claude Code cũng đi tới kết luận tương tự