콘텐츠로 이동

스트리밍 (Streaming)

LLM답변은 한 번에 오지 않아요. 모델이 토큰을 만들면서 차례대로 내려오죠. 이 스트리밍을 우리 제품에서 제대로 다루면, 사용자는 "기다리는 시간"이 아니라 "채워지는 화면"을 보게 됩니다. Vercel AI SDK는 그 스트리밍을 서버와 클라이언트 어디서 다룰지, 상태를 어떻게 관리할지까지 묶어서 제공합니다. 이 페이지는 소스 문서 AI SDK UI 를 바탕으로, 스트리밍 응답을 실제 UI로 흘려보내는 방법을 설명합니다.


개요

LLM 호출을 그냥 fetch로 받으면 응답 전체 도착까지 화면이 멈춘 것처럼 보여요. 그런데 답변이 토큰 단위로 도착하는 걸 그대로 표시하면, 생성이 끝나기도 전에 사용자에게 결과가 보이기 시작합니다. 느리게 느껴지는 모델도 이렇게 하면 반응이 빠른 것처럼 체감됩니다. 스트리밍은 단순한 UX 개선이 아니라 LLM 제품의 기본 동작이에요. AI SDK는 이 왕복(round-trip)과 상태 관리를 훅 하나로 다뤄줍니다.


핵심 개념

서버와 클라이언트의 역할 나누기

스트리밍은 두 쪽으로 나뉩니다. 서버는 streamText로 토큰 스트림을 만들고, 클라이언트는 useChat 훅이 그 스트림을 받아 실시간으로 렌더링합니다. 서버 쪽 라우트는 streamText 결과를 toUIMessageStreamResponse()로 돌려주고, 브라우저 쪽 훅은 메시지 도착을 기다리지 않고 입력을 비우고 응답이 채워지는 걸 보여줘요.

useChat이 관리하는 상태

useChat은 입력·메시지·상태·에러를 한꺼번에 다룹니다. 특히 status 값이 핵심인데, 네 가지로 나뉘어요.

  • submitted — 메시지를 API로 보내고 응답 스트림 시작을 기다리는 중
  • streaming — 응답이 스트림으로 들어오는 중
  • ready — 응답을 끝까지 받고 처리 완료, 새 메시지를 보낼 수 있음
  • error — API 요청 중 에러 발생

이 상태로 로딩 스피너를 보여주거나, "중지" 버튼을 만들거나, 제출 버튼을 비활성화할 수 있어요. sendMessage로 보내면 훅이 자동으로 대화 흐름과 상태를 이어갑니다.

메시지 파트(parts)로 렌더링하기

AI SDK UI의 메시지는 content 대신 parts라는 배열 속성을 권장합니다. 텍스트뿐 아니라 도구 호출(tool invocation), 도구 결과(tool result) 같은 여러 종류의 파트를 담을 수 있어서, 채팅 UI를 더 유연하게 만들 수 있어요. 예를 들어 도구가 그린 요소와 텍스트를 한 메시지에서 섞어 보여줄 때 이 구조가 필요합니다.

stop과 에러 처리

statussubmittedstreaming일 때 stop()을 호출하면 현재 응답을 중단할 수 있어요. error가 나면 regenerate()로 다시 시도할 수 있고, 이때 에러 내용을 그대로 보여주기보다 "문제가 발생했어요" 같은 일반 메시지로 감추는 게 좋습니다. 서버 내부 정보가 사용자에게 새는 것을 막아주거든요.


실제 적용 (데이터스케쳐스)

  • 캔버스 다이어그램 생성 — 모델이 요소를 만들 때 스트리밍으로 그리면, 사용자가 답변 완료를 기다리지 않고 다이어그램이 채워지는 과정을 봅니다. 생성이 길어도 "일하는 중"이라는 인상을 줘요.
  • 웹빌더 콘텐츠 — 사이트 문구가 타이핑처럼 흘러 들어오게 해서, 생성 대기가 아니라 진행 중인 느낌을 만듭니다.
  • 이벤트 NLG 리포트 — 긴 리포트도 토큰 단위로 내려와서, 사용자가 첫 문장부터 바로 읽을 수 있어요.
  • 도구 호출 진행 시각화parts 렌더링으로 모델이 도구를 부르고 결과를 받는 중간 과정을 UI에서 보여줄 수 있습니다.

AI SDK의 스트리밍을 쓰면 "도착하는 토큰을 어떻게 받고, 상태를 어떻게 갱신하고, 중단을 어떻게 처리할지"를 매번 새로 구현하지 않아도 됩니다.


더 알아보기