
Next.js, Supabase, WebSockets를 활용하여 자체 호스팅 AI 인터뷰어 구축하기
요약
Next.js, Supabase, WebSockets를 활용하여 실시간 음성·채팅·비디오 인터뷰가 가능한 오픈 소스 AI 인터뷰어 'Aural' 구축 방법을 소개합니다. 데이터 통제권을 위해 자체 호스팅이 가능한 아키텍처와 적응형 후속 질문 기능을 구현하는 데 중점을 둡니다.
핵심 포인트
- Next.js, Supabase, tRPC를 활용한 타입 안정성 확보
- 인터뷰 정의, 실시간 세션, 평가 결과의 관심사 분리 설계
- 텍스트, 오디오, 비디오를 통합 지원하는 멀티모달 인터페이스
- 데이터 보안을 위한 오픈 소스 및 자체 호스팅 아키텍처 지향
- 맥락에 따른 적응형 후속 질문 생성 기능
대부분의 인터뷰 소프트웨어는 누군가가 대화를 예약하거나, 녹화하거나, 점수를 매기는 데 도움을 줍니다. 저희가 만들고 싶었던 것은 인터뷰어 그 자체였습니다. 즉, 구조화된 인터뷰를 생성하고, 음성, 채팅 또는 비디오를 통해 진행하며, 답변이 모호할 때 후속 질문을 하고, 결과를 유용한 보고서로 변환하는 시스템이었습니다.
그 결과물이 Aural이 되었고, 저희는 이를 MIT 라이선스로 공개했습니다.

