- Mit TensorZero als Open-Source-Proxy wurden der Traffic zwischen Cursor und LLM-Anbietern (z. B. OpenAI) abgefangen und analysiert sowie Prompts, Modelle und Inferenz-Ergebnisse in Echtzeit beobachtet und für Optimierungsexperimente genutzt
- Cursor erlaubt es bei LLM-Aufrufen, Base URL und Modellnamen zu überschreiben, sodass sich ein eigener Proxy (TensorZero) leicht integrieren lässt
- Intern ruft Cursor LLMs über eigene Server auf; für eine vollständige Proxy-Konfiguration sind daher Ngrok + Nginx-Reverse-Proxy sowie CORS-Header-Einstellungen erforderlich
- Über den Proxy lassen sich der tatsächliche System-Prompt, User-Prompts und sogar Inline-Codebearbeitungsanfragen, die Cursor an das LLM sendet, vollständig beobachten; außerdem sind Echtzeit-Umschaltungen und Experimente mit verschiedenen LLMs (A/B-Tests) möglich
- Die Analyse des System-Prompts von Cursor zeigt, dass das LLM den Großteil des Software-Engineering-Kontexts mit einem Prompt von nur etwa 642 Tokens versteht und verarbeitet. Codebearbeitung übernimmt ein separates „apply model“ (ein weniger intelligentes Hilfsmodell)
- Mit einer Proxy-Architektur wie TensorZero sind personalisierte LLM-Experimente pro Nutzer und feedbackbasierte Optimierung möglich; diese Struktur ist ideal für Qualitätsbewertung von Code-Assistenten (A/B-Tests), Prompt-Optimierung und Monitoring im realen Einsatz
Einführung
- Behandelt werden Erfahrungen damit, das Open-Source-Framework TensorZero als Proxy-Gateway zwischen Cursor und verschiedenen LLMs (Large Language Models) zu schalten, sowie die daraus gewonnenen Beobachtungen, Experimente und Optimierungsmöglichkeiten
- TensorZero ist Open Source und hilft dabei, die Qualität von LLM-Anwendungen mithilfe von Feedback-Signalen (Produktionsmetriken, Nutzerverhalten usw.) zu verbessern
- Als Cursor-Nutzer wurde diese Technik auf die meistgenutzte LLM-basierte IDE angewendet, um zu untersuchen, welche API-Anfragen tatsächlich ausgetauscht werden und wie sich Optimierungen direkt ausprobieren lassen
Gesamtüberblick und Ziel
- Cursor ist ein für die gesamte Nutzerschaft optimierter Coding-Assistent, doch individuelle Optimierungsexperimente und die Beobachtung von Daten sind kaum möglich
- Setzt man TensorZero als Proxy davor, lassen sich Cursors Anfragen und LLM-Antworten, Prompts, Modelle und der gesamte Inferenzprozess transparent beobachten, experimentell verändern und weiter optimieren
- Da die meisten Optimierungs-, Evaluierungs- und Experimentiermethoden echte Inferenzdaten voraussetzen, wird konkret gezeigt, wie sich diese in der Praxis sammeln und automatisiert verarbeiten lassen
Integrationsprozess: Aufbau eines LLM-Gateways
- Cursor unterstützt es, die OpenAI-Base-URL und den Modellnamen benutzerdefiniert zu ändern
- Da TensorZero einen OpenAI-kompatiblen Inferenz-Endpunkt bereitstellt, kann Cursor statt mit OpenAI direkt mit TensorZero verbunden werden
- Durch die Registrierung einer
cursorzero-Funktion in TensorZero werden Experimente mit verschiedenen Modellen/Prompts und die anbieterunabhängige automatisierte Speicherung von Inferenz- und Feedback-Daten möglich
Erstes Hindernis: Cursors eigene Server
- Cursor versuchte zwar, sich direkt mit lokalem TensorZero zu verbinden, scheiterte jedoch
- Cursor sendet Anfragen immer zuerst an seine eigenen Server und führt nach interner Verarbeitung erst danach den LLM-Aufruf aus
- Dadurch werden Anmeldedaten an die Cursor-Server übermittelt, und diese Server können Daten zu sämtlichen Anfragen und zur gesamten Codebasis erfassen
- Als Alternative wurde die Verbindung über OpenRouter getestet, um zu prüfen, ob sich in einigen Cursor-Interaktionen externe Modelle nutzen lassen
- Cursors Tab-Autovervollständigung läuft auf einem eigenen proprietären Modell und kann mit anderen LLMs kombiniert werden
- Letztlich wurde das Problem mithilfe eines Reverse Proxys und Ngrok gelöst, sodass Anfragen über einen öffentlich erreichbaren Endpunkt an das interne TensorZero weitergeleitet werden
- Nginx wurde davor geschaltet, um zusätzliche Authentifizierung und mehr Sicherheit zu bieten; außerdem wurde das LLM-Routing mit einer benutzerdefinierten TensorZero-Funktion abgeschlossen
- Endgültige Struktur:
- Cursor → Ngrok → Nginx (Authentifizierung) → TensorZero (lokal) → LLM-Provider
Zweites Hindernis: CORS
- Bei der Authentifizierung erreichten CORS-Preflight-(OPTIONS)-Anfragen Nginx, wodurch die anfängliche Authentifizierung ausblieb
- Nginx wurde so konfiguriert, dass es dieselben CORS-Header wie die OpenAI-API zurückgibt und damit die Anforderungen der Electron-basierten Cursor-IDE erfüllt
- Nach Lösung der Authentifizierungs- und CORS-Probleme liefen alle tatsächlichen Anfragen über die Cursor-Server
- (Beispielcode für die Nginx-Konfiguration enthalten)
Endergebnis: Einblick in Cursor wird möglich
- Sämtliche LLM-Anfragen/-Antworten, System-Prompts, User-Prompts sowie Inhalte angehängter Codes/Dateien lassen sich in Echtzeit beobachten
- Im Beispiel des System-Prompts ist sogar der Befehl zum Start eines separaten „apply model“ für Codebearbeitung festgelegt (eine zweistufige Modellarchitektur)
- Wichtige Struktur von Cursors Prompt:
- Bereitstellung von Kontext wie Nutzer-Session-Informationen, Dateien und Cursor-Position
- Kennzeichnung von Bereichen etwa durch Kommentarblöcke
- Bei Codeänderungsanfragen Anweisung, Codeblöcke zu erzeugen, in denen nur die geänderten Teile möglichst minimal enthalten sind
- Cursors Prompt Engineering
- Schon ein großer System-Prompt mit 642 Tokens automatisiert den Großteil typischer Software-Engineering-Aufgaben
- Ein weniger intelligentes, auf Codeänderungen spezialisiertes apply model (Hilfsmodell) existiert separat und gibt dem Haupt-LLM klar vor, worauf Änderungen angewendet werden und welche Regeln gelten
- Es wurde bestätigt, dass unterschiedliche LLM-Schichten (Intelligenz, funktionale Trennung) tatsächlich im Prompt selbst umgesetzt sind
Fazit und Implikationen
- Cursor kann den Kontext von Software Engineering allein mit dem eingebauten Wissen moderner LLMs und einem kompakten Prompt verarbeiten
- Mit Proxys wie TensorZero lässt sich leicht eine Struktur für nutzerspezifisches Feedback und datenbasierte Optimierung im realen Einsatz aufbauen (A/B-Tests, Prompt-/Modell-Tuning)
- Unternehmen mit KI-Codeeditor-Hilfen oder LLM-Einsatz können mit diesem Ansatz Prompt-Design, Leistungsverbesserungen und nutzerspezifische Optimierung schnell erproben
- Im nächsten Beitrag sind Folgeexperimente zu Methoden der Datenerfassung im realen Einsatz, Tree-sitter und der Nutzung von Git Hooks geplant
1 Kommentare
Hacker-News-Kommentare
Cursor ist das einzige Produkt unter den Diensten, die ich seit über 20 Jahren nutze, bei dem ich das Abonnement wegen komplett fehlendem Kundensupport gekündigt habe
Über mehrere Wochen hinweg habe ich mehrfach E-Mails zu einer Abrechnungsfrage geschickt, aber kein einziges Mal eine Antwort erhalten
Es ging nicht um eine einfache VS-Code-Frage, sondern um ein Problem, das zwingend Eingreifen durch das Cursor-Team erforderte
Werbe-Mails kamen dagegen problemlos an
Ich hoffe, dass sich der „Wert“ von Cursor schnell auch auf andere Dienste ausbreitet
Vom nächsten Team erwarte ich, dass es auf E-Mails antwortet
In diesem Prompt fehlt eine Menge
Am auffälligsten ist das Fehlen der Tool-Call-Descriptors
Man kann ihn direkt mit dem Jailbreaking-Prompt von vor einem Jahr vergleichen
Trotzdem sind andere Konfigurationsteile wie etwa Cursor Rules eine gute Idee
Zur Referenz gibt es verwandtes Prompt-Material hier
In Cursor werden je nach Aktion des Nutzers unterschiedliche Prompts verwendet
Im Moment wurde nur ein Beispiel bereitgestellt, aber das grundlegende Ziel ist, verschiedene Modelle per A/B-Test zu vergleichen und Prompts sowie Modelle zu optimieren
Damit es reproduzierbar ist, habe ich auch den Code bereitgestellt, und dort kann man sich weitere Prompts ansehen
Das von dir geteilte Gist-Material ist ebenfalls ziemlich nützlich
Ich frage mich, ob es vielleicht eine Art Optimierungslogik gibt, die nur die für die Nutzeranfrage wirklich nötigen Tool-Informationen in den Prompt aufnimmt
Vermutlich wird zum Tokensparen aggressiv auf unnötige Tool-Descriptors verzichtet
Relevantes Referenzmaterial gibt es hier
Heißt das also ... Wireshark kann man jetzt nicht mehr verwenden?
Im letzten Beitrag des Artikels steht ausdrücklich, dass dies nur ein erster Post zum Sichten ist, bevor entschieden wird, wie man es nutzen will
Nebenbei: Heutzutage ist
mitmproxyauch zum einfachen Mitschneiden von Paketen ziemlich gut geworden mitmproxy docsWireshark kann verwendet werden, um die Anfragen der Desktop-App an die Cursor-Server zu sehen, also effektiv die Anfragen, die an das LLM gesendet werden
Wenn man aber sehen will, wie die eigentliche Anfrage von den Cursor-Servern zum LLM weitergeleitet wird, braucht man zusätzliche Konfiguration
Mit so einer Konfiguration könnten wir die Anfragen auch verändern und A/B-Tests durchführen
Cursor und verschiedene IDE-Modality-Lösungen sind interessant, aber schade ist, dass sie die Gewohnheit fördern, mit Kontext schlampig umzugehen
Ein Auszug aus dem Cursor-Prompt lautet sinngemäß:
„Jedes Mal, wenn der Nutzer eine Nachricht sendet, können wir automatisch zusätzliche Informationen anhängen, etwa den aktuellen Zustand, die Bearbeitungshistorie innerhalb der Sitzung, Linter-Fehler usw.; diese Informationen können für die Programmieraufgabe relevant sein oder auch nicht. Über die Relevanz entscheidest du.“
Dieser „Context Bloat“ begrenzt die Leistung von LLMs stark, wenn sie wirklich schwierige Probleme lösen sollen
Das als Beispiel genannte
.env-Problem ist ein einfacher Typ von Problem, den Cursor gut behandelt, aber mit dieser Komplexitätsstufe kann man nicht dauerhaft auf Softwareingenieure verzichtenIch würde persönlich empfehlen, bei der Arbeit mit KI zuerst darüber nachzudenken, wie man den Gesprächskontext in einer Chat-Oberfläche sauber verwaltet
Bei komplexen Problemen sind Besprechungen, Slack-Gespräche, interne Dokumente, externe Inhalte und Code alle Teil des Kontexts
Ich habe Tools wie FileKitty(Link) und in letzter Zeit slackprep(Link) gebaut, damit man nur die für die Problemlösung relevanten Informationen herausziehen und gezielter verwenden kann
Die Instruktionen mussten nur das enthalten, was tatsächlich angehängt wurde, nicht „kann automatisch angehängt werden“
Statt „es könnte relevant sein oder auch nicht, entscheide du“ braucht man klare Anweisungen dafür, was bei vorhandener und bei fehlender Relevanz zu tun ist
Bei kurzem Kontext ist das kein großes Problem, aber bei langen und komplexen Themen machen solche feinen Instruktionen einen großen Unterschied
Vermutlich hält Cursor die Instruktionen so allgemein wie möglich, um die Vorteile gecachter Token-Preise mitzunehmen
Vieles ist noch experimentell, und ich denke, dass Prompts und Modelle künftig noch deutlich verbessert werden
Eine weitere Analyse des Cursor-Prompts gibt es hier
Mich hat schon immer interessiert, wie in langen Gesprächen der relevante Kontext ausgewählt wird
Ich frage mich, ob jemand diese Logik tatsächlich per Reverse Engineering untersucht und herausgefunden hat, wie Änderungsverläufe abgeschnitten und wie die neuesten Dateistände dargestellt werden
Ich werde das weiterhin untersuchen und mit TensorZero weiter Experimente zur Optimierung von Modellen und Prompts durchführen
Ich analysiere es auf dieselbe Weise mit
mitmproxyrelevante DiskussionJetzt, da die Prompt-Informationen bekannt sind, frage ich mich, ob es möglich wäre, den Cursor-Server nachzubauen und eine vollständig lokale Version zu erstellen, oder eine Art gecrackte Version
Oder man nutzt gleich Open-Source-, auf agentisches Coding spezialisierte Projekte wie Cline oder Roo Code
Dass jemand auf die Veröffentlichung des Prompts gewartet hat, um genau diesen Versuch zu unternehmen, ist schon etwas überraschend
Das Apply-Modell von Cursor scheint serverseitig zu laufen
Ich frage mich, wie schwierig es wäre, selbst ein lokales Apply-Modell zu implementieren
Auf einem MacBook könnte es sogar deutlich schneller laufen
Definitiv möglich