Opanowanie opóźnień AI za pomocą SSE
Stworzyłem funkcję autouzupełniania AI. Użytkownicy jej nienawidzili.
Każde naciśnięcie klawisza wyzwalało zapytanie do AI. Użytkownicy czekali od 2 do 3 sekund na pełną odpowiedź w formacie JSON. Interfejs użytkownika (UI) sprawiał wrażenie zepsutego. Próbowałem debouncingu i cachowania. Nic nie działało. Główny problem pozostał ten sam: użytkownicy nie widzieli nic, dopóki nie dotarła cała odpowiedź.
Rozwiązałem to, używając Server-Sent Events (SSE), aby przesyłać odpowiedzi strumieniowo, kawałek po kawałku.
Stary przepływ wyglądał następująco:
- Użytkownik pisze
- Debounce 300 ms
- Zapytanie HTTP POST
- AI przetwarza (1-2 sekundy)
- Serwer zwraca pełną odpowiedź
- Klient renderuje
Użytkownicy przez kilka sekund widzieli pusty ekran. Nawet z animacją ładowania (loading spinner), wszystko wydawało się wolne.
Rozważałem polling lub WebSockets. Polling generuje zbyt duży narzut. WebSockets są zbyt ciężkie dla jednostronnego strumienia danych.
Wybrałem SSE, ponieważ:
- Działa jednostronnie od serwera do klienta
- Wykorzystuje proste tekstowe fragmenty i bloki JSON
- Automatycznie nawiązuje połączenie, jeśli zostanie przerwane
- Nie wymaga dodatkowych bibliotek na serwerze
Wyniki zmieniły wszystko:
- Czas do pierwszej odpowiedzi wizualnej: spadek z 2,1 s do 0,3 s
- Zaangażowanie użytkowników: wzrost o 40%
- Skargi użytkowników: zero
Strumieniowanie to kwestia percepcji. Progresywny interfejs wydaje się szybszy niż statyczny. Użytkownicy wolą widzieć, jak słowa pojawiają się jedno po drugim, zamiast czekać na cały blok tekstu.
Jeśli odpowiedzi AI są bardzo krótkie, pozostań przy standardowych zapytaniach. Jeśli potrzebujesz dwukierunkowej komunikacji, użyj WebSockets. Jednak w większości przypadków związanych ze strumieniowaniem AI, SSE jest najlepszym wyborem.
Jak radzicie sobie z opóźnieniami AI w swoich aplikacjach? Strumieniujecie dane czy czekacie na pełne odpowiedzi?