[vercel/ai-chatbot] AI chatbot 프론트엔드는 어떤 구조로 이루어졌나

이진우·2025년 5월 6일
0

AI 챗봇을 직접 구축해보기 위해서, Vercel에서 제공하는 ai-chatbot 템플릿 v3.0.19을 활용해보았습니다. 해당 템플릿은 Next.js를 기반으로 하고 있으며, vercel의 ai-sdk를 사용하기 때문에 OpenAI, Google gemini등 다양한 API를 연동하여 기본적인 대화형 챗봇 기능을 구현할 수 있습니다.

ai-chatbot 의 구조 분석

ai-chatbot 은 보편적으로 사용되는 UI와 기능들을 갖추고 있습니다.

  • 로그인 및 회원가입
  • 메시지 입력 후 챗봇 답변 받기
  • LLM 모델 선택
  • 각 채팅 별 세션 분리
  • 입력한 메시지 수정 기능
  • 여러 Tool 제공
    • 날씨 조회
    • 문서(document) 작성 기능
  • Artifact 기능
    • 문서(document) 작성
      • Text kind
      • Code kind
      • Sheet kind
      • Image kind

구조 분석

ai-chatbot-architecture

Next app 라우터로 auth 그룹과 chat 그룹을 Route group으로 나눠놨습니다.
chat 그룹에는 챗봇 기능에 대한 컴포넌트들이 모여있습니다. Chat이라는 컴포넌트가 챗봇 기능을 담당하는 핵심적인 컴포넌트입니다. 구조는 다음과 같습니다:

Page 컴포넌트 분석

역할

Page 컴포넌트는 서버 사이드 페이지 컴포넌트로, 특정 채팅 ID에 해당하는 채팅 데이터를 가져와 클라이언트 컴포넌트인 ChatDataStreamHandler를 렌더링합니다. 인증, 권한 확인, 데이터 조회 및 변환을 처리합니다.

주요 기능

  1. 파라미터 처리
  2. 데이터 조회
    • getChatById(id): DB에서 채팅 데이터를 조회.
    • getMessagesByChatId(id): 해당 채팅의 메시지 목록을 조회.
    • 조회된 채팅이 없으면 notFound()로 404 응답.
  3. 인증 및 권한 확인
    • auth()를 호출해 사용자 세션을 확인.
    • 세션이 없으면 /api/auth/guest로 리다이렉트.
    • 채팅이 private인 경우:
      • 세션에 사용자 정보가 없거나, 사용자가 채팅 소유자가 아니면 notFound() 호출.
  4. 데이터 변환
    • convertToUIMessages: DB 메시지(DBMessage)를 클라이언트용 UIMessage 포맷으로 변환.
      • id, parts, role, createdAt, experimental_attachments를 매핑.
      • content는 곧 deprecated될 예정이므로 빈 문자열로 설정.
  5. 쿠키 기반 모델 선택
    • cookies()를 사용해 chat-model 쿠키를 확인.
    • 쿠키가 없으면 DEFAULT_CHAT_MODEL을 사용.
    • 쿠키가 있으면 해당 값을 selectedChatModel로 전달.

특징

  • 서버 사이드에서 실행되며, 클라이언트로 데이터를 전달하기 전에 인증과 권한을 철저히 확인.
  • 쿠키를 활용해 사용자 선호 모델을 동적으로 반영.
  • 메시지 데이터를 클라이언트 포맷으로 변환해 Chat 컴포넌트에 전달.

Chat 컴포넌트 분석

역할

Chat 컴포넌트는 클라이언트 사이드에서 동작하는 채팅 UI 컴포넌트로, 사용자와 AI 간의 대화를 관리하고 표시합니다. @ai-sdk/reactuseChat 훅을 사용해 메시지 상태를 관리하며, 메시지 입력, 투표, 아티팩트 등을 처리합니다.

주요 기능

  1. 상태 관리
    • useChat 훅(ai-sdk 문서 참고):
      • messages, setMessages: 메시지 목록 관리.
      • input, setInput: 사용자 입력 관리.
      • handleSubmit, append: 메시지 전송 및 추가.
      • status, stop, reload: 채팅 상태 및 제어.
      • 커스텀 설정:
        • id: 채팅 ID.
        • initialMessages: 초기 메시지 목록.
        • experimental_throttle: 100ms로 요청 제한.
        • generateId: UUID 생성.
        • experimental_prepareRequestBody: 요청 본문에 id, message, selectedChatModel 포함.
        • onFinish: 채팅 완료 시 사이드바 히스토리 캐시 갱신.
        • onError: 에러 발생 시 토스트 알림 표시.
    • useState:
      • attachments: 첨부 파일 상태 관리.
    • useSWR(SWR 문서 참고):
      • /api/vote?chatId=${id}에서 투표 데이터 조회 (메시지가 2개 이상일 때).
    • useArtifactSelector: 아티팩트 표시 여부 확인.
  2. UI 구성
    • ChatHeader: 채팅 상단 바 (모델, 공개 상태, 읽기 전용 여부 표시).
    • Messages: 메시지 목록 표시 및 투표, 메시지 수정, 리로드 기능.
    • MultimodalInput: 텍스트 및 첨부 파일 입력 폼 (읽기 전용이 아닌 경우 표시).
    • Artifact: 추가 콘텐츠 (예: 이미지, 파일) 표시 및 관리.
  3. 이벤트 처리
    • 메시지 전송: handleSubmit 또는 append 호출.
    • 입력 중단: stop 호출.
    • 메시지 리로드: reload 호출.
    • 첨부 파일 관리: setAttachments로 상태 업데이트.
    • 캐시 갱신: mutate로 사이드바 채팅 히스토리 갱신.

특징

  • 클라이언트 사이드에서 동작하며, 실시간 메시지 및 첨부 파일 관리.
  • useChat 훅을 활용해 AI 대화 상태를 효율적으로 관리.
  • SWR을 사용해 투표 데이터를 비동기적으로 로드.
  • 읽기 전용 모드와 아티팩트 표시 여부를 동적으로 처리.
  • 에러 핸들링 및 사용자 피드백(토스트) 제공.

요약 비교

  • Page: 서버 사이드에서 데이터 조회, 인증, 권한 확인, 데이터 변환을 처리하며 Chat 컴포넌트에 필요한 데이터를 준비.
  • Chat: 클라이언트 사이드에서 사용자 인터랙션과 UI 렌더링을 담당하며, AI 대화와 실시간 상태를 관리.
  • 연결점: PageChatinitialMessages, selectedChatModel, session 등을 전달해 초기 상태를 설정.
profile
언젠가 보게 된다. 기록하자 😡🔥🔥

0개의 댓글