Streaming de respuestas: mostrar la IA mientras escribe

El streaming de respuestas muestra el texto de un modelo de IA mientras se genera, en vez de esperar al final. Cómo funciona con SSE y cómo diseñarlo.

info Definición Rápida
El streaming de respuestas es la forma de entregar el resultado de un modelo de IA en fragmentos, a medida que se genera, para que la persona empiece a leer antes de que termine. Suele enviarse con SSE (server-sent events, eventos enviados por el servidor). El modelo no tarda menos: cambia el momento en que aparece el texto.

¿Qué es y cómo funciona?

Un modelo de lenguaje genera la respuesta token por token (si no tienes claro qué es un token, mira tokens). Sin streaming, el servidor espera a tener el texto completo y lo envía de una vez. Con streaming, envía cada fragmento en cuanto lo tiene.

SSE es un mecanismo web de una sola vía: el servidor responde con el tipo de contenido text/event-stream y el cliente recibe eventos mientras la conexión sigue abierta. No se pueden enviar eventos del cliente al servidor por ese mismo canal (MDN).

En la API de Claude se activa con "stream": true y el flujo sigue siempre el mismo orden:

EventoQué traeQué puede hacer tu interfaz
message_startUn mensaje con content vacíoMostrar el indicador inicial
content_block_startAbre un bloque de contenido (texto, uso de herramienta, razonamiento)Crear el contenedor del bloque
content_block_deltaUn fragmento nuevo; en bloques de texto, un text_deltaAñadir el texto a lo ya mostrado
content_block_stopCierra el bloqueDar el formato final al bloque
message_deltaCambios del mensaje, como stop_reason; el uso de tokens es acumuladoGuardar el motivo de parada
message_stopFin del flujoQuitar el botón de detener
pingMantiene viva la conexión; puede llegar varias vecesIgnorarlo
errorPor ejemplo overloaded_errorMarcar la respuesta como incompleta

Los bloques de uso de herramientas y de razonamiento también llegan por deltas (input_json_delta y thinking_delta); decide si los muestras. Pueden aparecer tipos de evento nuevos, así que tu código debe ignorar los que no conoce.

No tienes que leer este protocolo a mano: los SDK oficiales de Python y TypeScript ofrecen ayudantes que entregan solo el texto (text_stream en Python, el evento text en TypeScript). Si no necesitas mostrar nada a medias, el SDK puede usar streaming por dentro y devolverte el mensaje completo, útil con valores grandes de max_tokens para evitar tiempos de espera HTTP.

¿Por qué le importa a un diseñador?

Porque cambia lo que la persona percibe como espera. Nielsen Norman Group recuerda los tres límites clásicos: 0,1 s es lo que se siente como instantáneo, 1 s es lo máximo para no cortar el hilo de pensamiento y 10 s es el límite para mantener la atención en la tarea. Con una respuesta de ocho segundos que aparece de golpe, la persona mira una pantalla quieta; con texto desde el primer segundo, ya está leyendo.

Ojo: el streaming no acelera la respuesta. Mejora el tiempo hasta el primer contenido útil: si el modelo tarda seis segundos en generarlo todo, esos seis segundos siguen ahí; cambia qué ve la persona durante ellos.

Hay tres decisiones de diseño que dependen de esto:

  1. Qué mostrar antes de que llegue texto. Un indicador breve (un punto que pulsa, “Pensando”) que desaparece cuando empieza el texto. Para elegir entre spinner, esqueleto o barra, mira estados de carga en interfaces de IA.
  2. Cómo mostrar el texto parcial. Un texto que salta con cada token cansa. Agrupa fragmentos y mantén estable lo ya escrito.
  3. Qué pasa si se corta. Si la conexión cae o hay un error, la persona no debe perder lo que ya leyó sin saberlo.

¿Cuándo usar streaming y cuándo no?

Situación¿Streaming?Por qué
Resumen largo, borrador de correo, explicación de varios párrafosSíLa persona lee mientras llega y el texto parcial ya tiene valor
Respuesta de una palabra o un númeroNoSe entiende de golpe; el streaming solo añade parpadeo
Acción que se confirma al final (crear un registro)NoEl resultado parcial no sirve para decidir
Salida estructurada (un JSON que otro código va a leer)NoUn JSON a medias no se puede interpretar hasta que cierra
Agente con varios pasosSí, pero de pasosMostrar qué hace pesa más que el texto

