SSE로 AI 지연 시간(Latency) 잡기

AI 자동 완성 기능을 개발했습니다. 사용자들은 싫어했습니다.

키를 누를 때마다 AI 요청이 발생했습니다. 사용자는 전체 JSON 응답을 받기 위해 2~3초를 기다려야 했습니다. UI는 먹통인 것처럼 느껴졌습니다. 디바운싱(debouncing)과 캐싱(caching)을 시도해 보았지만, 아무것도 효과가 없었습니다. 핵심 문제는 그대로였습니다. 전체 답변이 도착할 때까지 사용자는 아무것도 볼 수 없었습니다.

저는 Server-Sent Events(SSE)를 사용하여 응답을 조각 단위로 스트리밍함으로써 이 문제를 해결했습니다.

기존 흐름은 다음과 같았습니다:

  • 사용자 입력
  • 300ms 디바운싱
  • HTTP POST 요청
  • AI 처리 (1~2초)
  • 서버가 전체 응답 반환
  • 클라이언트 렌더링

사용자는 몇 초 동안 빈 화면을 보아야 했습니다. 로딩 스피너가 있어도 느리게 느껴졌습니다.

폴링(polling)이나 WebSockets를 고려했습니다. 폴링은 오버헤드가 너무 큽니다. WebSockets는 단방향 스트리밍에는 너무 무겁습니다.

제가 SSE를 선택한 이유는 다음과 같습니다:

  • 서버에서 클라이언트로의 단방향 통신이 가능합니다
  • 단순한 텍스트와 JSON 청크(chunks)를 사용합니다
  • 연결이 끊기면 자동으로 재연결됩니다
  • 서버에 추가 라이브러리가 필요하지 않습니다

결과는 모든 것을 바꾸어 놓았습니다:

  • 첫 시각적 응답 시간: 2.1초에서 0.3초로 단축
  • 사용자 참여도: 40% 증가
  • 사용자 불만: 0건

스트리밍은 인지의 문제입니다. 점진적인(progressive) UI는 정적인 UI보다 더 빠르게 느껴집니다. 사용자는 텍스트 덩어리가 나타날 때까지 기다리는 것보다 단어가 하나씩 나타나는 것을 선호합니다.

AI 응답이 매우 짧다면 기존의 표준 요청 방식을 유지하세요. 양방향 통신이 필요하다면 WebSockets를 사용하세요. 하지만 대부분의 AI 스트리밍 요구 사항에는 SSE가 최선의 선택입니다.

여러분의 앱에서는 AI 지연 시간을 어떻게 처리하고 계신가요? 스트리밍을 사용하시나요, 아니면 전체 응답을 기다리시나요?

출처: https://dev.to/__c1b9e06dc90a7e0a676b/taming-ai-latency-streaming-responses-with-server-sent-events-42d5