더 나은 Agent UX 구축: 스트리밍 진행, 상태 및 파일 작업 with LangChain

발행: (2026년 1월 16일 오전 03:38 GMT+9)
3 min read
원문: Dev.to

Source: Dev.to

What you’ll build

간단한 패턴:

  1. 도구가 이벤트를 발생시킴 (진행 상황/상태/파일 작업) while it runs
  2. 프론트엔드가 구독하고 즉시 해당 이벤트를 렌더링
  3. 타입 가드가 UI 로직을 안전하고 예측 가능하게 유지

폴링 루프 없음. 추측 없음. “생각 중…” 같은 플레이스홀더도 없음.

1) Emit typed custom events from a tool call

도구 호출 내부에서 작업이 진행되는 동안 커스텀 이벤트를 작성합니다:

config.writer?.({
  type: "progress",
  id: analysisId,          // stable id => update in place
  step: steps[i].step,
  message: steps[i].message,
  progress: Math.round(((i + 1) / steps.length) * 100),
  totalSteps: steps.length,
  currentStep: i + 1,
  toolCall: config.toolCall,
} satisfies ProgressData);

이것이 핵심 전환점입니다: 도구는 단순한 함수가 아니라 이벤트 생산자입니다.

2) Receive those events in React

UI에서 스트림 훅에 핸들러를 전달합니다:

onCustomEvent: handleCustomEvent,

이제 도구가 발생시킨 모든 이벤트가 실시간으로 클라이언트에 도착합니다.

3) Narrow event types and update UI state predictably

들어오는 이벤트를 unknown으로 취급한 뒤 타입 가드로 좁히고 id를 키로 하는 상태 맵을 업데이트합니다:

if (isProgressData(data)) {
  /* update progress */
} else if (isStatusData(data)) {
  /* update status */
} else if (isFileStatusData(data)) {
  /* update file ops */
}

이렇게 하면 프론트엔드가 안정적으로 유지됩니다:

  • 진행 상황이 제자리에서 업데이트
  • 최소한의 재렌더링
  • 문자열 기반 이벤트 스파게티 방지

Why it matters (beyond “nice UI”)

UI가 실제 실행을 반영할 때:

  • 사용자는 에이전트를 더 신뢰하게 됨
  • 디버깅이 크게 쉬워짐
  • 로그를 파헤치지 않아도 실패 원인을 이해할 수 있음
  • 더 나은 UX를 만들 수 있음: 단계 표시기, 타임라인, 파일 작업 피드 등

🎥 Video:

Back to Blog

관련 글

더 보기 »

기술은 구원자가 아니라 촉진자다

왜 사고의 명확성이 사용하는 도구보다 더 중요한가? Technology는 종종 마법 스위치처럼 취급된다—켜기만 하면 모든 것이 개선된다. 새로운 software, ...

에이전틱 코딩에 입문하기

Copilot Agent와의 경험 나는 주로 GitHub Copilot을 사용해 인라인 편집과 PR 리뷰를 수행했으며, 대부분의 사고는 내 머리로 했습니다. 최근 나는 t...