Jak przesyłać odpowiedzi LLM strumieniowo za pomocą SSE i fragmentów z danymi o zużyciu
Tłumaczenie automatyczne
Ten artykuł został automatycznie przetłumaczony z angielskiego oryginału.
Aby przesyłać odpowiedź LLM strumieniowo, parsuj protokół zdarzeń serwera, składaj delty treści i aktualizuj ekran, gdy dociera tekst nadający się do wyświetlenia. Wiele interfejsów API korzysta z Server-Sent Events, czyli SSE. Jeden odczyt HTTP może zawierać część zdarzenia lub kilka zdarzeń. Zdarzenie może zawierać wiele tokenów modelu.
Implementacje klienta potrzebują buforowania i obsługi zakończenia, a także szybkiej pierwszej aktualizacji.
Parsuj zdarzenia przed danymi modelu
Format SSE używa wierszy takich jak data: i kończy zdarzenie pustym wierszem. Odczyty sieciowe mogą dzielić te wiersze lub łączyć kilka zdarzeń. Buforuj niekompletny tekst, rozpoznawaj kompletne zdarzenia, a następnie parsuj dane zgodnie z formatem konkretnego API. Wiele wierszy data: należy do jednego zdarzenia.
W OpenAI Chat Completions treść dociera jako delty, które klient składa w wiadomość. Obsługuj delty wywołań narzędzi lub delty strukturalne zgodnie z ich polami, zamiast traktować każde zdarzenie jak zwykły tekst. Znacznik [DONE] jest konwencją API, a nie ogólnym wymaganiem SSE.
Przydatna kolejność przetwarzania po stronie klienta:
- Dekoduj przychodzące bajty bez utraty znaku UTF-8 podzielonego między odczyty.
- Buforuj dane do uzyskania kompletnego zdarzenia SSE.
- Interpretuj zdarzenie według schematu wybranego API.
- Dodaj treść lub pola strukturalne do składanej odpowiedzi.
- Zaktualizuj ekran przy odpowiedniej granicy buforowania.
Oddziel wyświetlanie, zakończenie i zużycie
Wyświetlaj zwykły tekst jak najszybciej, gdy to możliwe. Buforuj niekompletne konstrukcje Markdown lub wiersze kodu, jeśli natychmiastowe formatowanie powoduje powtarzające się zmiany układu. Rejestruj początek żądania i pierwszą wygenerowaną treść oddzielnie od otwarcia połączenia lub zdarzenia zawierającego tylko metadane.
W Chat API OpenAI ustawienie stream_options: {"include_usage": true} żąda końcowego fragmentu z danymi o zużyciu przed [DONE]. Ten fragment ma pustą tablicę wyborów. Przerwane lub anulowane strumienie mogą nigdy go nie dostarczyć, dlatego braku danych o zużyciu nie można interpretować jako zera tokenów.
Serwery zgodne z OpenAI mogą implementować inne formaty danych lub inaczej obsługiwać zakończenie. Testuj fragmentację zdarzeń, wiele zdarzeń w jednym odczycie, puste delty, anulowanie, błędy serwera i brak końcowych danych o zużyciu na implementacji o ustalonej wersji. Zachowuj już otrzymany tekst i odróżniaj niekompletną odpowiedź od pomyślnego zakończenia.
Przewodnik inżynierski: przesyłanie strumieniowe w praktyce łączy zachowanie klienta z TTFT, TPOT i planowaniem fazy prefill.