Inicio → Ayuda

Una respuesta en streaming se detiene a mitad de frase

Un stream sano termina con un marcador explícito: un fragmento con finish_reason y después data: [DONE]. Si tu último fragmento no tiene ninguno de los dos, la conexión se cortó y la respuesta que tienes es parcial. El estado HTTP no te lo dirá, porque se envió antes de que empezara el cuerpo.

Lo que ves

Por qué ocurre

Las respuestas en streaming se comprometen con un 200 OK en cuanto sale el primer byte. Todo lo que viene después es cuerpo. Si la conexión muere en el token 900 de 1200, el cliente ya vio una línea de estado exitosa y no lanzará ningún error salvo que esté comprobando el marcador de fin del propio stream.

Por eso el fallo parece aleatorio. Las respuestas cortas terminan dentro de la ventana que permite el eslabón más débil; las largas, no. El punto de corte se desplaza porque depende del tiempo, no del contenido.

La causa habitual son los timeouts por inactividad de los proxies, que encajan mal con los modelos de razonamiento: durante una fase de razonamiento larga no se emite ningún token, así que un intermediario que mide el silencio en lugar de la duración total puede dar la conexión por muerta mientras el modelo sigue pensando.

Comprueba si es esta la causa

Lee el stream en bruto en lugar del objeto ya interpretado por un SDK, y mira el final:

curl -N -s 'YOUR_BASE_URL/chat/completions' \
  -H 'Authorization: Bearer YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"model":"YOUR_MODEL","stream":true,
       "messages":[{"role":"user","content":"Count slowly from 1 to 400."}]}' \
  | tail -5

Un stream completo termina con un fragmento que contiene "finish_reason":"stop" seguido de data: [DONE]. Si la última línea es un fragmento de contenido normal, el stream se cortó.

Cómo solucionarlo

  1. Verifica el marcador de finRegistra si viste [DONE] o un fragmento con un finish_reason no nulo. Sin ninguno de los dos, trata el resultado como fallido, no como corto. Este es el único cambio que hace visible el problema.
  2. Mantén viva la conexión durante las pausas largasSi un intermediario cierra por inactividad, los comentarios de heartbeat en el stream SSE lo evitan. Los proveedores que los envían hacen que los modelos de razonamiento sean mucho más fiables por la misma ruta de red.
  3. No reintentes a ciegas desde el principioUn stream cortado ya ha facturado los tokens que produjo. Reintentar todo el prompt duplica el coste. Donde la respuesta se pueda trocear, reanuda; donde no, al menos registra el fragmento parcial para que el gasto quede contabilizado.
  4. Prueba con una generación deliberadamente lenta y largaLos prompts cortos lo ocultan por completo. Pide algo que tarde un minuto en producirse y sabrás en un solo intento si tu ruta es estable.
APICLAN transmite el stream del upstream sin almacenarlo en búfer, así que finish_reason y [DONE] llegan exactamente como los envió el proveedor. La configuración de cada cliente está en el inicio rápido.

Relacionado

Unexpected token '<' al llamar a una API compatible con OpenAI401 invalid API key: cuando la clave parece correcta pero sigue fallando

Revisado por última vez el 2026-10-01. Escrito a partir de problemas diagnosticados en una pasarela compatible con OpenAI en producción, no recopilado de otras webs.