- Chia sẻ trải nghiệm sử dụng TensorZero làm proxy mã nguồn mở để chặn và phân tích lưu lượng giữa Cursor và các nhà cung cấp LLM (OpenAI, v.v.), đồng thời quan sát theo thời gian thực prompt, model, kết quả suy luận và thử nghiệm tối ưu hóa
- Cursor cho phép ghi đè Base URL và tên model khi gọi LLM, nên có thể dễ dàng tích hợp proxy riêng (TensorZero)
- Về mặt nội bộ, Cursor gọi LLM thông qua máy chủ riêng của họ, vì vậy để cấu hình proxy hoàn chỉnh cần reverse proxy Ngrok + Nginx cùng thiết lập header CORS
- Thông qua proxy, có thể quan sát toàn bộ system prompt, user prompt, cả các yêu cầu chỉnh sửa mã inline mà Cursor thực sự gửi tới LLM, đồng thời chuyển đổi/thử nghiệm nhiều LLM khác nhau theo thời gian thực (A/B test)
- Kết quả phân tích system prompt của Cursor cho thấy chỉ với một prompt khoảng 642 token là LLM đã có thể hiểu và xử lý phần lớn ngữ cảnh kỹ thuật phần mềm. Việc chỉnh sửa mã do một "apply model" riêng đảm nhiệm (một model phụ kém thông minh hơn)
- Với kiến trúc proxy như TensorZero, có thể thử nghiệm LLM tùy biến theo từng người dùng và tối ưu hóa dựa trên phản hồi, rất phù hợp cho đánh giá chất lượng công cụ hỗ trợ code (A/B test), tối ưu prompt và giám sát sử dụng thực tế
Giới thiệu
- Bài viết nói về trải nghiệm kết nối framework mã nguồn mở TensorZero như một gateway proxy giữa Cursor và nhiều LLM (mô hình ngôn ngữ lớn), cùng các quan sát, thử nghiệm và điểm tối ưu hóa từ cách làm này
- TensorZero là phần mềm mã nguồn mở giúp nâng cao chất lượng ứng dụng LLM bằng cách tận dụng tín hiệu phản hồi (chỉ số vận hành, hành vi người dùng, v.v.)
- Với tư cách là người dùng Cursor, tác giả đã áp dụng công nghệ này vào IDE dựa trên LLM mà mình sử dụng nhiều nhất để thử nghiệm xem thực tế các API request nào đang được trao đổi, và có thể trực tiếp thử tối ưu ra sao
Tổng quan và mục tiêu
- Cursor là trợ lý lập trình được tối ưu trên toàn bộ tập người dùng, nhưng gần như không thể thử nghiệm tối ưu hóa cá nhân hóa hay quan sát dữ liệu theo từng cá nhân
- Nếu đặt TensorZero làm proxy, có thể quan sát minh bạch toàn bộ request của Cursor, phản hồi từ LLM, prompt, model và quá trình inference, đồng thời mở rộng sang thử nghiệm và tối ưu hóa
- Vì hầu hết các phương pháp tối ưu hóa, đánh giá và thử nghiệm đều cần dữ liệu suy luận thực tế, bài viết giới thiệu cụ thể cách thu thập dữ liệu đó trong thực chiến và cách tự động hóa
Quá trình tích hợp: xây dựng gateway LLM
- Cursor hỗ trợ thay đổi tùy chỉnh OpenAI base URL và tên model
- TensorZero cung cấp endpoint inference tương thích OpenAI, vì vậy có thể kết nối Cursor tới TensorZero thay cho OpenAI
- Bằng cách đăng ký hàm
cursorzero trong TensorZero, có thể thử nghiệm nhiều model/prompt khác nhau và tự động lưu dữ liệu inference và phản hồi mà không bị phụ thuộc vào nhà cung cấp
Trở ngại đầu tiên: máy chủ riêng của Cursor
- Khi Cursor thử kết nối trực tiếp tới TensorZero cục bộ, việc này đã thất bại
- Cursor luôn ưu tiên gửi request tới máy chủ riêng của họ trước, rồi sau khi xử lý nội bộ mới tiếp tục gọi LLM
- Vì vậy thông tin xác thực được chuyển tới máy chủ của Cursor, và máy chủ đó có thể thu thập dữ liệu về toàn bộ request cũng như codebase
- Giải pháp thay thế là kết nối qua OpenRouter để kiểm tra xem trong một số tương tác của Cursor có thể dùng model bên ngoài hay không
- Tính năng Tab tự động hoàn thành của Cursor chạy trên model riêng không công khai, và có thể kết hợp với các LLM khác
- Cuối cùng, tác giả giải quyết bằng cấu trúc dùng reverse proxy và Ngrok, proxy request tới TensorZero nội bộ thông qua một endpoint công khai bên ngoài
- Đặt Nginx ở phía trước để bổ sung xác thực và tăng cường bảo mật, đồng thời hoàn tất việc định tuyến LLM bằng hàm TensorZero tùy chỉnh
- Kiến trúc cuối cùng:
- Cursor → Ngrok → Nginx(xác thực) → TensorZero(cục bộ) → LLM Provider
Trở ngại thứ hai: CORS
- Trong quá trình xác thực, request CORS preflight (OPTIONS) đi tới Nginx, khiến ban đầu phát sinh hiện tượng chưa thực hiện xác thực
- Tác giả cấu hình Nginx trả về header CORS giống với OpenAI API, từ đó đáp ứng yêu cầu của Cursor IDE dựa trên Electron
- Sau khi giải quyết vấn đề xác thực và CORS, mọi request thực tế đều được thực hiện thông qua máy chủ của Cursor
- (Có kèm ví dụ mã cấu hình Nginx)
Kết quả cuối cùng: có thể nhìn sâu vào Cursor
- Có thể quan sát theo thời gian thực mọi request/response LLM, system prompt, user prompt, nội dung code/file đính kèm
- Trong ví dụ system prompt, còn chỉ rõ lệnh để chạy một "apply model" riêng dùng cho chỉnh sửa mã (cấu trúc hai tầng model)
- Cấu trúc chính của prompt trong Cursor:
- Cung cấp ngữ cảnh như thông tin phiên người dùng, file, vị trí con trỏ, v.v.
- Phân tách khu vực bằng các khối comment
- Khi yêu cầu sửa code thì có chỉ dẫn tạo code block với nguyên tắc ‘chỉ thay đổi tối thiểu phần cần sửa’
- Prompt engineering của Cursor
- Chỉ với một system prompt lớn 642 token cũng đã tự động hóa được phần lớn tác vụ kỹ thuật phần mềm
- Tồn tại riêng một apply model ít thông minh hơn nhưng chuyên cho tác vụ thay đổi code, và model này được model chính chỉ định rõ phạm vi áp dụng cùng quy tắc
- Qua đó xác nhận rằng cấu trúc phân tầng nhiều LLM khác nhau (phân tách theo mức độ thông minh và chức năng) thực sự được triển khai ngay trong prompt
Kết luận và hàm ý
- Cursor có thể xử lý ngữ cảnh kỹ thuật phần mềm chỉ với tri thức nền tích hợp sẵn của các LLM mới nhất và prompt ngắn gọn
- Với proxy như TensorZero, có thể dễ dàng xây dựng cấu trúc tối ưu hóa dựa trên phản hồi theo từng người dùng và dữ liệu sử dụng thực tế (A/B test, tinh chỉnh prompt/model)
- Các AI hỗ trợ trong trình soạn thảo code hay doanh nghiệp triển khai LLM có thể dùng cách tiếp cận này để nhanh chóng thử nghiệm thiết kế prompt, cải thiện hiệu năng và tối ưu hóa theo từng người dùng
- Trong bài tiếp theo, tác giả dự định thử nghiệm tiếp về cách thu thập dữ liệu sử dụng thực tế, tree-sitter, git hook và các phương pháp liên quan
1 bình luận
Ý kiến trên Hacker News
Cursor là sản phẩm duy nhất trong hơn 20 năm tôi dùng các dịch vụ mà tôi đã hủy đăng ký chỉ vì hoàn toàn không có hỗ trợ khách hàng
Tôi đã gửi email nhiều lần trong nhiều tuần về câu hỏi liên quan đến thanh toán, nhưng chưa từng nhận được dù chỉ một phản hồi
Đây không phải là câu hỏi đơn giản liên quan đến VS Code, mà là vấn đề nhất định cần có sự can thiệp từ đội ngũ Cursor
Thế nhưng email quảng bá thì vẫn được gửi đều đặn
Tôi hy vọng "giá trị" của Cursor sẽ sớm lan sang các dịch vụ khác
Mong rằng đội tiếp theo sẽ trả lời email
Prompt này còn thiếu khá nhiều nội dung
Dễ thấy nhất là thiếu các tool call descriptors
Có thể so sánh trực tiếp với prompt jailbreaking từ 1 năm trước
Dù vậy, các phần cấu hình khác như cursor rules vẫn có ý tưởng khá hay
Tham khảo thêm, tài liệu prompt liên quan có thể xem tại đây
Trong Cursor, các prompt khác nhau được dùng tùy theo hành động người dùng thực hiện
Hiện tại tôi chỉ cung cấp sample, nhưng mục tiêu căn bản là A/B test nhiều mô hình khác nhau và tối ưu prompt cùng mô hình
Tôi cũng đã cung cấp code để có thể tái hiện, và từ đó có thể tham khảo thêm các prompt khác
Tài liệu Gist bạn chia sẻ cũng khá hữu ích
Tôi tự hỏi liệu có logic tối ưu nào đó để chỉ đưa vào prompt những thông tin công cụ thật sự cần thiết từ truy vấn của người dùng hay không
Có lẽ họ đang dùng chiến lược mạnh tay loại bỏ các tool descriptor không cần thiết để tiết kiệm token
Tài liệu tham khảo liên quan có ở đây
Vậy là... giờ không thể dùng wireshark nữa sao?
Ở cuối bài có ghi rõ đây mới chỉ là bài đăng đầu tiên để lướt qua trước khi quyết định sẽ dùng thế nào
Tham khảo thêm, dạo này mitmproxy khá xuất sắc cho mục đích đơn giản là xem packet mitmproxy docs
wireshark vẫn có thể dùng để xem các request từ ứng dụng desktop đến máy chủ Cursor (thực chất là các request được gửi tới LLM)
Nhưng nếu muốn xem chính xác các request đi từ máy chủ Cursor đến LLM như thế nào thì cần cấu hình riêng
Với kiểu cấu hình này, chúng ta cũng có thể thay đổi request để A/B test
Cursor và nhiều giải pháp modality cho IDE khác khá thú vị, nhưng điều đáng tiếc là chúng khiến người ta hình thành thói quen xử lý context khá cẩu thả
Nhìn vào đoạn trích từ prompt của Cursor thì là kiểu,
"Mỗi khi người dùng gửi tin nhắn, chúng tôi có thể tự động đính kèm thêm thông tin như trạng thái hiện tại, lịch sử chỉnh sửa trong phiên, lỗi linter, v.v., và những thông tin này có thể liên quan đến tác vụ lập trình hoặc không. Việc đánh giá mức độ phù hợp là do bạn quyết định"
Kiểu "context bloat" này hạn chế đáng kể hiệu năng của LLM khi giải quyết những vấn đề thực sự khó
Vấn đề .env được nêu làm ví dụ là loại đơn giản nên Cursor xử lý tốt, nhưng với mức độ phức tạp như vậy thì không thể tiếp tục thuê kỹ sư phần mềm mãi được
Cá nhân tôi đề xuất rằng khi làm việc với AI, trước tiên hãy nghĩ cách quản lý ngữ cảnh hội thoại thật gọn gàng trong giao diện chat
Trong các vấn đề phức tạp, ngữ cảnh thường đan xen giữa cuộc họp, trao đổi Slack, tài liệu nội bộ, nội dung bên ngoài và code
Tôi đã tạo các công cụ như FileKitty(link) và gần đây là slackprep(link) để lọc ra chỉ những thông tin liên quan đến việc giải quyết vấn đề, giúp sử dụng chúng có chủ đích hơn
Không phải kiểu "có thể tự động đính kèm", mà cần viết chỉ dẫn sao cho chỉ bao gồm những gì thực sự đã được đính kèm
Thay vì "có thể liên quan hoặc không, bạn tự quyết định", sẽ hiệu quả hơn nếu có chỉ dẫn rõ ràng phải làm gì trong từng trường hợp có liên quan và không liên quan
Khi ngữ cảnh ngắn thì không thành vấn đề lớn, nhưng với các issue dài và phức tạp, những instruction tinh vi như vậy tạo ra khác biệt rất lớn
Có lẽ Cursor đang cố giữ chỉ dẫn ở mức càng tổng quát càng tốt để tận dụng lợi thế về giá token được cache
Hiện vẫn còn nhiều phần đang ở giai đoạn thử nghiệm, và tôi nghĩ sau này prompt và mô hình sẽ còn được cải thiện nhiều
Có thể xem một phân tích khác về prompt của Cursor tại đây
Tôi luôn tò mò về quá trình chọn lọc ngữ cảnh liên quan trong các cuộc hội thoại dài
Tôi tự hỏi liệu đã có ai reverse engineer logic đó để tìm ra cách cắt bớt lịch sử biến đổi và biểu diễn trạng thái mới nhất của file như thế nào chưa
Tôi sẽ tiếp tục điều tra phần này, đồng thời tiếp tục các thử nghiệm tối ưu hóa mô hình và prompt bằng TensorZero
Tôi cũng đang phân tích theo cách tương tự bằng mitmproxy thảo luận liên quan
Giờ đã biết thông tin prompt, tôi tự hỏi có thể tái triển khai máy chủ Cursor để tạo ra một phiên bản hoàn toàn local (hoặc kiểu như bản crack) hay không
Hoặc ngay từ đầu cứ dùng các dự án mã nguồn mở chuyên về agent coding như Cline hay Roo Code thì hơn
Việc chờ prompt lộ ra rồi mới thử điều này quả thật hơi bất ngờ
Có vẻ mô hình apply của Cursor chạy theo kiến trúc phía máy chủ
Tôi tò mò không biết sẽ khó đến mức nào nếu tự triển khai một mô hình apply cục bộ
Có khi chạy trên MacBook còn nhanh hơn nhiều
Chắc chắn là có thể