- Usando TensorZero como proxy open source, se comparte la experiencia de interceptar y analizar el tráfico entre Cursor y los proveedores de LLM (como OpenAI), y de observar en tiempo real prompts, modelos y resultados de inferencia, además de hacer experimentos de optimización
- Cursor permite sobrescribir la Base URL y el nombre del modelo al hacer llamadas al LLM, por lo que es fácil integrar un proxy propio como TensorZero
- Internamente, Cursor invoca al LLM pasando primero por sus propios servidores, así que para una configuración de proxy completa se necesita Ngrok + un reverse proxy con Nginx y configurar encabezados CORS
- A través del proxy, se puede observar todo lo que Cursor realmente envía al LLM: system prompts, user prompts e incluso solicitudes de edición de código inline, y también cambiar/hacer pruebas en tiempo real con distintos LLM (A/B testing)
- Del análisis del system prompt de Cursor se desprende que, con un prompt de apenas unos 642 tokens, el LLM entiende y procesa la mayor parte del contexto de ingeniería de software. La edición de código la maneja un "apply model" aparte, un modelo auxiliar menos inteligente
- Con una arquitectura de proxy como TensorZero, es posible hacer experimentos de LLM personalizados por usuario y optimización basada en feedback, y esta estructura es ideal para evaluar calidad en herramientas de asistencia de código (A/B testing), optimizar prompts y monitorear uso real
Introducción
- Se aborda la experiencia de conectar el framework open source TensorZero como gateway proxy entre Cursor y varios LLM (modelos de lenguaje grandes), así como las observaciones, experimentos y puntos de optimización que esto habilita
- TensorZero es un proyecto open source que ayuda a mejorar la calidad de aplicaciones con LLM usando señales de feedback (métricas de producción, comportamiento de usuarios, etc.)
- Como usuario de Cursor, se aplicó esta tecnología al IDE basado en LLM que más se usa, para experimentar qué solicitudes API circulan realmente y cómo intentar optimizaciones de forma directa
Panorama general y objetivo
- Cursor es un asistente de programación optimizado para el conjunto total de usuarios, pero es casi imposible hacer experimentos de optimización personalizados por persona y observar los datos
- Si se coloca TensorZero como proxy, es posible observar de forma transparente todo el proceso de solicitudes de Cursor, respuestas del LLM, prompts, modelos e inferencia, además de experimentar y extenderlo hacia optimización
- Como la mayoría de los métodos de optimización, evaluación y experimentación requieren datos reales de inferencia, se presenta de forma concreta una manera práctica de recolectarlos y automatizarlos
Proceso de integración: construcción del gateway LLM
- Cursor permite cambiar de forma personalizada la OpenAI base URL y el nombre del modelo
- Como TensorZero ofrece un endpoint de inferencia compatible con OpenAI, es posible conectar Cursor a TensorZero en lugar de OpenAI
- Registrando la función
cursorzero dentro de TensorZero, se vuelve posible automatizar el almacenamiento de datos de inferencia y feedback sin depender de un proveedor específico, además de hacer experimentos con distintos modelos/prompts
Primer obstáculo: el propio servidor de Cursor
- Se intentó conectar Cursor directamente a TensorZero local, pero falló
- Cursor siempre envía primero las solicitudes a sus propios servidores y, tras procesamiento interno adicional, continúa con la llamada al LLM
- Por esto, las credenciales se transfieren a los servidores de Cursor, y dichos servidores pueden recolectar datos de todas las solicitudes y del codebase completo
- Como alternativa, se conectó con OpenRouter para comprobar si ciertas interacciones dentro de Cursor podían usar modelos externos
- El autocompletado con Tab de Cursor funciona con su propio modelo privado, y puede combinarse con otros LLM
- Finalmente, el problema se resolvió usando reverse proxy y Ngrok, con una estructura que hace proxy de solicitudes hacia TensorZero interno a través de un endpoint público externo
- Se colocó Nginx al frente para añadir autenticación y reforzar seguridad, y se completó también el enrutamiento LLM con una función personalizada de TensorZero
- Estructura final:
- Cursor → Ngrok → Nginx (autenticación) → TensorZero (local) → proveedor de LLM
Segundo obstáculo: CORS
- Durante la autenticación, una solicitud CORS preflight (OPTIONS) llegaba a Nginx, provocando que inicialmente no se realizara la autenticación
- Se configuró Nginx para devolver los mismos encabezados CORS que la API de OpenAI, satisfaciendo así los requisitos del IDE Cursor basado en Electron
- Tras resolver los problemas de autenticación y CORS, todas las solicitudes reales siguieron pasando por los servidores de Cursor
- (Se incluye código de ejemplo de configuración de Nginx)
Resultado final: ya es posible ver dentro de Cursor
- Se pueden observar en tiempo real todas las solicitudes/respuestas al LLM, system prompts, user prompts y contenidos de código/archivos adjuntos
- En el ejemplo del system prompt, incluso se especifica el comando para ejecutar un "apply model" separado para edición de código (estructura de doble capa de modelos)
- Estructura principal del prompt de Cursor:
- Proporciona contexto como información de sesión del usuario, archivos y posición del cursor
- Delimita secciones con bloques de comentarios y similares
- Al pedir modificaciones de código, instruye generar bloques de código con solo los cambios necesarios y mínimos
- La ingeniería de prompts de Cursor
- Con un único system prompt amplio de 642 tokens, ya se automatiza la gran mayoría de tareas de ingeniería de software
- Existe por separado un apply model menos inteligente, especializado en tareas de modificación de código, al que el LLM principal le especifica claramente el objetivo de aplicación y las reglas
- Se confirma que dentro del prompt real ya está implementada una arquitectura por capas de distintos LLM (separación por inteligencia y función)
Conclusión e implicaciones
- Cursor puede manejar contexto de ingeniería de software con el conocimiento base incorporado de los LLM modernos y prompts concisos
- Con proxies como TensorZero, se puede construir fácilmente una estructura de optimización basada en feedback y datos reales de uso por usuario (A/B testing, ajuste de prompts/modelos)
- Las empresas que incorporan LLM o IA de asistencia para editores de código pueden usar este método para experimentar rápidamente con diseño de prompts, mejora de rendimiento y optimización por usuario
- En el siguiente artículo se planean experimentos posteriores sobre métodos de recolección de datos de uso real, Tree-sitter y uso de git hook
1 comentarios
Comentarios en Hacker News
Cursor es el único producto, entre todos los servicios que he usado por más de 20 años, cuya suscripción cancelé porque no ofrece absolutamente ningún soporte al cliente
Durante varias semanas envié varios correos con preguntas sobre pagos, pero no recibí ni una sola respuesta
No era una simple consulta relacionada con VS Code, sino un problema que necesariamente requería la intervención del equipo de Cursor
Pero eso sí, los correos promocionales sí llegaban muy bien
Ojalá el ‘valor’ de Cursor se propague rápido a otros servicios
Espero que el próximo equipo sí responda los correos
A este prompt le faltan muchas cosas
Lo más evidente es la ausencia de los descriptores de llamadas a herramientas
Incluso se puede comparar directamente con prompts de jailbreaking de hace un año
Aun así, otras configuraciones como las cursor rules tienen buenas ideas
Como referencia, se pueden ver materiales de prompts relacionados aquí
En Cursor usan prompts distintos según la acción que realiza el usuario
Por ahora solo compartí una muestra, pero el objetivo de fondo es hacer pruebas A/B con distintos modelos y optimizar tanto los prompts como los modelos
También compartí el código para que se pueda reproducir, y ahí mismo se pueden consultar otros prompts
El material del Gist que compartiste también es bastante útil
Me pregunto si no habrá alguna lógica de optimización que haga que solo se incluyan en el prompt los datos de herramientas realmente necesarios para la consulta del usuario
Probablemente estén usando una estrategia de eliminar sin problemas los tool descriptors innecesarios para ahorrar tokens
Hay material de referencia relacionado aquí
Entonces... ¿ya no se puede usar wireshark?
Al final del artículo se aclara que esto es solo una primera publicación para revisar antes de decidir cómo usarlo
Como referencia, hoy en día mitmproxy se ha vuelto bastante bueno para simplemente ver paquetes mitmproxy docs
wireshark sí se puede usar para ver las solicitudes que van desde la app de escritorio hacia el servidor de Cursor, es decir, las solicitudes que en la práctica se envían al LLM
Pero si quieres ver cómo van realmente las solicitudes desde el servidor de Cursor hacia el LLM, hace falta una configuración aparte
Con una configuración así también podríamos hacer pruebas A/B cambiando las solicitudes
Cursor y varias soluciones de modalidad para IDE son interesantes, pero es una lástima que fomenten la costumbre de tratar el contexto de manera descuidada
Si ves una frase extraída del prompt de Cursor, dice algo como:
"Cada vez que el usuario envía un mensaje, podemos adjuntar automáticamente información adicional como el estado actual, el historial de ediciones dentro de la sesión, errores del linter, etc., y esa información puede o no estar relacionada con la tarea de programación. Tú decide su pertinencia"
Este ‘context bloat’ limita mucho el rendimiento del LLM cuando intenta resolver problemas realmente difíciles
El problema de
.envusado como ejemplo es de un tipo simple, así que Cursor lo maneja bien, pero con ese nivel de complejidad no puedes seguir contratando ingenieros de softwarePersonalmente, cuando trabajo con IA, sugeriría primero pensar en cómo mantener limpio el contexto de la conversación en la interfaz de chat
En problemas complejos, el contexto se entrelaza con reuniones, conversaciones de Slack, documentos internos, contenido externo y código
Yo hice herramientas como FileKitty(enlace) y más recientemente slackprep(enlace) para filtrar solo la información relacionada con la resolución del problema y usarla de forma más intencional
No bastaba con decir "se puede adjuntar automáticamente", sino que había que redactar las instrucciones incluyendo solo lo que realmente se adjuntó
En vez de decir "puede o no estar relacionado, así que decide por tu cuenta", funciona mejor dar instrucciones claras sobre qué hacer cuando sí es relevante y cuando no lo es
Cuando el contexto es corto no suele haber problema, pero en asuntos largos y complejos este tipo de instrucciones detalladas marca una gran diferencia
Probablemente Cursor está dejando las instrucciones lo más generales posible para aprovechar las ventajas del precio de los tokens en caché
Todavía muchas cosas están en fase experimental, y creo que en adelante habrá muchas mejoras tanto en prompts como en modelos
Se puede ver otro análisis del prompt de Cursor aquí
Siempre me ha dado curiosidad el proceso de seleccionar contexto relevante en conversaciones largas
Me pregunto si alguien ya hizo ingeniería inversa de esa lógica para averiguar cómo recortan el historial de transformaciones y cómo representan el estado más reciente de los archivos
Voy a seguir investigando esa parte y también seguiré haciendo experimentos de optimización de modelos y prompts usando TensorZero
También lo estoy analizando de la misma manera con mitmproxy discusión relacionada
Ahora que ya se conoce la información del prompt, me pregunto si sería posible reimplementar el servidor de Cursor para hacer una versión completamente local (o una especie de versión crackeada)
O mejor aún, desde el inicio ya existen proyectos open source especializados en agentic coding como Cline o Roo Code, así que sería mejor usar eso
Me sorprende un poco que alguien haya intentado esto solo esperando a que salieran los prompts
El modelo apply de Cursor parece estar corriendo en el servidor
Me pregunto qué tan difícil sería implementar directamente un modelo apply local
Incluso podría ser mucho más rápido si corriera en una MacBook
Definitivamente es posible