En mis últimas publicaciones, hablé mucho sobre el almacenamiento en caché rápido y el almacenamiento en caché en general, y cómo puede mejorar su aplicación de IA en términos de costo y latencia. Sin embargo, incluso para una aplicación de IA totalmente optimizada, a veces las respuestas tardarán algún tiempo en generarse y simplemente no hay nada que podamos hacer al respecto. Cuando solicitamos grandes resultados del modelo o requerimos razonamiento o pensamiento profundo, el modelo naturalmente tardará más en responder. Por muy razonable que sea, esperar más tiempo para recibir una respuesta puede resultar frustrante para el usuario y reducir su experiencia general al utilizar una aplicación de IA. Afortunadamente, una forma sencilla y directa de mejorar este problema es la transmisión de respuestas.
Streaming significa obtener la respuesta del modelo de forma incremental, poco a poco, a medida que se genera, en lugar de esperar a que se genere la respuesta completa y luego mostrársela al usuario. Normalmente (sin transmisión), enviamos una solicitud a la API del modelo, esperamos a que el modelo genere la respuesta y, una vez que se completa la respuesta, la recuperamos de la API en un solo paso. Sin embargo, con la transmisión, la API devuelve resultados parciales mientras se genera la respuesta. Este es un concepto bastante familiar porque la mayoría de las aplicaciones de IA orientadas al usuario como ChatGPT, desde el momento en que aparecieron por primera vez, utilizaron la transmisión para mostrar sus respuestas a sus usuarios. Pero más allá de ChatGPT y LLM, la transmisión se utiliza esencialmente en todas partes de la web y en aplicaciones modernas, como por ejemplo en notificaciones en vivo, juegos multijugador o transmisiones de noticias en vivo. En esta publicación, exploraremos más a fondo cómo podemos integrar la transmisión en nuestras propias solicitudes para modelar API y lograr un efecto similar en aplicaciones de IA personalizadas.
Existen varios mecanismos diferentes para implementar el concepto de streaming en una aplicación. No obstante, para las aplicaciones de IA, existen dos tipos de transmisión ampliamente utilizados. Más específicamente, esos son:
Transmisión HTTP a través de eventos enviados por el servidor (SSE): es un tipo de transmisión relativamente simple y unidireccional que solo permite la comunicación en vivo del servidor al cliente. Streaming con WebSockets: Es un tipo de streaming más avanzado y complejo, que permite la comunicación bidireccional en vivo entre el servidor y el cliente.
En el contexto de las aplicaciones de IA, la transmisión HTTP a través de SSE puede admitir aplicaciones de IA simples en las que solo necesitamos transmitir la respuesta del modelo por razones de latencia y UX. No obstante, a medida que avanzamos más allá de los simples patrones de solicitud-respuesta hacia configuraciones más avanzadas, los WebSockets se vuelven particularmente útiles ya que permiten una comunicación bidireccional en vivo entre nuestra aplicación y la API del modelo. Por ejemplo, en asistentes de código, sistemas multiagente o flujos de trabajo de llamada de herramientas, es posible que el cliente necesite enviar actualizaciones intermedias, interacciones del usuario o comentarios al servidor mientras el modelo aún está generando una respuesta. Sin embargo, para la mayoría de las aplicaciones de IA simples en las que solo necesitamos que el modelo proporcione una respuesta, los WebSockets suelen ser excesivos y SSE es suficiente.
En el resto de esta publicación, analizaremos mejor la transmisión de aplicaciones de IA simples que utilizan la transmisión HTTP a través de SSE.
. . .
¿Qué pasa con la transmisión HTTP a través de SSE?
La transmisión HTTP a través de eventos enviados por el servidor (SSE) se basa en la transmisión HTTP.
. . .
La transmisión HTTP significa que el servidor puede enviar lo que sea que tenga que enviar en partes, en lugar de hacerlo todo a la vez. Esto se logra cuando el servidor no finaliza la conexión con el cliente después de enviar una respuesta, sino que la deja abierta y envía al cliente cualquier evento adicional que ocurra inmediatamente.
Por ejemplo, en lugar de obtener la respuesta en una sola parte:
¡Hola Mundo!
podríamos obtenerlo en partes usando transmisión HTTP sin formato:
Hola Mundo !
Si tuviéramos que implementar la transmisión HTTP desde cero, necesitaríamos manejar todo nosotros mismos, incluido el análisis del texto transmitido, la gestión de errores y las reconexiones al servidor. En nuestro ejemplo, usando streaming HTTP sin procesar, tendríamos que explicarle de alguna manera al cliente que “¡Hola mundo!” Es un evento conceptualmente, y todo lo posterior sería un evento separado. Afortunadamente, existen varios marcos y contenedores que simplifican la transmisión HTTP, uno de los cuales es la transmisión HTTP a través de eventos enviados por el servidor (SSE).
. . .
Por lo tanto, los eventos enviados por el servidor (SSE) proporcionan una forma estandarizada de implementar la transmisión HTTP estructurando las salidas del servidor en eventos claramente definidos. Esta estructura hace que sea mucho más fácil analizar y procesar respuestas transmitidas en el lado del cliente.
Cada evento normalmente incluye:
una identificación un tipo de evento una carga útil de datos
o más propiamente…
id: evento: datos:
Nuestro ejemplo usando SSE podría verse así:
id: 1 evento: datos del mensaje: ¡Hola mundo!
Pero ¿qué es un evento? Cualquier cosa puede considerarse un evento: una sola palabra, una oración o miles de palabras. Lo que realmente califica como un evento en nuestra implementación particular está definido por la configuración de la API o el servidor al que estamos conectados.
Además de esto, SSE viene con otras comodidades, como volver a conectarse automáticamente al servidor si se finaliza la conexión. Otra cosa es que los mensajes de flujo entrantes están claramente etiquetados como texto/flujo de eventos, lo que permite al cliente manejarlos adecuadamente y evitar errores.
. . .
Arremangarse
Las API de Frontier LLM, como la API de OpenAI o la API de Claude, admiten de forma nativa la transmisión HTTP a través de SSE. De esta manera, integrar la transmisión en sus solicitudes se vuelve relativamente simple, ya que se puede lograr modificando un parámetro en la solicitud (por ejemplo, habilitando un parámetro stream=true).
Una vez habilitada la transmisión, la API ya no espera la respuesta completa antes de responder. En cambio, devuelve pequeñas partes de la salida del modelo a medida que se generan. En el lado del cliente, podemos iterar sobre estos fragmentos y mostrarlos progresivamente al usuario, creando el familiar efecto de escritura ChatGPT.
Pero hagamos un ejemplo mínimo de esto usando, como de costumbre, la API de OpenAI:
tiempo de importación desde openai import OpenAI client = OpenAI(api_key=”your_api_key”) stream = client.responses.create( model=”gpt-4.1-mini”, input=”Explica la transmisión de respuesta en 3 párrafos cortos.”, stream=True, ) full_text = “” para evento en flujo: # solo imprime el delta de texto a medida que llegan las partes del texto si event.type == “response.output_text.delta”: print(event.delta, end=””, flush=True) full_text += event.delta print(“\n\nRespuesta final recopilada:”) print(full_text)
En este ejemplo, en lugar de recibir una única respuesta completa, iteramos sobre un flujo de eventos e imprimimos cada fragmento de texto a medida que llega. Al mismo tiempo, también almacenamos los fragmentos en una respuesta completa full_text para usarlos más adelante si así lo deseamos.
. . .
Entonces, ¿debería simplemente presionar streaming = True en cada solicitud?
La respuesta corta es no. Por muy útil que sea, con un gran potencial para mejorar significativamente la experiencia del usuario, el streaming no es una solución única para las aplicaciones de IA, y debemos usar nuestro criterio para evaluar dónde debería implementarse y dónde no.
Más concretamente, añadir streaming en una aplicación de IA es muy eficaz en configuraciones en las que esperamos respuestas largas y valoramos sobre todo la experiencia del usuario y la capacidad de respuesta de la aplicación. Un caso así serían los chatbots orientados al consumidor.
Por otro lado, para aplicaciones simples en las que esperamos que las respuestas proporcionadas sean breves, no es probable que agregar streaming proporcione mejoras significativas a la experiencia del usuario y no tiene mucho sentido. Además de esto, la transmisión por secuencias solo tiene sentido en los casos en que la salida del modelo es texto libre y no estructurada (por ejemplo, archivos json).
Lo más importante es que el principal inconveniente de la transmisión es que no podemos revisar la respuesta completa antes de mostrársela al usuario. Recuerde, los LLM generan los tokens uno por uno y el significado de la respuesta se forma a medida que se genera la respuesta, no por adelantado. Si realizamos 100 solicitudes a un LLM con exactamente la misma información, obtendremos 100 respuestas diferentes. Es decir, nadie sabe antes de completar las respuestas qué va a decir. Como resultado, con el streaming activado es mucho más difícil revisar la salida del modelo antes de mostrársela al usuario y aplicar cualquier garantía sobre el contenido producido. Siempre podemos intentar evaluar las terminaciones parciales, pero nuevamente, las terminaciones parciales son más difíciles de evaluar, ya que tenemos que adivinar hacia dónde va el modelo con esto. Agregar que esta evaluación debe realizarse en tiempo real y no solo una vez, sino de forma recursiva en diferentes respuestas parciales del modelo, hace que este proceso sea aún más desafiante. En la práctica, en tales casos, la validación se ejecuta en toda la salida una vez completada la respuesta. Sin embargo, el problema con esto es que en este punto puede que ya sea demasiado tarde, ya que es posible que ya hayamos mostrado al usuario contenido inapropiado que no pasa nuestras validaciones.
. . .
en mi mente
La transmisión por secuencias es una característica que no tiene un impacto real en las capacidades de la aplicación de IA, ni en su costo y latencia asociados. No obstante, puede tener un gran impacto en la forma en que el usuario percibe y experimenta una aplicación de IA. La transmisión hace que los sistemas de IA se sientan más rápidos, con mayor capacidad de respuesta y más interactivos, incluso cuando el tiempo para generar la respuesta completa sigue siendo exactamente el mismo. Dicho esto, el streaming no es una solución milagrosa. Diferentes aplicaciones y contextos pueden beneficiarse más o menos de la introducción del streaming. Como muchas decisiones en ingeniería de IA, se trata menos de lo que es posible y más de lo que tiene sentido para su caso de uso específico.
. . .
Si llegaste hasta aquí, Puede que te resulten útiles los pialgoritmos. — una plataforma que hemos estado construyendo y que ayuda a los equipos a gestionar de forma segura el conocimiento organizacional en un solo lugar.
. . .
¿Te encantó esta publicación? Únase a mí en 💌Substack y 💼LinkedIn
. . .
Todas las imágenes del autor, salvo que se indique lo contrario.