← Blog
October 2, 2025

Adicione streaming ao seu aplicativo LLM de maneira simples

O streaming é a vitória mais fácil para UX e custo. Os usuários veem as palavras mais cedo, cancelam quando têm o suficiente e você gasta menos tokens. O streaming reduz a latência, o que é essencial para uma experiência tranquila para o usuário final. Você só precisa de duas coisas: um servidor que transmitee um cliente que lê partes sem armazenar em buffer.

Experimente o Compute hoje
Lance um vLLM servidor de inferência ligado Computar. Você obtém um endpoint HTTPS com rotas no estilo OpenAI que são transmitidas por padrão. Aponte seu SDK OpenAI existente para o novo URL base e comece a medir o TTFT.

Tokens de streaming: uma comparação entre SSE e WebSockets em inglês simples

Eventos enviados pelo servidor (SSE). Stream unidirecional via HTTP. O SSE transmite dados do servidor para o cliente por meio de uma conexão HTTP. Simples, compatível com proxy, ótimo para streaming de tokens. A API EventSource é padronizada como parte do HTML Living Standard pelo WHATWG. Funciona com o EventSource em navegadores e com respostas de streaming na maioria dos clientes HTTP.

WebSockets. Mensagens bidirecionais em um soquete persistente. Os WebSockets usam o protocolo WebSocket e são gerenciados por meio de um objeto WebSocket, permitindo a comunicação bidirecional em tempo real entre cliente e servidor. Útil quando o cliente precisa enviar eventos no meio do fluxo (digitação, sincronização do cursor, edições colaborativas). O streaming de tokens é o modo no qual o servidor retorna os tokens um por um à medida que o modelo os gera.

Regra prática: usa SSE para bate-papo a menos que você realmente precise de mensagens bidirecionais. Com o streaming de tokens, o servidor pode começar a retornar tokens antes de gerar toda a resposta.

Quando usar qual

  • VEJA: respostas de bate-papo, resumos, geração de código, qualquer coisa somente para leitura no navegador.
  • WebSockets: editores colaborativos, fluxos de voz, ferramentas que enviam atualizações de média geração do cliente para o servidor e aplicativos do mundo real que exigem comunicação bidirecional interativa.
  • Misturar: comece com o SSE; adicione o WS posteriormente para os poucos lugares que precisam dele. Os tokens de streaming são credenciais temporárias e exclusivas usadas por plataformas de vídeo on-line para autenticar e autorizar o acesso de um usuário a um fluxo de vídeo específico.

Implementar eventos enviados pelo servidor (SSE)

Nodo (SDK do OpenAI, servidor compatível com OpenAI)

