Streaming para generaciones largas

Resumen

Si generas contenido corto con IA, esperar unos segundos no molesta, pero cuando produces una newsletter, un guion largo o una campaña completa, esa espera se vuelve eterna. Aquí aprenderás a usar streaming con la API de OpenAI para mostrar la respuesta mientras se va generando, palabra por palabra. Es una técnica clave para cualquier desarrollador que construya herramientas de generación de contenido con Python y FastAPI.

Qué es el streaming y por qué mejora la experiencia

El streaming consiste en mostrar el texto conforme el modelo lo produce, en lugar de esperar a que termine toda la respuesta. Esto cambia radicalmente la percepción de velocidad: en vez de mirar una pantalla en blanco durante segundos, ves cómo aparecen las oraciones en tiempo real.

¿Qué es el streaming en la API de OpenAI? Es un modo de respuesta que entrega el resultado en eventos parciales mientras el modelo genera el texto, en lugar de enviarlo todo junto al final. Mejora la experiencia de usuario en contenidos largos.

La clave está en un parámetro. Seguimos usando el mismo client.responses.create, pero le agregamos stream con el valor true [00:31]. Con eso, la API deja de devolver un bloque único y empieza a responder en eventos.

Cómo se recorren los eventos del streaming

Cuando activas streaming, la respuesta ya no es un objeto plano sino una secuencia de eventos que debes recorrer con un for loop. Por cada evento en la respuesta, puedes imprimirlo o procesarlo [00:44].

El primer evento que llega es un response.created [01:05], que trae información inicial:

  • Un identificador único de la respuesta.
  • El tipo de objeto creado y su estatus.
  • Si hay error o no, y las instrucciones enviadas.
  • El listado de tokens y los modelos que se están utilizando.

Cada uno de estos eventos se va imprimiendo o mostrando en pantalla según lo que necesites. Y aquí viene lo interesante: no todos los eventos sirven para mostrar texto al usuario.

Cómo se construye la función de contenido largo

En el archivo del cliente de OpenAI, debajo de la función que genera imágenes, se agrega una nueva función para generar contenido largo vía stream [01:36]. La estructura es sencilla:

  • Se llama a client.responses.create con el modelo gpt-5.4, el mismo que se venía usando para texto.
  • Las instrucciones indican: genera contenido largo y claro para una campaña.
  • El input es el prompt, que llega por parámetros.
  • Se activa stream: true para recibir la respuesta por partes.

Con esa base, la función queda lista para entregar el contenido de forma progresiva en lugar de un solo golpe.

Cómo se conecta el endpoint en FastAPI

Para que el navegador reciba el stream, hay que crear un endpoint en el server. Debajo del endpoint de generar imagen se agrega uno nuevo llamado stream content [02:23], que recibe una idea desde el formulario y responde usando la función del cliente.

El detalle técnico importante es el formato de respuesta: se indica un media type de texto plano, para que el navegador interprete correctamente el flujo continuo de datos.

¿Qué importaciones necesito para el streaming en FastAPI? Debes importar StreamingResponse desde las respuestas de FastAPI y la función stream_long_content desde tu cliente de OpenAI. Sin ambas, el endpoint no funciona.

Cuando las dos funciones quedan correctamente importadas, el editor las marca con el color que confirma que todo está en orden [03:03]. Después solo falta ajustar la vista de home para agregar el formulario nuevo debajo del de generar imagen [03:12].

Cómo queda el formulario en el navegador

El formulario de contenido largo en streaming es un form simple con estos elementos:

  • Un text area con el nombre id, que se lee vía parámetros.
  • Una action que apunta al nuevo endpoint stream content.
  • Un botón de tipo submit con el texto generar en streaming.

Con el servidor corriendo usando el comando con --reload para que lea los cambios en caliente, el formulario ya aparece listo para probarse en el navegador [03:47].

Por qué el texto se quedaba en la terminal y no en el navegador

Al probar con el prompt "Cuéntame la historia de Platzi", la respuesta daba un error en el navegador, pero en la terminal aparecía todo el contenido en eventos [04:22]. Ese contraste es la pista clave.

En la terminal se veían líneas de tipo delta, cada una con una fracción del texto: una traía la palabra "cómo", otra "resumen", y así hasta armar la frase completa [04:42]. El problema era que el evento genérico incluía más de un tipo, así que no se imprimía correctamente en pantalla.

¿Cómo filtro solo el texto en el streaming de OpenAI? Valida que el tipo de evento sea response.output_text.delta y usa yield event.delta en vez de imprimir el evento completo. Así muestras solo el texto generado, parte por parte.

La solución fue reemplazar el print event por una validación que revisa si el tipo de evento es response.output_text.delta, que es justo el que carga el texto [05:26]. En lugar de imprimir, se usa yield con event.delta, lo que permite ir mostrando el contenido fragmento por fragmento.

Qué resultado se obtiene al final

Después de reiniciar el servidor y volver a pedir la historia de Platzi, la pantalla mostró el texto generándose oración por oración en tiempo real [06:04]. El contenido incluyó el origen de la comunidad, los fundadores Freddy Vega y Christian Van Der Henst, la etapa de Mejorando.la como primer gran paso, el crecimiento, la misión y el impacto cultural y empresarial.

Un detalle valioso: como trabajamos en generar textos e imágenes para campañas, el propio modelo ofreció versiones alternativas del contenido [06:40]:

  • Versión breve tipo resumen.
  • Versión cronológica con fechas clave.
  • Versión estilo storytelling.
  • Versión enfocada a negocios con modelo de startup.

La experiencia de usuario mejora de forma drástica cuando el contenido se visualiza mientras se crea, y no al terminar. ¿Has probado ya el streaming en tus propios proyectos con OpenAI? Cuéntanos en los comentarios cómo te fue.