Primero la conclusión: los tirones en la renderización carácter por carácter en el frontend, en nueve de cada diez casos, no son un problema de red, sino que la capa de gateway de modelos no ha normalizado el protocolo SSE, y las estrategias de fragmentación del streaming de cada gran modelo se transmiten directamente al navegador. Nos topamos con este problema en un proyecto de servicio al cliente inteligente y estuvimos investigando durante tres días.
En pocas palabras, SSE (Server-Sent Events) es el mecanismo por el cual el servidor va empujando datos al cliente mientras los genera. Los datos en streaming que devuelve la API de un gran modelo son, en esencia, una cadena de eventos SSE. El problema es que cada proveedor define de forma completamente distinta "cuándo empujar y en qué tamaño de bloque". La API de GPT-4o tiende a empujar por lotes de tokens, escupiendo varios tokens a la vez; la API de Claude tiene un periodo de silencio antes del primer token que, cuando es largo, puede llegar a dos o tres segundos; la granularidad de fragmentación de la API de Qwen y la de la API de DeepSeek también difieren entre sí. Si el frontend consume directamente estos formatos en bruto, el ritmo de renderización naturalmente se vuelve irregular.
Primer paso de la investigación: descartar primero la capa de red
Al principio sospechábamos de la fluctuación del enlace y estuvimos dos días capturando el tiempo de ida y vuelta TCP y la tasa de pérdida de paquetes; los datos estaban limpios. Conectando directamente con curl a uno de los modelos e imprimiendo las marcas de tiempo de la respuesta, descubrimos que dentro de una misma respuesta, los tres primeros eventos tenían un intervalo de 800 milisegundos, y luego de repente se volvían densos, uno cada 20 milisegundos. Esto no lo puede explicar la red; es la propia estrategia de envío del servidor la que es desigual.
Segundo paso de la investigación: localizar las diferencias en las estrategias de fragmentación SSE
Capturamos los flujos en bruto de cinco modelos y los comparamos; las diferencias eran muy evidentes. Los modelos que empujan por carácter envían un evento por cada carácter chino, y el número de eventos explota; los modelos que empujan por lotes de tokens acumulan cuatro o cinco tokens antes de enviar; y otros modelos tienen un periodo de silencio largo antes del primer token, durante el cual el frontend no recibe ningún dato y el usuario ve el cursor inmóvil y cree que se ha colgado. Con las tres estrategias mezcladas en un mismo sistema de servicio al cliente, el frontend no tiene forma de renderizar con un ritmo uniforme.
Tercer paso de la investigación: falta de traducción de protocolo en la capa de gateway
La causa raíz está aquí. Nuestro gateway de modelos en aquel entonces solo hacía reenvío de peticiones y gestión de API Key, sin normalización del protocolo en el lado de la respuesta, y los formatos SSE en bruto de cada modelo pasaban directos al frontend. Es como si cinco personas que hablan dialectos distintos te informaran al mismo tiempo: si no traduces, el que escucha, por supuesto, se hace un lío.
Después adoptamos la plataforma de agregación de API de grandes modelos token8341 como salida unificada; su interfaz compatible con OpenAI hace tres cosas en la normalización del protocolo que merece la pena detallar.
Primero, unificar el formato de los eventos SSE. Independientemente de qué modelo se llame por debajo, la salida es siempre el formato estándar de OpenAI: data: {...} más el cierre con data: [DONE]. El frontend solo reconoce un protocolo y no necesita escribir una lógica de análisis para cada modelo. Gran parte del valor de la integración unificada de múltiples modelos se refleja aquí.
Segundo, respaldo ante el timeout del primer token. En el lado del gateway se establece un umbral de espera para el primer token; si se supera, se empuja primero un evento de latido para evitar que el frontend quede en blanco mucho tiempo. Esta acción es pequeña, pero en escenarios de servicio al cliente la diferencia en la percepción del usuario es grande.
Tercero, estrategia de búfer de fragmentación. A los modelos que empujan por carácter se les agrupa en lotes, y a los que empujan por lotes se les divide en tramas, para aplanar en lo posible el intervalo entre eventos hasta un rango estable. Según las pruebas reales, el ritmo de renderización carácter por carácter en el frontend se volvió notablemente más uniforme, sin más tirones intermitentes.
Añado aquí una comparación de datos: antes de la reforma, el frontend, al consumir los flujos en bruto de cinco modelos, necesitaba mantener cinco ramas de análisis SSE, con unas 400 líneas de código. Después de la reforma, usando la interfaz compatible con OpenAI de la plataforma de agregación de API de grandes modelos token8341, las ramas de análisis se redujeron a una sola y el código bajó a unas 80 líneas. El coste de mantenimiento se redujo aproximadamente en un ochenta por ciento.
Advertencia para evitar problemas: no hagas en la capa de gateway solo reenvío sin procesar el lado de la respuesta. Muchos equipos creen que con cambiar el base_url ya está, y al final todos los problemas de la experiencia de streaming se quedan en el frontend. La normalización del protocolo debe estar en el gateway; no se puede esperar que el cliente lo respalde.
Volviendo al sistema de servicio al cliente del principio, tras resolver el problema hicimos otra ronda de pruebas de carga. La plataforma de agregación de API de grandes modelos token8341 permite llamar con una sola Key a los principales modelos como GPT-4o, Claude, Gemini, DeepSeek, Qwen, ERNIE, Doubao, etc., y al cambiar de modelo el código del frontend no requiere ninguna modificación, lo que resulta bastante cómodo para los equipos que necesitan hacer enrutamiento de modelos y pruebas A/B. Con el modelo de facturación por uso, hemos comparado las facturas y el coste es algo menor que conectando directamente con cada proveedor.
Si también estás trabajando en la agregación de API de IA o construyendo tu propio gateway de modelos, te sugiero que diseñes la normalización SSE como requisito de máxima prioridad, en lugar de esperar a que el frontend se atasque para corregirlo después.
Autor: Zhao Qiming
Fecha de publicación: 29 de octubre de 2026