Home → Assistenza

Una risposta in streaming si interrompe a metà frase

Uno stream sano termina con un marcatore esplicito: un frammento con finish_reason, poi data: [DONE]. Se il tuo ultimo frammento non ha né l'uno né l'altro, la connessione è stata tagliata e la risposta che hai è parziale. Lo stato HTTP non te lo dirà, perché è stato inviato prima che iniziasse il corpo.

Cosa vedi

Perché succede

Le risposte in streaming si impegnano su un 200 OK non appena parte il primo byte. Tutto ciò che segue è corpo. Se la connessione muore al token 900 su 1200, il client ha già visto una riga di stato riuscita e non solleverà errori, a meno che non stia controllando il marcatore di fine dello stream stesso.

Ecco perché il problema sembra casuale. Le risposte brevi finiscono entro la finestra concessa dall'anello più debole; quelle lunghe no. Il punto di interruzione si sposta perché dipende dal tempo, non dal contenuto.

La causa abituale sono i timeout di inattività dei proxy, che si combinano male con i modelli di ragionamento: durante una lunga fase di ragionamento non viene emesso alcun token, quindi un intermediario che misura il silenzio invece della durata totale può dichiarare morta la connessione mentre il modello sta ancora pensando.

Verifica se la causa è questa

Leggi lo stream grezzo invece dell'oggetto già analizzato da un SDK, e guarda la fine:

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

Uno stream completo termina con un frammento che contiene "finish_reason":"stop" seguito da data: [DONE]. Se l'ultima riga è un normale frammento di contenuto, lo stream è stato tagliato.

Come risolvere

  1. Verifica il marcatore di fineRegistra se hai visto [DONE] o un frammento con un finish_reason non nullo. Senza nessuno dei due, considera il risultato fallito, non breve. È l'unica modifica che rende visibile il problema.
  2. Mantieni viva la connessione durante le pause lungheSe un intermediario chiude per inattività, i commenti heartbeat nello stream SSE lo impediscono. I provider che li inviano rendono i modelli di ragionamento molto più affidabili sullo stesso percorso di rete.
  3. Non ritentare alla cieca dall'inizioUno stream interrotto ha già addebitato i token che ha prodotto. Ritentare l'intero prompt raddoppia il costo. Dove la risposta si può suddividere, riprendi; dove non si può, registra almeno la parte ricevuta così che la spesa sia contabilizzata.
  4. Testa con una generazione volutamente lenta e lungaI prompt brevi nascondono completamente il problema. Chiedi qualcosa che richieda un minuto per essere prodotto e saprai al primo tentativo se il tuo percorso è stabile.
APICLAN inoltra lo stream dell'upstream senza bufferizzarlo, quindi finish_reason e [DONE] arrivano esattamente come li ha inviati il provider. La configurazione di ogni client è nella guida rapida.

Articoli correlati

Unexpected token '<' quando chiami un'API compatibile con OpenAI401 invalid API key: quando la chiave sembra giusta ma continua a fallire

Ultima verifica: 2026-10-01. Scritto a partire da problemi diagnosticati su un gateway compatibile con OpenAI in produzione, non raccolto da altri siti.