LLM 객체를 React 필드별로 스트리밍하는 방법 (하나의 훅으로)
요약
LLM이 생성하는 JSON 객체를 React 컴포넌트의 필드별로 스트리밍하여 UI에 표시하는 방법을 소개합니다. `trickle-react` 훅은 부분적인 JSON 파싱을 처리하며, `useSyncExternalStore`를 사용하여 React 동시성 환경에서도 안전하게 작동합니다. 이 솔루션은 `sse-wire`, `trickle-json`, `coerce-json` 등 여러 독립적인 패키지를 조합하여 스트리밍 구조화 출력 파이프라인의 각 단계를 해결합니다.
핵심 포인트
- LLM JSON 스트리밍을 위한 전용 훅(`useStreamingObject`) 제공
- 부분적 JSON 파싱 및 상태 관리를 위해 `trickle-json` 사용
- React 동시성 환경에 안전한 구조로 설계됨 (useSyncExternalStore)
- 스트림 처리 과정이 여러 독립적인 패키지로 분리되어 재사용성이 높음
모델에게 JSON 객체를 요청하고 stream: true를 설정하여 UI가 도착하는 대로 채워지게 할 수 있습니다. 이제 일반적인 복잡한 상황에 놓이게 됩니다:
useEffect(() => {
const ctrl = new AbortController();
(async () => {
...
JSON.parse는 마지막 토큰까지 오류를 발생시키므로, 어떤 필드가 완료되었는지 알 수 없고, 주의하지 않으면 스트림을 찢거나 누수시킬 수 있습니다. 이를 수정해 보겠습니다.
하나의 훅 (One hook)
import { z } from "zod";
import { sse } from "sse-wire";
import { useStreamingObject, openAIContent } from "trickle-react";
...
data: 청크마다 업데이트되는DeepPartial<Profile>입니다. 오류를 발생시키지 않습니다.status.city:city가 완전히 도착했을 때만true로 바뀝니다 (단순히 나타나는 것만은 아님).done: 끝날 때 플립되며, 마운트 해제되거나deps가 변경되면 스트림이 자동으로 중지됩니다.
내부적으로는 useSyncExternalStore를 사용하므로 렌더링이 찢어짐 없이 React-18 동시성(concurrent)에 안전하며, 부분적인 JSON 파싱은 trickle-json이 처리합니다.
작은 스택의 최상단 (It's the top of a small stack)
trickle-react는 제가 만든 세 가지 다른 작고, 의존성이 없는 패키지 위에 구축된 채택 계층(adoption layer)입니다. 각각은 스트리밍 구조화 출력 파이프라인의 한 단계를 해결하며, 각자 독립적으로 유용합니다:
fetch → SSE (sse-wire) → 부분 JSON 파싱 (trickle-json) → 복구/강제 변환 (coerce-json) → 렌더링 (trickle-react)
- sse-wire — fetch 기반 SSE: POST + 헤더
EventSource가 할 수 없는 것. - trickle-json — 증분 부분 JSON 파서; 모든 청크에서 최상의 유효 값을 제공합니다.
- coerce-json — 모델의 거의 유효한 JSON을 스키마에 맞게 복구 및 강제 변환하며, 모든 수정 사항을 기록합니다.
전체 스택을 채택할 필요는 없습니다. trickle-react는 trickle-json만 필요로 합니다. 스트림이 필요하면 sse-wire를, 검증이 필요하면 coerce-json/zod를 가져오면 됩니다.
하나의 객체보다 더 많은 것 (There's more than one object)
// 스트리밍되는 행들 (rows as they stream)
const { items } = useStreamingList<Suggestion>(startStream, { path: "suggestions" });
...
사용해 보기
npm install trickle-react
- npm: https://www.npmjs.com/package/trickle-react
- GitHub: https://github.com/H1manshu01/trickle-react
react는 peer 의존성입니다. zod와 coerce-json은 선택 사항입니다. ~1.5 kB, ESM + CJS 형식이며,
완벽하게 타입 지정되었고 출처(provenance)와 함께 게시되었습니다. 만약 렌더링에 오류가 있다면,
스트림과 스키마를 포함하여 이슈를 열어주시면 감사하겠습니다. — ⭐ 수많은 useEffect 로직을 대체할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기