Strona główna → Pomoc

Odpowiedź strumieniowa urywa się w połowie zdania

Prawidłowy strumień kończy się jawnym znacznikiem – fragmentem z finish_reason, a potem data: [DONE]. Jeśli twój ostatni fragment nie ma ani jednego, ani drugiego, połączenie zostało zerwane, a odpowiedź jest niepełna. Status HTTP ci tego nie powie, bo został wysłany, zanim zaczęła się treść.

Co widzisz

Dlaczego tak się dzieje

Odpowiedzi strumieniowe zobowiązują się do 200 OK, gdy tylko wyjdzie pierwszy bajt. Wszystko później to treść. Jeśli połączenie padnie na tokenie 900 z 1200, klient widział już linię statusu z sukcesem i nie zgłosi błędu, chyba że akurat sprawdza znacznik końca samego strumienia.

Dlatego ten błąd wydaje się losowy. Krótkie odpowiedzi mieszczą się w oknie, na jakie pozwala najsłabsze ogniwo; długie – nie. Miejsce urwania się przesuwa, bo zależy od czasu, a nie od treści.

Najczęstszą przyczyną są limity bezczynności w proxy, które szczególnie źle współgrają z modelami rozumującymi: w długiej fazie rozumowania nie jest emitowany żaden token, więc pośrednik mierzący ciszę zamiast łącznego czasu może uznać połączenie za martwe, choć model wciąż myśli.

Sprawdź, czy to ta przyczyna

Czytaj surowy strumień zamiast sparsowanego obiektu z SDK i spójrz na jego koniec:

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

Kompletny strumień kończy się fragmentem zawierającym "finish_reason":"stop", po którym następuje data: [DONE]. Jeśli ostatnia linia to zwykły fragment treści, strumień został ucięty.

Jak to naprawić

  1. Sprawdzaj znacznik końcaZapamiętuj, czy pojawiło się [DONE] albo fragment z niepustym finish_reason. Bez żadnego z nich traktuj wynik jako nieudany, a nie krótki. Ta jedna zmiana sprawia, że problem staje się widoczny.
  2. Utrzymuj połączenie przy życiu podczas długich przerwJeśli pośrednik zamyka połączenia z powodu bezczynności, zapobiegają temu komentarze heartbeat w strumieniu SSE. Dostawcy, którzy je wysyłają, sprawiają, że modele rozumujące działają znacznie stabilniej na tej samej trasie sieciowej.
  3. Nie ponawiaj na ślepo od początkuZerwany strumień już naliczył wygenerowane tokeny. Ponowienie całego promptu podwaja koszt. Gdzie odpowiedź da się dzielić – wznów; gdzie nie – przynajmniej zaloguj fragment, żeby wydatek był rozliczony.
  4. Testuj celowo wolnym, długim generowaniemKrótkie prompty całkowicie to ukrywają. Poproś o coś, czego wygenerowanie zajmie minutę, a po jednej próbie będziesz wiedzieć, czy twoja trasa jest stabilna.
APICLAN przekazuje strumień z upstreamu bez buforowania, więc finish_reason i [DONE] docierają dokładnie tak, jak wysłał je dostawca. Konfiguracja każdego klienta jest w szybkim starcie.

Powiązane

Unexpected token '<' przy wywołaniu API zgodnego z OpenAI401 invalid API key – gdy klucz wygląda dobrze, a i tak nie działa

Ostatnio sprawdzono 2026-10-01. Napisane na podstawie problemów zdiagnozowanych na działającej bramce zgodnej z OpenAI, a nie zebrane z innych stron.