시스템이 수행해야 할 작업
유용한 AI 인터뷰어는 단순히 질문 목록 이상의 것이 필요합니다. 다음 기능을 갖추어야 합니다:
- 일반 언어의 개요를 일관된 인터뷰 구조로 변환할 수 있어야 함;
- 실시간 대화 전반에 걸쳐 상태(state)를 유지해야 함;
- 답변이 모호할 때 언제 맥락적인 후속 질문이 필요한지 결정할 수 있어야 함;
- 제품을 별도의 워크플로우로 분리하지 않고 텍스트, 오디오, 비디오를 지원해야 함;
- 사람이 검토할 수 있는 녹취록(transcripts), 증거(evidence), 점수, 요약본을 생성해야 함;
- 팀에게 데이터와 모델 제공업체에 대한 통제권을 부여해야 함.
마지막 지점이 바로 여기서 오픈 소스가 중요한 이유입니다. 인터뷰에는 이력서, 개인 정보, 녹음 파일, 평가 등이 포함될 수 있습니다. 팀은 해당 데이터가 시스템을 통해 어떻게 이동하는지 검사할 수 있어야 하며, 필요에 따라 전체 스택(stack)을 자체 인프라에서 실행할 수 있어야 합니다.
아키텍처
Aural은 Next.js 14와 App Router를 사용하여 구축된 TypeScript 애플리케이션입니다. Supabase는 PostgreSQL, 인증(authentication), 스토리지(storage), 실시간 구독(real-time subscriptions)을 제공합니다. tRPC는 클라이언트 및 서버 호출에 타입 안정성(type-safe)을 유지하며, Tailwind CSS, shadcn/ui, Radix primitives가 UI 계층을 제공합니다.
기술 인터뷰의 경우, Monaco가 코드 에디터를 구동하고 Excalidraw가 협업 화이트보드를 제공합니다.
핵심 분리는 인터뷰 정의(interview definition), 실시간 세션(live session), 그리고 평가 결과(assessment result) 사이입니다.
- **정의(definition)**는 역량, 질문, 타이밍, 모달리티 및 평가 기준을 설명합니다.
- **세션(session)**은 실시간 대화, 현재 상태, 후속 결정 및 무결성 이벤트를 기록합니다.
- **평가(assessment)**는 세션 증거를 역량별 점수, 요약, 주제 및 참여 지표로 변환합니다.
이러한 관심사들을 분리함으로써 동일한 인터뷰가 채팅, 음성 또는 비디오를 통해 진행될 수 있으며 하나의 보고 모델을 유지할 수 있습니다.
적응형 후속 질문 (Adaptive follow-ups)
스크립트화된 설문지(questionnaire)는 응답마다 진행됩니다. 면접관은 또 다른 결정을 내려야 합니다: 답변이 실제로 충분한 증거를 제공했는가?
각 응답 후에 Aural은 활성 질문 및 그 기준에 따라 답변을 평가합니다. 모델은 집중적인 후속 질문을 하거나, 모호성을 명확히 하거나, 다음 질문으로 진행할 수 있습니다. 목표는 모델이 더 많이 말하게 만드는 것이 아니라, 모든 참가자에게 동일한 대화 경로를 강요하지 않으면서 비교 가능한 증거를 수집하는 것입니다.
또한 결과 트랜스크립트와 질문 컨텍스트도 저장합니다. 이는 점수가 설명할 수 없는 숫자가 되는 대신 무엇이 질문되었고 답변되었는지에 추적 가능하게 만듭니다.
실시간 음성 및 비디오 (Real-time voice and video)
오디오와 비디오는 채팅에서는 존재하지 않는 실패 모드(failure modes)를 추가합니다: 연결 끊김, 부분 트랜스크립트, 장치 권한 오류, 침묵, 순서가 뒤바뀐 이벤트 등입니다. 우리는 지속적인 세션 상태(persistent session state)와 WebSocket 릴레이를 사용하여 인터페이스가 인터뷰의 위치를 잃지 않고 복구할 수 있도록 합니다.
UI는 트랜스크립트를 일급 아티팩트(first-class artifact)로 취급합니다. 실시간 음성 이벤트는 대화를 업데이트하지만, 내구성 있는 세션 기록은 평가 및 보고를 위한 진실의 원천(source of truth)으로 남아 있습니다.
자체 호스팅 (Self-hosting)
이 저장소에는 제한적인 커뮤니티 에디션이 아닌 전체 애플리케이션이 포함되어 있습니다. 로컬 설정은 익숙한 Next.js 워크플로우를 따릅니다: 저장소를 클론하고, .env.example을 .env.local로 복사하고, 의존성을 설치한 다음, 개발 서버를 실행합니다.
Supabase 자격 증명(credentials), 모델 제공업체 키(model-provider keys), 그리고 원하는 통합 기능들을 구성합니다. 프로덕션 옵션으로는 Docker, Vercel, 일반적인 서버 배포가 포함됩니다. Supabase는 관리형으로 사용하거나 자체 호스팅할 수 있습니다.
모델 계층은 OpenAI와 호환되는 제공업체(OpenAI-compatible providers)를 지원하므로 특정 공급업체에 종속되지 않습니다. 이는 비용 통제, 데이터 거주지(data residency), 그리고 이미 내부 모델 게이트웨이를 운영하는 팀에게 유용합니다.
포함된 기능
오픈 소스 릴리스에는 인터뷰 디자이너, 적응형 채팅/음성/비디오 세션, 자동화된 평가, 후보자 및 세션 관리, Monaco 코딩 인터뷰, Excalidraw 화이트보드, 무결성 제어(integrity controls), 다국어 지원, 조직(organizations), 프로젝트, 그리고 역할 기반 접근(role-based access)이 포함되어 있습니다.
인프라를 직접 관리하고 싶지 않은 팀을 위해 호스팅된 제품 옵션도 유지했습니다. 두 경로 모두 동일한 코드베이스를 사용합니다: 데이터 주권(data sovereignty)과 맞춤화가 중요할 때는 자체 호스팅을 사용하고, 운영의 단순성(operational simplicity)이 더 중요할 때는 관리형 서비스를 사용합니다.
배운 점
가장 어려웠던 부분은 질문을 생성하는 것이 아니었습니다. 모델 주변에 신뢰할 수 있는 루프를 구축하는 것이었습니다: 영속적인 세션 상태(durable session state), 제한된 후속 질문(bounded follow-ups), 모달리티 독립적인 보고(modality-independent reporting), 관찰 가능한 증거(observable evidence), 그리고 실시간 미디어 실패 시 복구 기능입니다.
AI 인터뷰어는 자신감 있는 추천을 내보내는 블랙박스여서는 안 됩니다. 유용한 출력은 증거의 흔적(evidence trail)입니다: 무엇이 질문되었는지, 참가자가 무엇을 말했는지, 어떤 기준이 적용되었는지, 그리고 인간이 결과를 검토해야 하는 곳이 어디인지가 기록되어야 합니다.
소스 코드는 GitHub에서 확인할 수 있습니다. 자체 호스팅 경험, 채점 투명성(scoring transparency), 그리고 실시간 인터뷰 흐름에 대한 피드백을 특히 환영합니다.
원래 Aural 블로그에 게시되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기