9 điểm bởi GN⁺ 2025-06-10 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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 proxyNgrok, 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

 
GN⁺ 2025-06-10
Ý 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

    • Tôi cũng đã gặp trải nghiệm tương tự, và còn ghi lại issue liên quan
  • 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

    • Tôi cũng đồng ý với điểm này, và khi phát triển ứng dụng agent của mình tôi đã phải curate ngữ cảnh cẩn thận hơn nhiều
      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 chưa đào sâu workflow đó, nhưng vì có thể tái hiện trực tiếp công việc chúng tôi đã làm trên GitHub nên có thể tìm được manh mối từ đó
      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ể