importar OpenAI de “openai”;
const client = new OpenAI ({baseUrl: "https://YOUR-ENDPOINT/v1 “, apiKey: process.env.key});

const stream = await client.chat.completions.create ({
modelo: “f3-7b-instruct”,
messages: [{role: “user”, content: “Elabore uma breve atualização sobre o status do projeto.”}],
stream: verdadeiro,
máximo de tokens: 200
});

para await (const trecho do stream) {
const delta = chunk.choices?. [0]?. delta?. conteúdo;
if (delta) process.stdout.write (delta);
}

Python (SDK OpenAI, servidor compatível com OpenAI)

de openai import OpenAI
client = OpenAI (base_url=” https://YOUR-ENDPOINT/v1 “, API_key="your_key”)

com client.chat.completions.stream (
model="f3-7b-instruct”,
messages= [{"role” :"user”, "content” :"Escreva um resumo de um parágrafo. “}],
max_tokens = 200,
) como stream:
para evento em stream:
se event.type == “token”:
imprimir (event.token, end= "”)

Cancele rapidamente quando os usuários param de ler:

const controller = novo abortController ();
//sinal de passagem: client.chat.completions.create ({..., stream: true, signal: controller.signal})
//mais tarde
controller.abort ();

Implemente o WebSocket Server (quando você precisar de duas vias)

O servidor WebSocket estabelece uma conexão websocket persistente com os clientes, permitindo a comunicação bidirecional em tempo real. Durante o handshake inicial, o servidor e o cliente trocam cabeçalhos HTTP, incluindo SEC-WebSocket-Key, SEC-WebSocket-Version e SEC-WebSocket-Protocol, para atualizar a conexão HTTP para uma conexão WebSocket e garantir a segurança e a conformidade do protocolo.

//Esboço do servidor usando ws
importar {websocketServer} de “ws”;
const wss = novo WebSocketServer ({porta: 8080});

wss.on (“conexão”, (ws) => {
ws.on (“mensagem”, assíncrona (msg) => {
const {prompt} = JSON.parse (msg.toString ());
//chame seu endpoint compatível com OpenAI com stream=true
para await (símbolo const de generateStream (prompt)) {
ws.send (token);//contrapressão: verifique ws.bufferedAmount
}
});

ws.on (“fechar”, () => {
//Lidar com a limpeza quando a conexão é fechada
//Libere recursos ou realize qualquer limpeza necessária aqui
});
});

Quando a conexão é fechada, o servidor WebSocket aciona um evento de fechamento, permitindo que você gerencie a limpeza e os recursos gratuitos associados a essa conexão websocket.

Alça contrapressão: faça uma pausa quando ws.BufferedAmount for grande; retome quando for drenado. Em navegadores, use a API de streams com reader.read () e respeite os sinais ReadableStreamDefaultReader.

Cancelamentos, novas tentativas, contrapressão

  • Cancele rapidamente. Conecte um botão de parada que aborta a solicitação HTTP ou fecha o soquete. Liberte imediatamente os blocos de cache KV do lado do servidor.
  • Tentativas novamente. Use o recuo exponencial com instabilidade na conexão e erros de primeiro token. Não tente novamente depois de transmitir texto visível ao usuário, a menos que você reinicie claramente a resposta.
  • Contrapressão. No Node, verifique os sinais res.flush () /drain ou BufferedAmount no WS. Mantenha os blocos pequenos; prefira linhas JSON delimitadas por\npara fluxos personalizados. Configure o número máximo de solicitações ou fluxos simultâneos para evitar a sobrecarga do servidor.

Gateways e proxies (evite surpresas no buffer)

  • Mantenha buffer de resposta desativado para rotas de streaming.
  • Uso HTTP/1.1 ou HTTP/2 com keep‑alive; evite intermediários que coalescem pedaços.
  • Defina sensatamente tempos limite de inatividade portanto, gerações longas não caem no meio do caminho.
  • Enviar Tipo de conteúdo: texto/fluxo de eventos para SSE com Cache-Control: no-store e Connection: keep-alive.

Dicas de UX que fazem com que o streaming pareça rápido

  • Mostre as fichas quando elas chegarem; mantenha um cursor útil.
  • Permita que os usuários parar e copiar facilmente.
  • Imprima blocos de código parcial de forma limpa; feche as cercas quando os fluxos terminarem.
  • Mantenha as instruções do sistema curtas; tampas de saída abertas para funcionar.
  • Registrado em carimbo de data/hora do primeiro token para detectar regressões.
Experimentos de computação hoje
Implemente um vLLM ponto final ligado Computar. O streaming está ativado por padrão. Coloque-o perto de dois usuários, defina limites de saída restritos e veja o TTFT e o TPS melhorarem.

Streaming de tokens que parece rápido e custa menos

Use o SSE para a maioria dos bate-papos. Use WebSockets somente quando precisar de mensagens bidirecionais. Cancele imediatamente, limite as saídas e desative o proxy de buffer. Medida tempo até o primeiro token e tokens por segundoe, em seguida, ajuste os limites e os limites do lote antes de trocar o hardware.

PERGUNTAS FREQUENTES

O que é um evento enviado pelo servidor (SSE)?

Um fluxo HTTP unidirecional que o servidor envia para o cliente. O streaming de tokens é bem mapeado para o SSE.

Qual é a diferença entre SSE e WebSockets?

O SSE é unidirecional e simples; os WebSockets são bidirecionais e são melhores para aplicativos interativos. Para sair de bate-papo, o SSE geralmente é suficiente.

A API compatível com OpenAI é compatível com streaming?

Sim, use stream: true ou um cliente SSE. Você receberá tokens incrementais até que o modelo pare ou você cancele.

Como faço para cancelar uma transmissão?

Interrompa a solicitação HTTP (SSE) ou feche o WebSocket. Sempre libere recursos do servidor ao cancelar.

Por que vejo a saída chegar em um único bloco?

Um intermediário está armazenando a resposta em buffer. Desative o buffer da rota e mantenha a conexão ativa.

Posso transmitir em navegadores sem uma biblioteca?

Sim — EventSource para SSE ou fetch () com API Streams para ler partes.