Con el streaming de respuestas habilitado, si el cliente se desconecta (actualización del navegador) mientras el Agente de IA aún está transmitiendo, la ejecución se interrumpe y muestra { “isArtificialRecoveredEventItem”: true } con “Execution stopped at this node.” Me gustaría que la ejecución se complete en el servidor incluso si el cliente se desconecta, manteniendo el streaming activado.
Reproducción mínima (n8n vanilla, sin nodos personalizados)
- Chat Trigger (o Webhook con Response Mode: Streaming).
- Nodo AI Agent con enableStreaming: true, conectado a:
- cualquier Chat Model (p. ej. OpenAI Chat Model),
- cualquier herramienta que tarde unos segundos (p. ej. una herramienta HTTP Request que acceda a un endpoint lento — cualquier cosa que mantenga ocupado al agente lo suficiente para actualizar).
- Abre el chat integrado, envía un mensaje que haga que el agente llame a la herramienta.
- Actualiza la página inmediatamente, mientras aún está transmitiendo.
- Abre la ejecución → está detenida, salida del Agente de IA = { “isArtificialRecoveredEventItem”: true }.
Entorno
- n8n: Cloud, versión 2.27.4
- AI Agent node v3.1, Webhook v2.1 (responseMode: streaming)
Esperado vs real
- Esperado: el hecho de que el cliente pierda la transmisión no debería interrumpir la ejecución; el agente (y cualquier efecto secundario de la herramienta) debería completarse en el servidor.
- Real: la ejecución se interrumpe en el momento en que se cae la conexión de transmisión → elemento recuperado/artificial.
Lo que he probado
- Deshabilitar enableStreaming en el Agente de IA lo evita — pero entonces no hay streaming (deshabilitar el streaming en cualquiera de los nodos recurre al patrón request-response).
- Sé que existe el patrón de respuesta inmediata / dos webhooks asincrónico, pero eso elimina el streaming en vivo.
Pregunta
¿Hay alguna forma compatible de desacoplar la duración de la ejecución de la conexión HTTP de streaming — es decir, mantener el streaming habilitado pero permitir que la ejecución se complete (sin interrumpirse) cuando el cliente se desconecta a mitad de la transmisión? ¿Alguna configuración o patrón recomendado?
¿Quieres que:
- Exporte 1 workflow mínimo (Chat Trigger + AI Agent + 1 herramienta que simule lentitud + LLM) a JSON para que lo adjuntes — ¿reproducible al instante, aumentando mucho la probabilidad de recibir ayuda?
- ¿O mantengo esta versión y tú mismo rellenas la versión + adjuntas imágenes?
Con el streaming de respuestas habilitado, si el cliente se desconecta (actualización del navegador) mientras el Agente de IA aún está transmitiendo, la ejecución se interrumpe y muestra { “isArtificialRecoveredEventItem”: true } con “Execution stopped at this node.” Me gustaría que la ejecución se complete en el servidor incluso si el cliente se desconecta, manteniendo el streaming activado.
Reproducción mínima (n8n vanilla, sin nodos personalizados)
- Chat Trigger (o Webhook con Response Mode: Streaming).
- Nodo AI Agent con enableStreaming: true, conectado a:
- cualquier Chat Model (p. ej. OpenAI Chat Model),
- cualquier herramienta que tarde unos segundos (p. ej. una herramienta HTTP Request que acceda a un endpoint lento — cualquier cosa que mantenga ocupado al agente lo suficiente para actualizar).
- Abre el chat integrado, envía un mensaje que haga que el agente llame a la herramienta.
- Actualiza la página inmediatamente, mientras aún está transmitiendo.
- Abre la ejecución → está detenida, salida del Agente de IA = { “isArtificialRecoveredEventItem”: true }.
Entorno
- n8n: Cloud, versión <rellenar versión>
- AI Agent node v3.1, Webhook v2.1 (responseMode: streaming)
Esperado vs real
- Esperado: el hecho de que el cliente pierda la transmisión no debería interrumpir la ejecución; el agente (y cualquier efecto secundario de la herramienta) debería completarse en el servidor.
- Real: la ejecución se interrumpe en el momento en que se cae la conexión de transmisión → elemento recuperado/artificial.
Lo que he probado
- Deshabilitar enableStreaming en el Agente de IA lo evita — pero entonces no hay streaming (deshabilitar el streaming en cualquiera de los nodos recurre al patrón request-response).
- Sé que existe el patrón de respuesta inmediata / dos webhooks asincrónico, pero eso elimina el streaming en vivo.
@sawsew467 ninguno de los tres tiene un control integrado, el streaming vincula la ejecución a la conexión en vivo, así que una desconexión la destruye (ese elemento recuperado es el marcador genérico de n8ns “killed before finishing” (matado antes de terminar), no un OOM real), y no hay nada documentado para desacoplarlo o volverlo a adjuntar. la solución es no ejecutar el trabajo que debe sobrevivir en la ejecución transmitida, lanzar el agente + escritura de memoria a una ejecución separada no transmitida que termine del lado del servidor, y permitir que el cliente relea el historial al recargar. y extraer herramientas con efectos secundarios como enviar correo electrónico de la transmisión para que no se activen en un turno que nunca persiste.
Hola @sawsew467,
Ese marcador isArtificialRecoveredEventItem es una señal de que la ejecución se bloqueó en lugar de ser cancelada limpiamente. Cuando el navegador se desconecta, el socket TCP se cierra, y la siguiente llamada res.write() dentro del emisor de chunks de streaming de n8n lanza un error EPIPE. Eso se propaga a través de la cadena de callbacks de LangChain hacia el motor de flujo de trabajo, lo que bloquea la ejecución en mitad del proceso. El servicio de recuperación entonces rellena ese marcador artificial para cualquier nodo que comenzó pero nunca persistió su salida.
Así que la conexión SSE y la ejecución del lado del servidor están acopladas arquitectónicamente en la implementación actual de streaming de n8n. No hay una bandera de configuración para desacoplarse.
Tus opciones reales:
1. Desactivar streaming en el nodo AI Agent: lo que ya intentaste, pero vale la pena nombrarlo claramente: la ejecución se completa en el servidor con cero riesgo de desconexión, y la respuesta completa se devuelve cuando termina el flujo de trabajo. La compensación de UX es real pero la ejecución es confiable.
2. Responder inmediatamente y luego hacer polling: Usa un nodo Webhook configurado en «Respond Immediately» (Responder inmediatamente). Devuelve un executionId de inmediato, el flujo de trabajo se ejecuta completamente en segundo plano sin respuesta HTTP adjunta (sin conexión SSE que se pierda), y el cliente hace polling en GET /api/v1/executions/{id} para obtener el resultado. Las herramientas lentas siempre se completarán. Pierdes la UX de streaming pero ganas ejecución determinista. En Cloud estás dentro del límite de timeout de 5 minutos siempre que tu HTTP Request no sea absurdamente lento.
3. Modo queue workers: solo autohospedado, no disponible en Cloud. Aun así, no está claro si los fallos de escritura de streaming en el proceso principal se desacoplan completamente del estado de ejecución del worker.
Para tu configuración específica, la opción 2 es probablemente el mejor camino si necesitas que las herramientas siempre se completen. La UX de polling es menos elegante que SSE pero mucho más predecible que esperar a que el cliente se mantenga conectado.
Si el streaming con tolerancia a desconexiones es crítico, esto requeriría un cambio en cómo n8n maneja los errores de escritura SSE, específicamente no propagarlos de vuelta al motor de ejecución.
Ambas las respuestas anteriores tienen razón en que el streaming de agentes integrado de n8n vincula el trabajo a la solicitud en directo, por lo que una desconexión detiene la ejecución, y hoy no hay ningún indicador para desacoplarse. Pero aún puedes obtener UX de streaming y finalización garantizada del lado del servidor al mismo tiempo. El truco es dejar de hacer streaming a través de la solicitud de n8n y mover el stream a un canal al que el cliente se suscribe de forma independiente.
Una estructura que funciona:
-
Trata el turno como un trabajo de fondo duradero. Toma la opción 2 de PurveshGandhi como base: el webhook responde inmediatamente con un id de turno, el agente se ejecuta hasta completarse del lado del servidor sin SSE adjunto, y la escritura de memoria sucede sin importar qué. Eso solo hace que el trabajo que debe sobrevivir sea a prueba de desconexiones.
-
Recupera el streaming escribiendo chunks en un canal externo, no en la respuesta HTTP. A medida que el turno produce salida, escríbelo en algo a lo que el navegador pueda suscribirse por su cuenta: una fila de realtime de Supabase, Redis pub/sub, Ably, o incluso una columna partial_response que el cliente consulte un par de veces por segundo. El navegador lee desde ese canal, nunca desde el SSE de n8n. Ahora una desconexión solo interrumpe el lado de lectura, la ejecución sigue en marcha, y al recargar el cliente se vuelve a suscribir y se pone al día desde el parcial almacenado. Esa es la respuesta de tener ambos: el trabajo está vinculado al job, el stream está vinculado al almacén.
-
Si la suavidad a nivel de token realmente importa, haz el streaming del modelo en un streamer delgado fuera de n8n (una pequeña función edge que hace streaming de tokens del modelo al cliente y publica la transcripción final de vuelta a n8n para la escritura de memoria duradero y cualquier herramienta). n8n sigue siendo el sistema de registro, la función edge es solo el conducto.
Uno más, en el espíritu del punto de achamm sobre herramientas con efectos secundarios: mantén cada efecto secundario, envía correos electrónicos, escribe en CRM, cualquier cosa que cueste dinero, protegida detrás del turno confirmado e identificada por el id del turno, para que un turno reintentado o sin terminar no pueda dispararlo dos veces. El streaming nunca debe ser lo que decida si un efecto secundario ocurrió.
Así que en realidad no tienes que elegir. Vincula la ejecución a un trabajo duradero, vincula el stream a un canal externo, y la desconexión del cliente deja de importar.
Hola 
Creo que entiendo el problema — este es un caso extremo bastante común con n8n AI Agent + streaming cuando la conexión del cliente se corta (actualizar el navegador / reconectar).
Lo que está pasando aquí es básicamente:
el ciclo de vida del stream está demasiado acoplado al contexto de ejecución, así que cuando el frontend se desconecta, la ejecución del backend se interrumpe o se rehidrata incorrectamente.
Yo tratería esto como dos ciclos de vida que actualmente están acoplados:
-
ciclo de vida de streaming del cliente
La conexión del navegador/cliente quiere tokens/eventos parciales ahora.
-
ciclo de vida de ejecución del servidor
La ejecución del agente puede necesitar terminar incluso si el cliente se desconecta.
Si estos están vinculados a la misma conexión HTTP, una desconexión puede convertirse en una señal de cancelación de ejecución. Para agentes de larga duración, normalmente los desacoplería:
- la solicitud inicia un trabajo y devuelve un job_id;
- el flujo de trabajo del lado del servidor continúa de forma independiente;
- el endpoint de streaming solo se suscribe a eventos del trabajo;
- si el streaming se desconecta, el trabajo sigue ejecutándose;
- el cliente puede reconectarse con job_id y obtener el estado/eventos/resultado actual;
- los estados terminales son success, failed, cancelled_by_user, timed_out.
La distinción importante es «cliente desaparecido» frente a «usuario canceló intencionalmente». Estos deberían ser estados separados.
Si la ruta de streaming actual de n8n vincula la desconexión al aborto, el patrón más seguro es colocar el agente de larga duración detrás de una capa de trabajo durable y tratar el streaming como un observador, no como el propietario de la ejecución.
Una pregunta no sensible: ¿necesitas que el navegador reciba cada token intermedio, o es suficiente hacer streaming de estado/eventos y obtener el resultado final cuando se complete el trabajo?
¡Bienvenido @sawsew467!
Esta es una limitación actual de la arquitectura de n8n: cuando el streaming está habilitado, el ciclo de vida de la ejecución está vinculado a la conexión push, por lo que una desconexión señala una cancelación. No hay una configuración integrada para desacoplailos en este momento.
El patrón de funcionamiento más cercano en n8n hoy en día: usa un Webhook regular (sin streaming) como punto de entrada, devuelve inmediatamente un job_id al cliente usando el nodo “Respond to Webhook”, luego dispara el trabajo del agente como un sub-workflow usando “Execute Workflow” configurado en modo “Run in Background”. El cliente consulta un segundo webhook GET con el job_id para obtener el resultado una vez que se escribe en una base de datos o almacén de datos estático. Pierdes el streaming de tokens en tiempo real, pero la ejecución del agente se completa independientemente del estado del cliente, lo que parece ser lo que realmente necesitas aquí.