9 pontos por GN⁺ 2025-06-10 | 1 comentários | Compartilhar no WhatsApp
  • Usando o TensorZero como proxy open source, foi compartilhada a experiência de interceptar e analisar o tráfego entre o Cursor e provedores de LLM (como OpenAI), observando prompts, modelos e resultados de inferência em tempo real e testando otimizações
  • O Cursor permite sobrescrever a Base URL e o nome do modelo nas chamadas ao LLM, o que facilita integrar um proxy próprio, como o TensorZero
  • Internamente, o Cursor chama os LLMs passando por seus próprios servidores, então, para uma configuração de proxy completa, são necessários Ngrok + proxy reverso com Nginx e configuração de cabeçalhos CORS
  • Pelo proxy, é possível observar o system prompt, o user prompt e até pedidos de edição inline de código que o Cursor realmente envia ao LLM, além de alternar/testar diferentes LLMs em tempo real (teste A/B)
  • A análise do system prompt do Cursor mostrou que, com apenas cerca de 642 tokens de prompt, o LLM já consegue entender e processar a maior parte do contexto de engenharia de software. As edições de código ficam a cargo de um "apply model" separado, um modelo auxiliar menos inteligente
  • Com uma arquitetura de proxy como a do TensorZero, é possível fazer experimentos de LLM personalizados por usuário e otimização com base em feedback, sendo ideal para avaliação de qualidade de ferramentas de assistência a código (teste A/B), otimização de prompts e monitoramento em uso real

Introdução

  • Aborda a experiência de conectar o framework open source TensorZero como um gateway proxy entre o Cursor e vários LLMs (grandes modelos de linguagem), além das observações, experimentos e pontos de otimização obtidos com isso
  • O TensorZero é um projeto open source que ajuda a melhorar a qualidade de aplicações com LLM usando sinais de feedback (métricas de produção, comportamento do usuário etc.)
  • Como usuário do Cursor, foi aplicado esse recurso ao IDE com LLM mais usado pelo autor para testar quais requisições de API realmente circulam e como tentar otimizações diretamente

Visão geral e objetivo

  • O Cursor é um assistente de programação otimizado para a base total de usuários, mas quase não permite experimentos de otimização personalizados por indivíduo nem observação dos dados
  • Ao colocar o TensorZero como proxy, passa a ser possível observar com transparência todo o processo de requisições do Cursor, respostas do LLM, prompts, modelos e inferência, além de expandir isso para experimentação e otimização
  • Como a maioria dos métodos de otimização, avaliação e experimentação exige dados reais de inferência, o texto mostra em detalhe formas práticas e automatizadas de coletá-los

Processo de integração: construindo um gateway de LLM

  • O Cursor permite personalizar a OpenAI base URL e o nome do modelo
  • Como o TensorZero oferece um endpoint de inferência compatível com OpenAI, é possível conectar o Cursor ao TensorZero no lugar da OpenAI
  • Registrando a função cursorzero no TensorZero, torna-se possível automatizar o armazenamento de dados de inferência e feedback, sem dependência de provedor, além de experimentar diferentes modelos e prompts

Primeiro obstáculo: o próprio servidor do Cursor

  • O Cursor tentou se conectar diretamente ao TensorZero local, mas falhou
  • O Cursor sempre envia primeiro as requisições aos seus próprios servidores e, depois de processamento interno adicional, continua a chamada ao LLM
    • Com isso, as credenciais são enviadas ao servidor do Cursor, e esse servidor passa a conseguir coletar dados sobre todas as requisições e sobre a codebase
  • Como alternativa, foi feita conexão com o OpenRouter para verificar, em algumas interações do Cursor, se era possível usar modelos externos
  • O autocompletar com Tab do Cursor funciona com um modelo proprietário próprio e pode ser combinado com outros LLMs
  • No fim, a solução veio com proxy reverso e Ngrok, criando uma estrutura que encaminha, por meio de um endpoint público externo, as requisições para o TensorZero interno
  • O Nginx foi colocado na frente para adicionar autenticação, reforçar a segurança e concluir também o roteamento para LLMs por meio de uma função customizada no TensorZero
  • Estrutura final:
    • Cursor → Ngrok → Nginx (autenticação) → TensorZero (local) → provedor de LLM

