LLM 응답 스트리밍 구현 기술
- •스트리밍은 토큰을 즉각 표시해 전체 응답 완료를 기다릴 필요 없이 체감 성능을 향상시킨다.
- •서버와 지속적인 HTTP 연결을 유지하고 데이터를 점진적으로 전송하는 SSE 표준을 활용한다.
- •개발자는 무응답 중단, 유령 연결, 패킷 파편화 등 스트리밍 특유의 오류를 안정적으로 처리해야 한다.
스트리밍은 LLM이 생성하는 토큰을 즉시 화면에 표시함으로써 응답 대기 시간을 줄여 사용자 경험을 개선한다. 전체 생성 시간은 일반 요청과 동일하지만, "stream": true 플래그를 설정하면 약 300밀리초 내에 출력 렌더링을 시작할 수 있다. 이 방식은 웹 표준인 Server-Sent Events(SSE)를 활용해 지속적인 HTTP 연결을 유지하며, 모델이 생성하는 데이터를 클라이언트로 실시간 전송한다. 전송 과정에서 텍스트는 content_block_delta 이벤트 내 delta.text로 전달되며, 최종 완료 신호는 message_delta 이벤트의 stop_reason을 통해 확인한다.
스트림을 읽으려면 응답 본문의 ReadableStream을 반복하고 들어오는 바이트를 버퍼링하여 줄바꿈 문자를 기준으로 개별 SSE 메시지를 분리해야 한다. 네트워크 환경에 따라 토큰이 패킷으로 묶이는 방식이 달라지므로, 개발자는 불완전한 데이터를 버퍼링하여 파싱하는 과정을 거쳐야 한다. 또한 도구 인자나 검증 서명 같은 불필요한 메타데이터를 제외하고 text_delta와 같은 실제 콘텐츠 유형을 정확히 식별하는 작업이 필수적이다.
안정적인 스트리밍 구현을 위해 세 가지 문제를 해결해야 한다. 첫째, 페이지 이동 시 연결이 종료되지 않는 유령 스트림을 방지하기 위해 AbortController를 사용하여 요청을 명시적으로 취소해야 한다. 둘째, 스트림 도중 API 오류가 발생할 경우 데이터 타입 체크를 통해 오류를 인지하고 무시되지 않도록 처리해야 한다. 셋째, 조각난 패킷은 파싱 전 버퍼링으로 해결한다. 마지막으로, end_turn, max_tokens 등 stop_reason을 모니터링하여 모델의 응답이 정상 완료되었는지, 혹은 토큰 제한으로 중단되었는지 정확히 파악해야 한다.