AI 챗봇을 직접 구축해보기 위해서, Vercel에서 제공하는 ai-chatbot 템플릿 v3.0.19을 활용해보았습니다. 해당 템플릿은 Next.js를 기반으로 하고 있으며, vercel의 ai-sdk를 사용하기 때문에 OpenAI, Google gemini등 다양한 API를 연동하여 기본적인 대화형 챗봇 기능을 구현할 수 있습니다.
ai-chatbot 은 보편적으로 사용되는 UI와 기능들을 갖추고 있습니다.
Next app 라우터로 auth 그룹과 chat 그룹을 Route group으로 나눠놨습니다.
chat 그룹에는 챗봇 기능에 대한 컴포넌트들이 모여있습니다. Chat이라는 컴포넌트가 챗봇 기능을 담당하는 핵심적인 컴포넌트입니다. 구조는 다음과 같습니다:
Page
컴포넌트는 서버 사이드 페이지 컴포넌트로, 특정 채팅 ID에 해당하는 채팅 데이터를 가져와 클라이언트 컴포넌트인 Chat
과 DataStreamHandler
를 렌더링합니다. 인증, 권한 확인, 데이터 조회 및 변환을 처리합니다.
props.params.id
를 통해 동적 라우트에서 채팅 ID를 추출. (Next.js Dynamic route 참고)getChatById(id)
: DB에서 채팅 데이터를 조회.getMessagesByChatId(id)
: 해당 채팅의 메시지 목록을 조회.notFound()
로 404 응답.auth()
를 호출해 사용자 세션을 확인./api/auth/guest
로 리다이렉트.private
인 경우:notFound()
호출.convertToUIMessages
: DB 메시지(DBMessage
)를 클라이언트용 UIMessage
포맷으로 변환.id
, parts
, role
, createdAt
, experimental_attachments
를 매핑.content
는 곧 deprecated될 예정이므로 빈 문자열로 설정.cookies()
를 사용해 chat-model
쿠키를 확인.DEFAULT_CHAT_MODEL
을 사용.selectedChatModel
로 전달.Chat
컴포넌트에 전달.Chat
컴포넌트는 클라이언트 사이드에서 동작하는 채팅 UI 컴포넌트로, 사용자와 AI 간의 대화를 관리하고 표시합니다. @ai-sdk/react
의 useChat
훅을 사용해 메시지 상태를 관리하며, 메시지 입력, 투표, 아티팩트 등을 처리합니다.
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
: 아티팩트 표시 여부 확인.ChatHeader
: 채팅 상단 바 (모델, 공개 상태, 읽기 전용 여부 표시).Messages
: 메시지 목록 표시 및 투표, 메시지 수정, 리로드 기능.MultimodalInput
: 텍스트 및 첨부 파일 입력 폼 (읽기 전용이 아닌 경우 표시).Artifact
: 추가 콘텐츠 (예: 이미지, 파일) 표시 및 관리.handleSubmit
또는 append
호출.stop
호출.reload
호출.setAttachments
로 상태 업데이트.mutate
로 사이드바 채팅 히스토리 갱신.useChat
훅을 활용해 AI 대화 상태를 효율적으로 관리.Chat
컴포넌트에 필요한 데이터를 준비.Page
가 Chat
에 initialMessages
, selectedChatModel
, session
등을 전달해 초기 상태를 설정.