Segundo obstáculo: CORS

  • Durante a autenticação, a requisição de CORS preflight (OPTIONS) chegava ao Nginx, causando inicialmente falha na autenticação
  • O Nginx foi configurado para retornar os mesmos cabeçalhos CORS da API da OpenAI, atendendo aos requisitos do Cursor IDE, baseado em Electron
  • Depois de resolver autenticação e CORS, todas as requisições reais passaram a ocorrer via servidores do Cursor
  • (Inclui código de exemplo de configuração do Nginx)

Resultado final: ficou possível inspecionar o Cursor

  • É possível observar em tempo real todas as requisições/respostas ao LLM, system prompt, user prompt e conteúdo de código/arquivos anexados
  • O exemplo de system prompt mostra explicitamente até os comandos que acionam um "apply model" separado para edição de código, revelando uma estrutura em camadas com dois modelos
  • Estrutura principal do prompt do Cursor:
    • informações da sessão do usuário e contexto como arquivos e posição do cursor
    • marcação de seções por blocos de comentário e afins
    • em pedidos de modificação de código, instruções para gerar blocos com apenas as mudanças mínimas necessárias
  • Engenharia de prompts do Cursor
    • um único system prompt grande, com 642 tokens, já automatiza a maior parte das tarefas de engenharia de software
  • Existe separadamente um apply model menos inteligente, especializado em mudanças de código, e o LLM principal recebe instruções claras sobre alvo de aplicação e regras
    • Foi confirmado que diferentes camadas de LLM (inteligência e funções separadas) estão implementadas dentro do prompt real

Conclusão e implicações

  • O Cursor consegue lidar com contexto de engenharia de software apenas com o conhecimento embutido dos LLMs mais recentes e prompts concisos
  • Com proxies como o TensorZero, fica fácil montar uma estrutura de otimização baseada em feedback por usuário e dados reais de uso, incluindo teste A/B e ajuste de prompts/modelos
  • Empresas que adotam LLMs e AIs de apoio em editores de código podem usar essa abordagem para testar rapidamente design de prompts, melhoria de desempenho e otimização por usuário
  • No próximo texto, o autor pretende continuar os experimentos com formas de coleta de dados de uso real, Tree-sitter e git hook

