Cursor의 LLM 클라이언트 리버스 엔지니어링 하기
(tensorzero.com)- TensorZero를 오픈소스 프록시로 활용해, Cursor와 LLM 제공자(OpenAI 등) 사이의 트래픽을 가로채 분석하고, 프롬프트·모델·추론 결과를 실시간으로 관찰 및 최적화 실험한 경험 공유
- Cursor는 LLM 호출 시 Base URL과 모델명을 오버라이드할 수 있어, 자체 프록시(TensorZero)를 손쉽게 연동 가능
- 내부적으로 Cursor는 자체 서버를 거쳐 LLM을 호출하므로, 완전한 프록시 구성을 위해 Ngrok + Nginx 리버스 프록시 및 CORS 헤더 세팅이 필요함
- 프록시를 통해 Cursor가 실제로 LLM에 보내는 system prompt, user prompt, 인라인 코드 편집 요청까지 모두 관찰 가능하며, 다양한 LLM(A/B 테스트)로 실시간 전환/실험이 가능
- Cursor의 system prompt 분석 결과, 불과 642 토큰 정도의 프롬프트만으로 대부분의 소프트웨어 엔지니어링 문맥을 LLM이 이해·처리함. 코드 편집은 별도의 "apply model"(덜 지능적인 보조 모델)이 담당
- TensorZero와 같은 프록시 구조로, 사용자별 맞춤형 LLM 실험 및 피드백 기반 최적화가 가능하며, 이 구조는 코드 보조 도구의 품질 평가(A/B 테스트), 프롬프트 최적화, 실사용 모니터링에 이상적임
소개
- TensorZero 오픈소스 프레임워크를 Cursor와 각종 LLM(대형 언어 모델) 사이에 프록시 게이트웨이로 연결한 경험과 이로 인한 관찰, 실험, 최적화 지점을 다룸
- TensorZero는 피드백 신호(생산 지표, 사용자 행태 등)를 활용해 LLM 애플리케이션의 품질을 높일 수 있도록 도와주는 오픈소스임
- Cursor 사용자로서 가장 많이 쓰는 LLM 기반 IDE에 이 기술을 적용해, 실제로 어떤 API 요청이 오가는지, 그리고 어떻게 최적화를 직접 시도할 수 있는지 실험함
전체 개요 및 목적
- Cursor는 사용자 전체를 기준으로 최적화된 코딩 어시스턴트이지만, 개인별 맞춤형 최적화 실험과 데이터 관찰이 거의 불가능함
- TensorZero를 프록시로 두면, Cursor의 요청과 LLM 응답, 프롬프트, 모델, 인퍼런스 과정 전체를 투명하게 관찰하고, 실험하며, 최적화까지 확장 가능함
- 대부분의 최적화 및 평가, 실험 방법에는 실제 추론 데이터가 필수이므로, 이를 수집하는 실전 방법과 자동화 방식을 구체적으로 소개함
연동 과정: LLM 게이트웨이 구축
- Cursor는 OpenAI base URL과 모델명을 사용자 정의로 변경할 수 있도록 지원함
- TensorZero는 OpenAI 호환 인퍼런스 엔드포인트를 제공하기 때문에, Cursor를 OpenAI 대신 TensorZero로 연결이 가능함
- TensorZero 내에
cursorzero
함수 등록을 통해, 다양한 모델/프롬프트 실험과 제공사에 종속되지 않는 인퍼런스 및 피드백 데이터 자동화 저장이 가능함
첫 번째 장애물: Cursor 자체 서버
- Cursor가 로컬 TensorZero에 직접 연결을 시도했으나 실패함
- Cursor는 항상 우선 자체 서버에 요청을 보내고, 내부적으로 추가 처리 후 LLM 호출을 이어감
- 이로 인해 자격 증명이 Cursor 서버로 전달되며, 해당 서버가 모든 요청 및 코드베이스에 대한 데이터 수집이 가능해짐
- 대안으로, OpenRouter로 연결하며 일부 Cursor 내 상호작용에서 외부 모델 이용 가능 여부를 점검함
- Cursor의 Tab 자동완성은 자체 비공개 모델로 동작, 다른 LLM과 조합 가능함
- 최종적으로 reverse proxy와 Ngrok을 활용, 외부 공개 엔드포인트를 통해 내부 TensorZero에 요청을 프록시하는 구조로 해결함
- Nginx를 앞단에 두어 인증 추가 및 보안 강화, 커스텀 TensorZero 함수로 LLM 라우팅까지 완료함
- 최종 구조:
- Cursor → Ngrok → Nginx(인증) → TensorZero(로컬) → LLM Provider
두 번째 장애물: CORS
- 인증 시 CORS preflight(OPTIONS) 요청이 Nginx에 도달하며, 초기 인증 미수행 현상 발생
- Nginx에서 OpenAI API와 동일한 CORS 헤더를 반환하도록 설정하여, Electron 기반의 Cursor IDE 요구사항 충족함
- 인증 및 CORS 문제 해결 후, 모든 실제 요청은 Cursor 서버 경유로 이뤄짐
- (Nginx 설정 예시 코드 포함)
최종 결과: Cursor 들여다 보기 가능해짐
- 모든 LLM 요청/응답, system prompt, user prompt, 첨부 코드/파일 내용을 실시간 관찰 가능
- system prompt 예시에는, 코드 편집용 별도 "apply model"을 구동하는 명령까지 명시됨 (이중 모델 계층 구조)
- Cursor 프롬프트의 주요 구조:
- 사용자 세션 정보, 파일·커서 위치 등 맥락 제공
- 코멘트 블록 등으로 구역 표시
- 코드 수정 요청시에는 ‘변경 부분만 최소화’ 코드블록 생성 지침
- Cursor의 프롬프트 엔지니어링
- 642토큰의 대형 시스템 프롬프트 하나만으로도 대다수 소프트웨어 엔지니어링 업무가 자동화됨
- 코드 변경 작업에 특화된 덜 지능적인 apply model(보조 모델)이 별도로 존재하며, 메인 LLM에 명확하게 적용 대상과 규칙을 지정
- 다양한 LLM 계층 구조(지능, 기능 분리)가 실제 프롬프트 내부에 구현된 점을 확인함
결론 및 시사점
- Cursor는 최신 LLM의 기본 내장 지식과 간결한 프롬프트만으로 소프트웨어 엔지니어링 문맥 처리가 가능
- TensorZero 등 프록시로 사용자별 피드백, 실사용 데이터 기반의 최적화(A/B 테스트, 프롬프트/모델 튜닝) 구조를 쉽게 구축할 수 있음
- 코드 에디터 보조 AI, LLM 도입 기업은 이 방식을 통해 프롬프트 설계, 성능 개선, 사용자별 최적화를 신속하게 실험할 수 있음
- 차기 글에서는 실제 사용 데이터 수집 방식, 트리시터, git hook 활용법 등 후속 실험을 할 예정
Hacker News 의견
-
Cursor는 내가 20년 넘게 써온 서비스 중 유일하게, 고객 지원이 전혀 되지 않아 구독을 취소한 제품임
여러 주에 걸쳐 결제 관련 질문을 여러 번 메일로 보냈지만, 단 한 번도 답장을 받지 못함
단순 VS Code 관련 문의가 아니라 Cursor의 팀원 개입이 꼭 필요한 이슈였음
하지만 홍보 메일은 잘만 잘 옴
Cursor의 ‘가치’가 빨리 다른 서비스에도 확산되길 바람
다음 팀은 메일에 답장해주길 기대- 나 역시 비슷한 경험을 겪었고, 관련해서 이슈도 적어놓았음
-
이 프롬프트에는 빠진 내용이 많음
가장 두드러지는 건 tool call descriptors의 부재
1년 전 jailbreaking 프롬프트와 직접 비교해봐도 됨
그래도 cursor rules 등 다른 부분의 설정은 아이디어가 좋음
참고로, 관련 프롬프트 자료는 여기서 볼 수 있음-
Cursor에서는 사용자가 취하는 액션에 따라 다른 프롬프트를 사용함
지금은 샘플만 제공했는데, 근본적인 목표는 다양한 모델을 A/B 테스트하고 프롬프트와 모델을 최적화하는 것임
재현할 수 있도록 코드도 제공했고, 거기서 다른 프롬프트들도 참고할 수 있음
네가 공유한 Gist 자료도 꽤 유용함 -
혹시 어떤 최적화 로직이 있어서, 유저의 쿼리에서 꼭 필요한 도구 정보만 프롬프트에 포함시키는 것 아닐까 하는 생각이 듦
아마도 토큰 절약을 위해 불필요한 tool descriptor는 과감히 빼는 전략을 쓰고 있을 듯 -
관련 참고자료는 여기에 있음
-
-
그럼... wireshark는 이제 쓸 수 없는 것임?
-
기사 마지막에 어떻게 쓸지 결정하기 전에 훑어보는 첫 게시물일 뿐이라고 명시돼 있음
참고로, 요즘은 단순히 패킷을 보는 용도로 mitmproxy가 꽤 훌륭해짐 mitmproxy docs -
wireshark는 데스크탑 앱에서 Cursor 서버로 가는 요청(실질적으로 LLM에 보내는 요청)을 보는 데에는 쓸 수 있음
하지만 Cursor의 서버에서 LLM으로 실제 요청이 어떻게 가는지 보고 싶으면, 별도 설정이 필요
이런 설정이면 우리가 요청을 바꿔가며 A/B 테스트도 해볼 수 있음
-
-
Cursor 및 다양한 IDE 모달리티 솔루션은 흥미롭지만, 이들이 컨텍스트를 대충 다루는 습관을 기르게끔 만든다는 점이 아쉬움
Cursor 프롬프트에서 발췌한 문구를 보면,
"사용자가 메시지를 보낼 때마다 현재 상태, 세션 내 편집 히스토리, 린터 에러 등 추가 정보를 우리가 자동으로 붙일 수 있고, 이 정보는 코딩 작업에 연관될 수도 있고 안 될 수도 있음. 적절성은 니가 결정하라"는 식임
이런 ‘컨텍스트 블로트’는 LLM이 진짜 어려운 문제를 해결할 때 성능을 크게 제한함
예시로 든 .env 문제는 간단한 유형이라 Cursor가 잘 다루지만, 이 정도 복잡성으론 소프트웨어 엔지니어를 계속 고용할 수 없음
개인적으론 AI와 작업할 때 먼저 채팅 인터페이스에서 대화 맥락을 깔끔하게 관리하는 방법부터 고민하길 제안
복잡한 문제에서는 미팅, 슬랙 대화, 내부 문서, 외부 컨텐츠, 코드 등이 맥락에 얽혀 있기 때문
난 FileKitty(링크)와 최근엔 slackprep(링크) 같은 툴을 만들어서, 문제 해결과 관련 있는 정보만 추려내 더 의도적으로 쓸 수 있도록 함- 나도 이 부분에 동의하며, 내 에이전트 앱을 개발할 땐 맥락을 훨씬 신중하게 큐레이션해야 했음
"자동으로 첨부할 수 있다"가 아니라 실제 첨부한 것만 포함해 지시문 작성이 필요했음
"연관될 수도 있고 아닐 수도 있으니 네가 알아서 결정해라" 대신, 연관성이 있을 때와 없을 때 각각 어떻게 해야 할지 명확한 지시가 있어야 효과적임
맥락이 짧은 경우엔 별 문제 없지만, 길고 복잡한 이슈에선 이러한 세밀한 인스트럭션이 큰 차이를 만듦
아마 Cursor는 캐시된 토큰 가격의 장점을 위해 지시를 최대한 일반적으로 해두는 것 같음
아직 많은 부분이 실험 단계이고, 앞으로 프롬프트와 모델 개선이 많이 이뤄질 걸로 봄
- 나도 이 부분에 동의하며, 내 에이전트 앱을 개발할 땐 맥락을 훨씬 신중하게 큐레이션해야 했음
-
Cursor의 프롬프트에 대한 다른 분석은 여기서 볼 수 있음
-
긴 대화에서 관련 맥락을 선별하는 과정이 항상 궁금했음
실제로 그 로직을 리버스 엔지니어링해서 어떻게 변환 기록을 잘라내고, 파일의 최신 상태를 어떻게 표현하는지 알아낸 사람이 있는지 궁금함- 그 워크플로를 깊게 살펴보진 않았지만, 우리가 했던 작업을 GitHub에서 직접 재현할 수 있어서 거기서 힌트를 찾을 수 있음
앞으로도 이 부분을 계속 조사하며, TensorZero를 활용해 모델과 프롬프트 최적화 실험을 계속할 예정
- 그 워크플로를 깊게 살펴보진 않았지만, 우리가 했던 작업을 GitHub에서 직접 재현할 수 있어서 거기서 힌트를 찾을 수 있음
-
mitmproxy를 이용해서 같은 방식으로 분석 중임 관련 토론
-
이제 프롬프트 정보를 알게 되었으니 Cursor 서버를 재구현해서 완전 로컬(혹은 일종의 크랙된) 버전을 만드는 게 가능할지 궁금함
-
아니면 애초에 Cline, Roo Code 같은 오픈소스, 에이전트 코딩 특화 프로젝트가 있으니 그걸 쓰는 게 더 나음
-
프롬프트 나오기만을 기다려 이 시도를 했다는 건 좀 의외
-
Cursor의 apply 모델은 서버에서 돌아가는 구조로 보임
로컬 apply 모델을 직접 구현하는 게 얼마나 어려울지 궁금함
맥북에서 돌리면 훨씬 빠를 수도 있을 듯 -
확실히 가능함
-