API Responses ganha 40% mais velocidade com WebSockets
Quando você pede ao Codex para consertar um bug, ele vasculha seu código em busca de arquivos relevantes, lê o conteúdo para criar contexto, faz as alterações necessárias e executa testes para verificar se o problema foi resolvido. Por trás das cenas, esse processo envolve dezenas de solicitações à API Responses: determinar a próxima ação do modelo, executar uma ferramenta no seu computador, enviar o resultado de volta para a API e repetir o ciclo. Todas essas solicitações podem somar minutos de espera para os usuários concluírem tarefas complexas. Do ponto de vista de latência, o loop do agente Codex passa a maior parte do tempo em três etapas principais: processamento nos serviços da API (para validar e tratar as requisições), inferência do modelo e tempo no lado do cliente (executando ferramentas e construindo contexto para o modelo). A inferência é a fase em que o modelo roda em GPUs para gerar novos tokens. Antigamente, executar a inferência de modelos de linguagem grande (LLMs) nessas placas era a parte mais lenta do ciclo, então o overhead da API passava despercebido. Com a aceleração da inferência, os custos cumulativos de rede e processamento do fluxo de trabalho do agente ficaram cada vez mais evidentes.
Neste artigo, explicamos como reduzimos em 40% o tempo total dos loops de agentes usando a API, permitindo que os usuários percebam o salto de velocidade da inferência de 65 para quase 1.000 tokens por segundo. Conseguimos esse avanço com uma combinação de cache inteligente, eliminação de saltos desnecessários na rede, aprimoramento da pilha de segurança para detectar problemas rapidamente e — o mais importante — a implementação de uma conexão persistente com a API Responses, substituindo a série de chamadas síncronas por um único fluxo contínuo de dados. Antes, modelos como o GPT-5 e GPT-5.2 alcançavam cerca de 65 tokens por segundo (TPS) na API Responses. Com o lançamento do GPT-5.3-Codex-Spark, um modelo otimizado para programação, nosso objetivo era aumentar essa velocidade em uma ordem de magnitude: mais de 1.000 TPS, graças a hardware especializado da Cerebras voltado para inferência de LLMs. No entanto, para que os usuários realmente aproveitassem essa velocidade toda, era fundamental reduzir o overhead da API.
Em novembro de 2025, lançamos uma maratona de otimizações na API Responses, implementando melhorias críticas para reduzir a latência no caminho principal de uma única solicitação. Conseguimos uma melhora de quase 45% no tempo para o primeiro token (TTFT), que mede quão responsiva a API se sente. Mesmo assim, essas mudanças ainda não eram suficientes para o GPT-5.3-Codex-Spark. O overhead da API Responses continuava grande demais em comparação com a velocidade do modelo: os usuários tinham que esperar pelo processamento nos CPUs da API antes de poderem usufruir dos GPUs que executavam o modelo. O problema era mais profundo e estrutural: tratávamos cada solicitação do Codex como independente, processando todo o histórico da conversa e outros contextos reutilizáveis a cada nova requisição. Mesmo quando grande parte da conversa não havia mudado, ainda gastávamos recursos refazendo trabalho repetido. Com conversas mais longas, esse processamento redundante se tornava cada vez mais caro.
A solução veio de uma reestruturação radical no protocolo de transporte: em vez de estabelecer uma nova conexão HTTP a cada interação e enviar o histórico completo da conversa, poderíamos manter uma conexão persistente e armazenar o estado em cache. Assim, só seria necessário enviar novas informações que precisassem de validação e processamento, enquanto o restante do contexto ficaria armazenado na memória durante toda a duração da conexão. Isso reduziria drasticamente o overhead de trabalho redundante. Exploramos diferentes abordagens, como WebSockets e streaming bidirecional com gRPC. Optamos pelos WebSockets porque, como um protocolo simples de transporte de mensagens, os usuários não precisariam alterar a estrutura de entrada e saída da API Responses. Além de ser mais amigável para desenvolvedores, essa solução se integrou facilmente à nossa arquitetura existente com mínima disrupção.
O primeiro protótipo com WebSockets mudou completamente o que acreditávamos ser possível em termos de latência na API Responses. Um engenheiro do time do Codex, com vasta experiência em toda a pilha da API, desenvolveu um protótipo executando um agente do Codex durante uma noite inteira. Nesse teste, os fluxos de trabalho do agente foram modelados como uma única resposta em andamento. Usando recursos do asyncio, a API Responses passou a operar de forma assíncrona no loop de amostragem após uma chamada de ferramenta ser selecionada. A API enviaria então um evento response.done de volta ao cliente. Após a execução da ferramenta no lado do cliente, este enviaria um evento response.append com o resultado, desbloqueando o loop de amostragem e permitindo que o modelo continuasse seu trabalho. Uma boa analogia para esse processo é compará-lo a uma chamada de ferramenta hospedada. Quando o modelo precisa buscar informações na web, o loop de inferência é pausado, um serviço de busca é acionado e a resposta é inserida no contexto do modelo. Nossa implementação faz a mesma coisa, mas em vez de chamar um serviço remoto, enviamos a solicitação da ferramenta do modelo de volta para o cliente via WebSocket. Quando o cliente responde, nós inserimos o resultado no contexto e retomamos a geração de tokens.
Esse projeto se mostrou extremamente eficaz porque eliminou o trabalho repetido da API ao longo de um fluxo de trabalho de agente. Agora, conseguíamos fazer o pré-processamento da inferência uma única vez, pausar para a execução da ferramenta e realizar o pós-processamento apenas no final. No entanto, essa abordagem inicial enfrentou desafios em cenários com múltiplos clientes ou quando as conexões eram interrompidas inesperadamente. Para resolver isso, tivemos que implementar mecanismos robustos de retomada e sincronização de estado, garantindo que o modelo pudesse recuperar o contexto exatamente de onde parou, mesmo após uma queda na conexão. Além disso, foi necessário desenvolver uma camada de segurança aprimorada para validar cada interação sem adicionar latência