1 comentários

 
GN⁺ 2025-06-10
Comentários do Hacker News
  • Cursor é o único serviço que usei em mais de 20 anos em que cancelei a assinatura por não haver absolutamente nenhum suporte ao cliente
    Durante várias semanas, enviei vários e-mails com perguntas sobre cobrança, mas nunca recebi uma única resposta
    Não era uma dúvida simples relacionada ao VS Code, era um problema que exigia necessariamente a intervenção da equipe da Cursor
    Mas os e-mails de marketing continuavam chegando direitinho
    Espero que o “valor” da Cursor se espalhe logo para outros serviços
    Espero que a próxima equipe responda aos e-mails

    • Eu também tive uma experiência parecida e até registrei uma issue sobre isso
  • Falta bastante coisa nesse prompt
    O mais evidente é a ausência dos tool call descriptors
    Dá até para comparar diretamente com prompts de jailbreaking de um ano atrás
    Ainda assim, outras partes da configuração, como as cursor rules, têm boas ideias
    Aliás, materiais de prompt relacionados podem ser vistos aqui

    • No Cursor, prompts diferentes são usados dependendo da ação que o usuário executa
      Por enquanto, só fornecemos amostras, mas o objetivo fundamental é fazer testes A/B com vários modelos e otimizar os prompts e os modelos
      Também forneci o código para permitir reprodução, e lá você pode consultar outros prompts
      O material em Gist que você compartilhou também é bem útil

    • Fico pensando se não existe alguma lógica de otimização que inclua no prompt apenas as informações de ferramentas realmente necessárias a partir da consulta do usuário
      Provavelmente eles adotam uma estratégia de cortar sem dó os tool descriptors desnecessários para economizar tokens

    • Há material de referência relacionado aqui

  • Então... o wireshark não pode mais ser usado?

    • No final do artigo está explícito que isso é apenas um primeiro post, uma passada de olhos antes de decidir como usar
      E, como referência, hoje em dia o mitmproxy ficou muito bom para simplesmente inspecionar pacotes mitmproxy docs

    • O wireshark pode ser usado para ver as requisições do app desktop para os servidores da Cursor (ou seja, as requisições efetivamente enviadas ao LLM)
      Mas, se você quiser ver como a requisição real vai dos servidores da Cursor para o LLM, é preciso uma configuração separada
      Com esse tipo de configuração, também daria para fazer testes A/B alterando as requisições

  • O Cursor e várias soluções de modalidade de IDE são interessantes, mas é uma pena que acabem criando o hábito de tratar contexto de forma meio descuidada
    Pelo trecho citado do prompt do Cursor,
    "Sempre que o usuário envia uma mensagem, podemos anexar automaticamente informações adicionais como o estado atual, o histórico de edições na sessão, erros de linter etc., e essas informações podem ou não estar relacionadas à tarefa de programação. Você decide a relevância"
    Esse tipo de “inchaço de contexto” limita bastante o desempenho do LLM quando ele tenta resolver problemas realmente difíceis
    O problema de .env dado como exemplo é de um tipo simples, então o Cursor lida bem com isso, mas esse nível de complexidade não é suficiente para continuar empregando engenheiros de software
    Pessoalmente, quando se trabalha com IA, eu sugeriria primeiro pensar em como gerenciar de forma limpa o contexto da conversa em uma interface de chat
    Em problemas complexos, o contexto fica espalhado entre reuniões, conversas no Slack, documentação interna, conteúdo externo, código etc.
    Eu criei ferramentas como FileKitty(link) e, mais recentemente, slackprep(link) para selecionar apenas as informações relevantes para a resolução do problema e usá-las de forma mais intencional

    • Também concordo com isso e, quando desenvolvi meu app de agentes, precisei fazer uma curadoria muito mais cuidadosa do contexto
      Não bastava dizer "podemos anexar automaticamente"; foi preciso escrever instruções incluindo apenas o que realmente foi anexado
      Em vez de "isso pode ou não ser relevante, então decida você mesmo", é mais eficaz haver instruções claras sobre o que fazer quando for relevante e quando não for
      Quando o contexto é curto, isso não costuma ser um problema, mas em questões longas e complexas esse tipo de instrução detalhada faz uma grande diferença
      Imagino que a Cursor esteja deixando as instruções o mais genéricas possível para aproveitar a vantagem de preço dos tokens em cache
      Muita coisa ainda está em fase experimental, e acho que ainda veremos muitas melhorias em prompts e modelos
  • Outra análise dos prompts do Cursor pode ser vista aqui

  • Sempre tive curiosidade sobre o processo de selecionar contexto relevante em conversas longas
    Fico me perguntando se alguém realmente fez engenharia reversa dessa lógica para descobrir como o histórico de mudanças é recortado e como o estado mais recente dos arquivos é representado

    • Não examinei esse fluxo de trabalho a fundo, mas dá para reproduzir diretamente no GitHub o trabalho que fizemos, então talvez seja possível encontrar pistas lá
      Vou continuar investigando essa parte e seguir fazendo experimentos de otimização de modelos e prompts com o TensorZero
  • Estou analisando da mesma forma usando mitmproxy discussão relacionada

  • Agora que as informações do prompt foram reveladas, fico pensando se seria possível reimplementar o servidor da Cursor e fazer uma versão totalmente local (ou meio crackeada)

    • Ou então seria melhor simplesmente usar projetos open source focados em agentic coding, como Cline e Roo Code

    • É meio surpreendente que alguém tenha esperado apenas o vazamento dos prompts para tentar isso

    • O modelo apply da Cursor parece rodar no servidor
      Fico curioso sobre o quão difícil seria implementar diretamente um modelo apply local
      Rodando num MacBook, talvez até fosse bem mais rápido

    • Com certeza é possível