47 puntos por GN⁺ 2025-03-24 | 4 comentarios | Compartir por WhatsApp
  • Entender el funcionamiento interno de herramientas de programación con IA como Cursor, Windsurf y Copilot permite aumentar la productividad y asegurar un rendimiento consistente en bases de código complejas
  • Mucha gente no entiende los límites de los IDE con IA y los trata como herramientas tradicionales, lo que termina causando problemas de rendimiento
  • Este artículo explica el funcionamiento interno de Cursor, su prompt de sistema y cómo optimizar la programación y las reglas de Cursor

De los LLM a los agentes de programación

Modelos de lenguaje grandes (LLM)

  • Los LLM funcionan básicamente prediciendo la siguiente palabra
  • Si se les da un prompt, el LLM genera una respuesta como autocompletado
    • Los primeros LLM basados en decoder (por ejemplo, GPT-2) requerían redactar prompts específicos para obtener el resultado deseado
    • La ingeniería de prompts es la técnica de “engañar” al modelo para inducir la respuesta que se quiere
  • Con la introducción del instruction tuning, mejoró la facilidad de uso
    • Instrucciones como “escribe un PR para refactorizar el método Foo” pueden ejecutarse directamente
    • En la práctica, sigue siendo una versión extendida del proceso de autocompletado
  • Se añadió el tool calling
    • El modelo puede realizar tareas como leer archivos, escribir archivos o ejecutar comandos
    • Ejemplo: read_file('index.py') → el cliente entrega el contenido del archivo → el modelo continúa la tarea

Programación basada en agentes

Los IDE con IA como Cursor están construidos usando una estructura compleja de wrappers:

  • Un fork de VSCode → comienza sobre una base open source
  • Se añade una UI de chat y se elige un LLM adecuado (por ejemplo, Sonnet 3.7)
  • Se implementan herramientas para el agente de programación
    • read_file(full_path: str)
    • write_file(full_path: str, content: str)
    • run_command(command: str)
  • Optimización de prompts
    • Se agregan instrucciones como “eres un programador experto” o “no adivines, usa herramientas”
      → Si solo se implementan estos pasos, en la práctica funciona, pero pueden aparecer problemas de errores de sintaxis, alucinaciones y falta de consistencia

Estrategias y consejos para optimizar la programación basada en agentes

  • Para crear un buen IDE con IA, hay que entender en qué tareas destacan los LLM y diseñar cuidadosamente los prompts y las herramientas en función de sus límites.
    • Simplificar la tarea principal y usar modelos más pequeños para subtareas es una estrategia efectiva
    • Distribuir tareas complejas puede mejorar el rendimiento y la consistencia
  • Agregar contexto del usuario (uso de @file)

    • Es muy probable que el usuario ya sepa cuáles son los archivos o el contexto adecuados
    • Se añade la sintaxis @file → incluye el contenido completo de archivos o carpetas para aportar contexto
    • Tip: se recomienda usar activamente @folder/@file → dar contexto claro mejora la velocidad y la precisión de la respuesta
  • Optimización de búsqueda de código

    • La búsqueda de código puede ser compleja, especialmente la búsqueda semántica (por ejemplo, “dónde está el código de autenticación”)
    • Se indexa la base de código en un Vectorstore → al buscar, el LLM filtra y reordena automáticamente
    • Tip: los comentarios y la documentación del código son importantes → mejoran el rendimiento del modelo de embeddings
      • Agregar al inicio del archivo una explicación de su propósito, significado y cuándo modificarlo
  • Optimización de escritura de archivos

    • Escribir código perfecto es difícil y costoso
    • En vez del archivo completo, se genera un Semantic Diff → solo se entregan los fragmentos modificados
    • A partir de ese diff semántico, un modelo de aplicación separado escribe el archivo real → corrige errores de sintaxis
    • Tip: no se pueden dar instrucciones por prompt directamente al modelo de aplicación → entregar el archivo completo mejora el control
    • Tip: el modelo de aplicación puede volverse lento y cometer errores al editar archivos grandes → conviene mantener el tamaño de archivo por debajo de 500 LoC
    • Tip: el feedback del linter es una señal muy importante → es esencial usar un linter potente
      • También se puede aprovechar el feedback de compilación y de lenguajes con tipos
    • Tip: usar nombres de archivo únicos → en vez de page.js, usar nombres concretos como foo-page.js, bar-page.js
      • Incluir la ruta completa del archivo en la documentación → elimina la ambigüedad de la herramienta de edición
  • Uso de modelos especializados para agentes

    • Se recomienda usar modelos especializados en agentes, no modelos generales de escritura de código
    • Esa es una de las razones por las que los modelos de Anthropic muestran un rendimiento sobresaliente en IDE como Cursor
    • Tip: no elegir simplemente un modelo que escriba código, sino uno optimizado para IDE basados en agentes
      • El rendimiento de los modelos puede revisarse en el leaderboard de WebDev Arena
  • Uso de herramientas de autocorrección (estrategia avanzada)

    • apply_and_check_tool → ejecuta un linter costoso y recopila logs de consola y capturas de pantalla en un navegador headless
    • MCP (Model Context Protocol) → refuerza la autonomía del agente y el suministro de contexto

