Cursor, một AI IDE nổi tiếng vừa công bố đạt doanh thu $300M ARR, sử dụng Merkle Tree để lập chỉ mục code nhanh chóng. Bài viết này sẽ đi sâu vào cách họ thực hiện điều đó.
Trước khi đi sâu vào cách Cursor triển khai, hãy cùng tìm hiểu Merkle Tree là gì nhé.
Merkle Tree là một cấu trúc cây trong đó mỗi nút “lá” (leaf node) được gán nhãn bằng hàm băm mật mã (cryptographic hash) của một khối dữ liệu, và mỗi nút không phải lá (non-leaf node) được gán nhãn bằng hàm băm mật mã của các nhãn từ các nút con của nó. Cấu trúc phân cấp này cho phép phát hiện thay đổi ở bất kỳ cấp độ nào một cách hiệu quả bằng cách so sánh các giá trị hash.
Hãy hình dung Merkle Tree như một hệ thống “lấy dấu vân tay” cho dữ liệu:
Root hash tóm tắt toàn bộ dữ liệu chứa trong từng phần riêng lẻ, đóng vai trò như một cam kết mật mã (cryptographic commitment) cho toàn bộ tập dữ liệu. Vẻ đẹp của phương pháp này nằm ở chỗ, nếu bất kỳ phần dữ liệu nào thay đổi, nó sẽ làm thay đổi tất cả các “dấu vân tay” phía trên nó, và cuối cùng là thay đổi cả root hash.
Cursor sử dụng Merkle Tree làm thành phần cốt lõi cho tính năng lập chỉ mục Codebase của mình. Theo một bài đăng của người sáng lập Cursor và tài liệu bảo mật, đây là cách nó hoạt động:
Cursor trước tiên sẽ chia nhỏ (chunk) các file trong codebase của bạn ngay trên máy tính cục bộ, phân tách code thành các phần có ý nghĩa ngữ nghĩa trước khi bất kỳ quá trình xử lý nào diễn ra.
Khi tính năng lập chỉ mục Codebase được kích hoạt, Cursor sẽ quét thư mục đang mở trong editor và tính toán một Merkle Tree từ các hash của tất cả các file hợp lệ. Merkle Tree này sau đó được đồng bộ hóa với server của Cursor, như đã được mô tả chi tiết trong tài liệu bảo mật của Cursor.
Sau khi các chunk được gửi đến server của Cursor, các embedding sẽ được tạo ra bằng cách sử dụng API embedding của OpenAI hoặc một mô hình embedding tùy chỉnh (tôi chưa thể xác minh điều này). Các biểu diễn vector này sẽ nắm bắt ý nghĩa ngữ nghĩa của các chunk code.
Các embedding, cùng với metadata như số dòng bắt đầu/kết thúc và đường dẫn file, được lưu trữ trong một vector database từ xa (Turbopuffer). Để duy trì quyền riêng tư trong khi vẫn cho phép lọc theo đường dẫn, Cursor lưu trữ một đường dẫn file tương đối đã được làm mờ (obfuscated relative file path) cùng với mỗi vector. Quan trọng hơn, theo người sáng lập Cursor, “Không có đoạn code nào của bạn được lưu trữ trong database của chúng tôi. Nó sẽ biến mất sau khi yêu cầu được xử lý xong.”
Cứ mỗi 10 phút, Cursor sẽ kiểm tra các hash không khớp (hash mismatches), sử dụng Merkle Tree để xác định những file nào đã thay đổi. Chỉ những file đã thay đổi mới cần được tải lên, giúp giảm đáng kể mức sử dụng băng thông, như đã giải thích trong tài liệu bảo mật của Cursor. Đây chính là nơi cấu trúc Merkle Tree thể hiện giá trị lớn nhất của nó—cho phép cập nhật gia tăng (incremental updates) hiệu quả.
Hiệu quả của việc lập chỉ mục codebase phần lớn phụ thuộc vào cách code được chia nhỏ (chunk). Mặc dù giải thích trước đó của tôi chưa đi sâu vào các phương pháp chunking, nhưng bài blog post này về xây dựng tính năng codebase tương tự Cursor có đưa ra một số thông tin chi tiết thú vị:
Trong khi các phương pháp đơn giản chỉ chia code theo ký tự, từ hoặc dòng, chúng thường bỏ qua các ranh giới ngữ nghĩa—dẫn đến chất lượng embedding bị giảm sút.
Sau khi đã tìm hiểu cách Cursor tạo và lưu trữ các code embedding, một câu hỏi tự nhiên sẽ nảy sinh: các embedding này thực sự được sử dụng như thế nào sau khi chúng đã được tạo ra? Phần này sẽ giải thích ứng dụng thực tế của các embedding này trong quá trình sử dụng thông thường.
Khi bạn tương tác với các tính năng AI của Cursor, chẳng hạn như đặt câu hỏi về codebase của mình (sử dụng @Codebase hoặc ⌘ Enter), quá trình sau sẽ diễn ra:
Khả năng truy xuất được hỗ trợ bởi embedding này cho phép:
You need to login in order to like this post: click here
YOU MIGHT ALSO LIKE