Regla práctica: si la persona necesita el resultado completo para actuar, muestra un estado de carga y entrega el resultado entero. Si puede empezar a leer, usa streaming.

Para agentes con herramientas, el loop de un agente explica por qué la interfaz debe mostrar pasos. Y para medir la espera, mira latencia y tokens por segundo.

¿Cómo se implementa bien en la interfaz?

  1. Agrupa las actualizaciones. Repintar en cada token es caro. Acumula fragmentos y actualiza una vez por cuadro de animación del navegador.
  2. No fuerces el scroll. Si la persona subió para releer, no la devuelvas abajo con cada fragmento. Sigue el final solo si ya estaba ahí.
  3. Renderiza el formato con cuidado. Un bloque de código o una tabla a medio escribir puede romper la maqueta. Muestra el bloque en curso como texto plano hasta que cierre.
  4. Cuida a los lectores de pantalla. MDN recomienda aria-live="polite" para cambios importantes que no sean tan rápidos como para molestar, y pide crear la región antes de actualizar su contenido. Anuncia el inicio y el final de la respuesta, no cada token.
  5. Da una salida. Un botón de detener la generación, visible desde el primer fragmento. El patrón completo está en interrumpir y redirigir a un agente.
  6. Revisa por qué terminó. Un flujo puede cerrarse sin error y aun así estar truncado. El stop_reason del message_delta lo dice: end_turn es un final normal; max_tokens, por ejemplo, indica que el límite cortó la respuesta.

¿Qué hacer cuando el flujo se corta?

La API puede enviar errores dentro del flujo, por ejemplo overloaded_error en periodos de mucha demanda, que llegan como un evento error y no como un código HTTP. Trátalo como un caso normal.

La documentación de Claude describe una estrategia de recuperación en tres pasos: guardar lo recibido, crear una solicitud nueva que incluya ese texto parcial y seguir con el streaming desde ahí. En Claude 4.6 y posteriores, el texto parcial va en un mensaje de usuario con la instrucción de continuar. Límite: los bloques de herramientas y de razonamiento no se recuperan a medias; solo puedes reanudar desde el último bloque de texto.

En diseño: conserva el texto parcial, márcalo como incompleto y ofrece “Reintentar” o “Continuar”.

Ejemplo

Ejemplo ilustrativo: una herramienta interna resume reportes de ventas de 1.500 palabras. La primera versión muestra un spinner durante unos siete segundos y luego el resumen entero. Algunas personas creen que la app se colgó y recargan, lo que duplica las solicitudes.

El equipo cambia a streaming. Los primeros encabezados aparecen casi de inmediato y el texto crece debajo. Añaden un aviso fijo (“Generando resumen”) y un botón de detener. La duración total no cambia, pero hay algo que leer desde el primer segundo. Si el flujo falla, se conserva el texto recibido con un aviso de “Respuesta incompleta” y un botón de reintento.

Errores comunes

  • Hacer streaming de respuestas cortas, donde el texto parcial no aporta nada.
  • Actualizar el DOM en cada token sin agrupar, lo que vuelve la pantalla lenta y parpadeante.
  • No manejar el error a mitad del flujo y dejar una respuesta cortada sin aviso.
  • Dar por buena una respuesta solo porque el flujo terminó, sin mirar el stop_reason.
  • Quitar la opción de detener la generación o anunciar cada fragmento a los lectores de pantalla.

Fuentes

Preguntas frecuentes

¿Qué es el streaming de respuestas en IA?
Es la técnica de enviar la respuesta del modelo en pedazos, a medida que se genera, para mostrarla en pantalla sin esperar a que termine. El modelo genera igual; cambia cuándo ve la persona el texto.
¿El streaming hace que la IA responda más rápido?
No. El tiempo total para generar la respuesta es el mismo. Lo que cambia es el tiempo hasta el primer contenido visible, que es lo que la persona percibe como espera.
¿Qué pasa si hay un error a mitad del streaming?
La respuesta ya empezó a llegar, así que la interfaz debe manejar un error parcial: conservar lo recibido, marcarlo como incompleto y ofrecer reintentar. La API de Claude puede enviar un evento de error dentro del mismo flujo.
¿Conviene usar streaming en toda la interfaz de IA?
Conviene en respuestas largas que la persona lee mientras llegan. Para resultados cortos o acciones que se confirman de una vez, un indicador de carga y el resultado completo suelen ser mejores.