Análisis detallado del prompt de sistema de Cursor

  • El prompt más reciente de Cursor (marzo de 2025) fue extraído mediante una técnica de inyección de prompts basada en MCP
    • Los prompt engineers de Cursor tienen una capacidad sobresaliente para redactar prompts, incluso comparados con otros IDE con IA.
    • Analizar la estructura del prompt permite mejorar tanto el rendimiento de generación de código como la capacidad para diseñar arquitecturas de agentes
  • Elementos principales del prompt y su significado

    • Uso de etiquetas como "<communication>", "<tool_calling>"
      • Se mezclan etiquetas Markdown y XML → facilita la lectura humana y el procesamiento por parte del LLM
    • "powered by Claude 3.5 Sonnet"
      • Refuerza la consistencia del modelo → evita que el LLM dé información incorrecta sobre el modelo en ejecución
    • "the world's best IDE"
      • Evita que el LLM recomiende otros productos cuando ocurre un error
    • "we may automatically attach some information…follow the USER's instructions…by the <user_query> tag."
      • En vez de pasar directamente el prompt del usuario, se incluye dentro de una etiqueta especial para evitar confusiones
    • "Refrain from apologizing"
      • Evita disculpas innecesarias (compensando una característica del modelo Sonnet)
    • "NEVER refer to tool names when speaking"
      • Se agrega la instrucción de no mencionar nombres de herramientas → pero en la práctica a veces el modelo la ignora
    • "Before calling each tool, first explain"
      • Explicar el estado antes de invocar una herramienta → mejora la experiencia del usuario
    • "partially satiate the USER's query, but you're not confident, gather more information"
      • Evita respuestas prematuras por exceso de confianza → induce a buscar más información
    • "NEVER output code to the USER"
      • Prohíbe mostrar código directamente → solo permite generarlo mediante herramientas
    • "If you're building a web app from scratch, give it a beautiful and modern UI"
      • Con un solo prompt se induce la creación de una web app atractiva y moderna (con fines de demo)
    • "you MUST read the the contents or section of what you're editing before editing it"
      • Obliga a leer el contexto antes de modificar código → refuerza la comprensión del contexto
    • "DO NOT loop more than 3 times on fixing linter errors"
      • Limita los ciclos de corrección → evita loops infinitos
    • "Address the root cause instead of the symptoms."
      • Induce a corregir la causa raíz del problema y no solo los síntomas
    • "DO NOT hardcode an API key"
      • Instrucción para reforzar la seguridad → evita el hardcoding
    • "codebase_search", "read_file", "grep_search", "file_search", "web_search"
      • Ofrece varias herramientas de búsqueda para asegurar el contexto correcto antes de escribir código
    • Exigencia de "One sentence explanation…why this command needs to be run…"
      • Refuerza la lógica al procesar argumentos de herramientas → se aplica una técnica de mejora de prompts
    • La herramienta "reapply" es "Calls a smarter model to apply the last edit"
      • Reaplica el último cambio con un modelo más avanzado → mejora la calidad de la edición
    • La herramienta "edit_file" dice "represent all unchanged code using the comment of the language you're editing"
      • Representa el código no modificado con comentarios → mejora la precisión del modelo de edición
  • Uso de prompt caching
    • El prompt de sistema y la descripción de herramientas se mantienen como estado estático
    • No hay personalización según la base de código o el usuario → el prompt caching puede mejorar costo y velocidad de procesamiento

