Streaming NDJSON, evento por evento
Un recorrido por cada tipo de evento del stream NDJSON al enviar un mensaje a un agente, para construir una interfaz de chat que se sienta en tiempo real.

Cuando envías un mensaje a un agente, la respuesta por defecto no es un JSON único al final: es un flujo NDJSON, una línea por evento, que empieza a llegar apenas el modelo tiene algo que decir. Entender qué representa cada tipo de línea es lo que separa una interfaz de chat que se siente viva de una que parece congelada hasta que termina de pensar.
NDJSON, en corto
NDJSON —JSON delimitado por saltos de línea— es exactamente lo que suena: cada línea del cuerpo de la respuesta es un objeto JSON completo e independiente. No hay que esperar a que termine la respuesta para parsear la primera línea; puedes leer el stream byte a byte, cortar por salto de línea y parsear cada fragmento en cuanto llega.
Los eventos que vas a ver más seguido
- chat: el chat donde ocurre la conversación —con su id y su agente— llega primero si se creó uno nuevo.
- message: el mensaje del usuario ya persistido, para que tu interfaz lo pinte de inmediato.
- message_start / message_end: marcan el inicio y el cierre de la respuesta del asistente.
- delta: el fragmento de texto que se va generando; vas concatenando estos para pintar la respuesta en tiempo real.
- done: el cierre del stream completo, con los mensajes finales ya persistidos.
Eventos que no siempre aparecen
Un tool_call anuncia que el agente decidió invocar una herramienta, seguido de un evento tool con el resultado —normalmente ofuscado como un objeto vacío por privacidad, salvo la generación de imágenes, que sí entrega la URL real en un evento de tipo image. El evento thinking, cuando aparece, expone razonamiento intermedio del modelo; trátalo como opcional en tu interfaz, no como algo con lo que siempre puedas contar.
Qué hacer con un evento error a mitad de stream
Un stream puede cortarse antes de llegar a done, con una línea de tipo error en su lugar. El mensaje del usuario ya se persistió antes de que el modelo empezara a responder, así que no se pierde; lo que falta es la respuesta del agente. Tu interfaz debería distinguir claramente ese caso —«no llegó respuesta»— de una respuesta vacía, y ofrecer reintentar sobre el mismo chat.
El streaming no es un detalle de transporte, es la diferencia entre una respuesta que se siente instantánea y una que se siente colgada.
Cuándo preferir la respuesta sin streaming
Si tu integración no tiene una interfaz que pinte texto progresivamente —un bot que solo entrega el mensaje final a otro sistema, por ejemplo— pedir la respuesta sin streaming simplifica el consumo: un único JSON con los mensajes completos. Ten en cuenta que los identificadores y las fechas de esa respuesta puntual son sintéticos, no los mismos que quedaron persistidos; si necesitas el registro real, consúltalo después por el historial del chat.
Lleva esto a producción con Arko
Crea tu agente, conéctale tus APIs con Powers y publícalo en tu producto desde un solo panel. Empieza gratis hoy mismo.
Crear cuenta gratis

