SSE를 이용한 LLM 응답 스트리밍: 60줄로 실시간 AI 채팅 UI 구축하기
요약
Server-Sent Events(SSE)를 활용하여 LLM의 실시간 토큰 스트리밍 UI를 구축하는 방법을 설명합니다. 프론트엔드와 백엔드를 포함한 최소한의 코드로 사용자 경험을 개선하는 실무적인 가이드를 제공합니다.
핵심 포인트
- SSE를 사용하여 LLM 응답의 첫 토큰 도달 시간(TTFT)을 단축하고 UX를 개선할 수 있습니다.
- Vanilla JS와 ReadableStream API를 이용해 의존성 없이 가벼운 스트리밍 구현이 가능합니다.
- 프로덕션 환경에서는 에러 핸들링, 모델 검증, 속도 제한(Rate Limiting)이 필수적입니다.
- DeepSeek 등 일부 중국산 모델은 GPT-4o 대비 낮은 TTFT와 높은 비용 효율성을 보입니다.
SSE를 이용한 LLM 응답 스트리밍: 60줄로 실시간 AI 채팅 UI 구축하기
ChatGPT를 사용해 보셨다면 보셨을 겁니다. 토큰이 단어별로 스트리밍되는 그 만족스러운 타자기 효과를 말이죠. 그 이면에는 현대적인 AI 인터페이스를 구동하는 가장 과소평가된 웹 표준 중 하나인 **Server-Sent Events (SSE)**가 있습니다.
대부분의 튜토리얼은 SSE를 신기한 기능 정도로 취급합니다. 하지만 실제 서비스되는 AI 앱에서 SSE는 필수적인 기본 요소입니다. 사용자는 모델이 500단어 분량의 응답을 생성하는 동안 스피너(spinner)를 바라보며 8초 동안 기다려주지 않습니다. 사용자들은 300ms 이내에 첫 번째 토큰을 보고 나머지 내용이 흘러나오는 것을 보고 싶어 합니다.
오늘 우리는 프론트엔드와 백엔드를 포함한 완전한 스트리밍 채팅 인터페이스를 약 60줄의 코드로 구축할 것입니다. 그리고 GPT-4o보다 비용이 90% 저렴한 실제 중국산 LLM들을 대상으로 이를 테스트해 보겠습니다.
LLM 스트리밍을 위해 WebSocket 대신 SSE를 사용하는 이유는?
코드를 작성하기 전에 이 문제를 정리해 봅시다. 개발자들은
우리가 엔드포인트로 https://aiwave.live/v1/chat/completions를 사용하고 있다는 점에 주목하세요. 이는 DeepSeek, GLM-5, Qwen, ERNIE를 포함한 50개 이상의 중국 AI 모델에 대한 접근을 단일 API를 통해 제공하는 OpenAI 호환 게이트웨이입니다. 이미 OpenAI SDK를 사용 중이라면, baseURL만 변경하면 바로 완료됩니다.
프론트엔드: 35줄의 Vanilla JS
React도 없고, 빌드 단계도 없으며, 의존성도 없습니다. 오직 HTML 파일 하나뿐입니다:
<!DOCTYPE html>
<html>
<body>
...
단 35줄의 프론트엔드 코드입니다. 브라우저의 네이티브 ReadableStream API가 SSE 파싱을 처리합니다. 각 청크(chunk)는 디코딩되고 JSON으로 파싱되며, delta.content 토큰이 화면에 표시되는 텍스트에 추가됩니다.
프로덕션 환경을 위한 준비
위의 최소 기능 버전도 작동하지만, 실제 프로덕션 환경에서는 몇 가지 추가 사항이 필요합니다:
1. 에러 핸들링 (Error Handling)
app.post('/api/chat', async (req, res) => {
try {
// ... 스트리밍 로직
...
2. 요청 검증 (Request Validation)
항상 허용 목록(allowlist)을 기준으로 모델 이름을 검증하세요. 사용자 입력을 API 제공업체에 직접 전달해서는 안 됩니다:
const ALLOWED_MODELS = ['deepseek-chat', 'glm-5', 'qwen-max', 'ernie-4.0-turbo'];
if (!ALLOWED_MODELS.includes(req.body.model)) {
...
3. 속도 제한 (Rate Limiting)
LLM 스트리밍 요청은 연결 유지 시간이 긴(long-lived) 연결입니다. 단 한 명의 사용자가 연결 풀(connection pool)을 빠르게 고갈시킬 수 있습니다:
const activeStreams = new Map();
app.post('/api/chat', async (req, res) => {
...
중국 모델이 스트리밍에 완벽한 이유
대부분의 개발자가 깨닫지 못하는 사실이 하나 있습니다. 중국의 LLM은 단순히 더 저렴할 뿐만 아니라, 서구권의 대안 모델들보다 **첫 번째 토큰 생성 시간 (TTFT, Time-to-First-Token)**이 더 낮은 경우가 많습니다. GPT-4o가 약 600ms인 것에 비해, DeepSeek V4 Pro는 약 200ms 만에 첫 토큰을 전달합니다.
스트리밍 UX를 위해서는 전체 생성 시간보다 TTFT (Time To First Token)가 더 중요합니다. 전체 생성에 5초 이상이 걸리더라도 첫 번째 토큰이 빠르게 나타나면 사용자는 응답이 "빠르다"고 인식합니다. 그렇기 때문에 aiwave.live와 같은 서비스를 통해 스트리밍 엔드포인트를 라우팅하는 것이 비용과 지연 시간(latency) 측면 모두에서 이점을 제공합니다. 이 서비스는 하나의 API를 통해 모든 주요 중국 모델을 제공하며 5달러의 무료 크레딧을 제공합니다.
빠른 비교: 모델별 TTFT
| 모델 | TTFT (평균) | 1M 토큰당 비용 |
|---|---|---|
| GPT-4o | ~600ms | $2.50 |
| ... |
지연 시간의 차이는 스트리밍 UI에서 즉각적으로 체감됩니다. 직접 테스트해 보세요. 동일한 프롬프트를 입력했을 때, DeepSeek가 GPT-4o보다 눈에 띄게 더 빠르게 타이핑을 시작할 것입니다.
종합 정리
전체 아키텍처는 다음과 같습니다:
브라우저 (Browser) → ReadableStream을 사용한 fetch()
↓ SSE
사용자 서버 (Express)
...
이 아키텍처의 묘미는 단순함에 있습니다. WebSocket 라이브러리, socket.io, SignalR 등이 필요 없습니다. 그저 text/event-stream 콘텐츠 타입(content type)을 가진 HTTP 응답만 있으면 되며, 나머지는 브라우저가 모두 처리합니다.
핵심 요약
- LLM 스트리밍에는 SSE가 WebSocket보다 우수함 — 더 단순하고, 자동 재연결이 가능하며, 프록시(proxy) 친화적입니다.
- 60줄로 작동하는 채팅 UI 구현 가능 — 빌드 단계가 필요 없는 바닐라 JS (vanilla JS)만으로 충분합니다.
- 스트리밍 UX에서는 TTFT > 전체 지연 시간 — 이 부분에서 중국 모델들이 우세합니다.
- 항상 검증 및 속도 제한(rate-limit) 실시 — 스트리밍 엔드포인트는 비용이 많이 듭니다.
- OpenAI 호환 API를 사용하면 전환이 매우 쉬움 — baseURL만 변경하면 됩니다.
실제 중국 AI 모델로 이를 테스트해보고 싶다면, aiwave.live에 가입하여 5달러의 무료 크레딧을 받으세요. 약 250만 토큰을 실험해 볼 수 있는 충분한 양입니다. API가 OpenAI와 완전히 호환되므로 위의 코드를 수정 없이 그대로 사용할 수 있습니다.
즐거운 스트리밍 되세요! 🚀
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기