Cómo escribir y usar eficazmente las reglas de Cursor

  • No existe una única respuesta correcta para escribir reglas de Cursor; depende del contexto, pero aquí se ofrecen varios consejos útiles basados en experiencia escribiendo prompts y entendiendo la estructura interna de Cursor
  • Es importante redactar las reglas no como órdenes simples, sino como guías de tipo enciclopédico.
  • Conceptos clave al escribir reglas

    • El LLM llama a fetch_rules(…) basándose en el nombre y la descripción de la lista de reglas
    • Las reglas no se agregan al prompt de sistema, sino que se consultan cuando hacen falta
    • Por eso, funciona mejor un estilo descriptivo tipo enciclopedia que uno imperativo
  • Qué evitar al escribir reglas

    • No definir identidad
      • Evitar descripciones como "eres un experto en TypeScript"
      • El LLM ya conoce su identidad mediante el prompt incorporado → hay riesgo de conflicto
    • No intentar sobrescribir el prompt de sistema
      • Instrucciones como "no agregues comentarios" o "haz preguntas antes de escribir código" → pueden generar confusión en el uso interno de herramientas
    • Evitar instrucciones negativas
      • En los LLM funcionan mejor órdenes positivas como “haz X” que negativas como “no hagas X”
      • Ejemplo de instrucción positiva: "al modificar un archivo, revisa primero todo el contexto"
  • Recomendaciones al escribir reglas

    • Usar nombres y descripciones de reglas claros e intuitivos
      • Debe ser posible aplicar la regla con información mínima sobre la base de código
      • Se pueden crear reglas redundantes → mejora la precisión de búsqueda
    • Escribir las reglas en estilo enciclopédico
      • Más que órdenes concretas, conviene describir situaciones y propósitos
      • Si hace falta, se pueden enlazar archivos de código para reforzar el contexto
    • Usar Cursor para redactar borradores de reglas
      • Los LLM son buenos escribiendo contexto para otros LLM
      • Ejemplo: "@folder/ genera un archivo Markdown sobre rutas de código que se modifican con frecuencia y sus definiciones"
    • Evitar escribir demasiadas reglas
      • Demasiadas reglas son ineficientes y pueden indicar una base de código poco intuitiva
      • En una base de código ideal, el agente debería poder trabajar con un mínimo de reglas
  • Ejemplos de reglas efectivas

    • ✅ Instrucciones de regla:
      • "lee todo el contexto antes de modificar un archivo"
      • "al modificar código del servidor, revisa la lógica de autenticación"
      • "si ocurre un error, corrige primero la causa"
    • ❌ Instrucciones de regla (a evitar):
      • "no borres comentarios"
      • "hazme preguntas antes de modificar"
      • "no modifiques código innecesario"
  • Estrategia central para escribir reglas

    • Las reglas deben redactarse no como órdenes, sino como descripciones de situaciones
    • Usar nombres y descripciones intuitivos → obtener el máximo rendimiento con el menor número de reglas
    • Reforzar descripciones situacionales y conexiones con el código más que instrucciones específicas

Conclusión

  • Resulta sorprendente que Cursor, que comenzó como un fork de VSCode y usa prompts basados en open source y APIs públicas de modelos, haya alcanzado una valuación cercana a 10 mil millones de dólares
    • Actualmente, Cursor está valuado en 6 veces bajo el criterio de wrapper multiple
  • Cursor ofrece un rendimiento potente gracias a prompts optimizados y a un sólido sistema de tool calling
  • Es poco probable que Cursor desarrolle su propio modelo de agente
    • En cambio, es más probable que Anthropic lance un producto competidor basado en Claude Code y Sonnet
  • Ideas clave

    • Configurar correctamente la base de código, la documentación y las reglas seguirá siendo una habilidad importante
    • Entender las estrategias de optimización de las herramientas de programación con IA puede mejorar la productividad y la precisión
    • Si Cursor no está funcionando bien, es muy probable que el problema sea la forma en que se está usando

"Si Cursor no funciona, hay que revisar de nuevo cómo se está usando."

4 comentarios

 
bluekai17 2025-03-26

Tendré que probarlo.

 
ohyecloudy 2025-03-25

Redactar borradores de reglas usando Cursor
Los LLM son buenos para escribir contexto para otros LLM

Qué interesante. ¿Será porque al final beben de la misma fuente?

 
linker 2025-03-25

Tiene mucha profundidad. Gracias.

 
nicewook 2025-03-25
  • Análisis detallado del prompt del sistema de Cursor: impresionante.
  • Ya me emociona la posibilidad de que Anthropic lance un AI IDE.