3 điểm bởi GN⁺ 18 ngày trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Để 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 isPublicgroups, 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ẵnkiế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

    • Ngành thư viện học truyền thống đã nắm bắt được các mẫu hình sâu của cấu trúc thông tin từ lâu
      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
    • Tôi đang làm việc với một codebase có hơn 400 tệp Python, và RAG dựa trên embedding thường xuyên lấy về những đoạn mã không liên quan chỉ vì từ ngữ giống nhau
      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
    • Khi xây dựng hệ thống tìm kiếm cho LLM, rốt cuộc tôi lại phát minh lại chỉ mục đảo (concordance)
      Đâ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
    • Có vẻ như ai đó đã mặc định rằng RAG nhất thiết phải dùng tìm kiếm vector, và mọi người đều đi theo hướng đó
    • AI assistant rốt cuộc là một nhân vật hư cấu được LLM tự động hoàn thành, nên các cơ chế dễ diễn giải giống như tương tác ngôn ngữ của con người sẽ có lợi thế hơn
  • 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

    • Nói vậy cũng đúng, nhưng trên thực tế agent làm việc theo kiểu tệp lại cho hiệu năng tốt hơn
      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
    • Tôi đã có kết quả tốt với agentic search dựa trên cơ sở dữ liệu
      Đ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
    • Thực ra đa số hệ thống tệp cũng bên trong dùng cấu trúc cơ sở dữ liệu
      Dùng hệ thống tệp như DB không phải chuyện mới
    • Tôi nghĩ cách tiếp cận bài viết nói tới rốt cuộc chẳng phải cũng là như vậy sao
    • Tôi cho rằng tốt hơn là để agent tự khám phá trực tiếp trên nhiều nguồn dữ liệu
  • 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

    • Nếu cấp cho mỗi agent một container cô lập, thì ngay cả khi không làm gì, bộ nhớ vẫn cứ bị chiếm dụng và chi phí sẽ tăng mạnh
  • 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

    • VFS của chúng tôi dựa trên Postgres và được chiếu ra dưới dạng tệp/thư mục
      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

    • Nếu là cách đặt FUSE lên trên các chunk thì có lẽ không cần mô phỏng shell
  • 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

    • Thực tế họ đã cân nhắc adapter FUSE nhưng quá chậm
      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

    • Ở đây bài toán là tìm kiếm mã nguồn, một use case rõ ràng nên mọi thứ đơn giản 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ự
    • công nghệ OCR đã phát triển đủ tốt, nếu tài liệu có thể OCR thì cách tiếp cận này cũng có thể được khái quát hóa
    • Nếu phủ VFS lên trên một hệ thống tài liệu phức tạp thì rốt cuộc nó cũng chỉ là một biến thể của indexer, và nếu không có kiểm soát truy cập thì sẽ phát sinh vấn đề bảo mật