로컬 LLM을 상대로 기술 면접을 연습할 수 있는 새로운 셀프 호스팅 프로젝트가 등장했습니다. 채점 기능, AI 후속 질문, 그리고 이제 음성 지원까지 갖췄습니다. 첫 커밋부터 음성 지원까지 단 12일 만에 이루어졌으며, GitHub 스타는 현재 4개입니다.
GrillKit이란 무엇인가 — 그리고 무엇이 아닌가
GrillKit은 큐레이션된 YAML 문제 은행을 기반으로 채점 가능한 모의 면접을 진행하고, 모든 OpenAI 호환 LLM에 연결할 수 있는 오픈소스 셀프 호스팅 기술 면접 트레이너입니다 . 어디까지나 응시자 측 도구로, 면접을 준비하는 사람을 위한 연습 플랫폼입니다. 채용 ATS나 기업용 스크리닝 플랫폼이 아님을 명시하고 있습니다 . 지원자를 필터링하는 도구를 찾고 있다면, GrillKit은 해당되지 않습니다.
각 세션은 N개의 고정된 질문 계획을 기반으로 WebSocket으로 구동되는 대화 형식으로 진행됩니다. 질문당 모델이 최대 2개의 AI 후속 질문을 생성할 수 있으며, 답변이 완료된 라운드는 1~5점 척도로 채점됩니다. 타이머가 만료된 라운드는 0점 처리될 수 있습니다 . 로컬 대시보드에서 지난 세션을 확인할 수 있으며, 설정 시 트랙·난이도·주제·문제 수를 선택할 수 있습니다 .
모델 백엔드는 의도적으로 개방형으로 설계되었습니다. GrillKit은 OpenAI 호환 /v1 엔드포인트라면 모두 연결할 수 있습니다 — http://localhost:11434/v1의 Ollama, vLLM, 또는 클라우드 OpenAI — 덕분에 모든 처리를 자신의 머신에서 완결하거나, 호스팅 프로바이더를 이용할 수도 있습니다 .
진정한 신생 프로젝트이기도 합니다. Apache-2.0 라이선스로 공개되었으며, 첫 공개 커밋은 2026년 5월 20일이었습니다 . 5월 31일 2026.5.31 릴리스에 이르러서는 텍스트 전용 모의 면접에서 음성 지원 트레이너로 발전했습니다 — 오디오 답변 지원, WAV 업로드 API, 녹음/전송 컨트롤이 2주 이내에 추가된 것입니다 . 2026년 6월 2일 기준 리포지토리는 스타 4개, 포크 1개, 커밋 11개, 릴리스 3개로 — 어떤 기준으로 봐도 초기 단계입니다 . 기대치를 적절히 조정하고 살펴볼 만한 프로젝트입니다.
면접 세션은 이렇게 흘러갑니다

GrillKit 세션은 설정된 루프로 진행됩니다. 파라미터를 한 번 설정하면, 모델이 각 답변을 채점하기 전에 탐색하는 동안 고정된 질문 목록에 답변하게 됩니다. 시작 전 설정 폼에서 트랙·난이도·주제·문제 수를 선택할 수 있습니다 . 이 문제 수가 세션의 계획이 됩니다 — 정적 퀴즈가 아닌, N개의 계획된 질문이 하나씩 제공됩니다.
각 질문은 WebSocket 연결을 통해 전달되어, 면접이 폼 기반이 아닌 대화형으로 느껴지게 합니다. 답변 후 LLM은 해당 질문에 대해 라운드가 종료되기 전에 최대 2개의 AI 후속 질문을 생성할 수 있습니다 . 이 후속 질문이 바로 이 트레이너가 그 이름값을 하는 지점입니다. 간략한 첫 번째 답변에는 라운드 종료 전에 구체적인 내용을 추가로 요구합니다.
채점은 라운드별로 이루어지며, 의도적으로 단순하게 설계되었습니다. 답변이 완료된 라운드는 1~5점 척도로 채점되며, 응답과 후속 질문 교환 내용이 판단 기준이 됩니다 . 2026.5.24 릴리스에서 추가된 선택적 라운드별 카운트다운 타이머는 긴장감을 높입니다. 답변하기 전에 타이머가 만료되면, 해당 라운드는 공백으로 남기는 대신 자동으로 0점 처리됩니다 . 타이머를 끄면 세션이 자유 진행 방식으로 유지되며, 주제를 아직 학습 중일 때는 이 설정이 더 나은 기본값입니다.
데이터 측면에서 GrillKit의 셀프 호스팅 철학이 드러납니다. 세션 기록, 라운드별 점수, 전체 후속 질문 대화 내용은 모두 로컬 SQLite 데이터베이스에 저장되며, 기기 내 대시보드에서 지난 세션으로 확인할 수 있습니다 . 세션 중 외부로 나가는 네트워크 호출은 설정된 LLM 엔드포인트에 대한 요청뿐이며, 해당 API 호출 외에 외부 서비스에는 아무것도 기록되지 않습니다 .
이 설계에는 주목할 만한 실질적인 함의가 있습니다. 대화 내용의 프라이버시는 연결된 모델에 달려 있습니다. 호스팅 프로바이더를 통해 세션을 라우팅하면 답변이 해당 서버로 전송되고, 로컬 엔드포인트를 통해 라우팅하면 루프 전체가 내 하드웨어 내에서만 유지됩니다 — 이 설정 선택에 대해서는 다음 섹션에서 다룹니다.
Whisper 음성 입력: 녹음, 업로드, 변환까지
GrillKit의 음성 입력은 완전히 로컬에서 동작하는 음성 처리 파이프라인입니다. 답변을 말하면 WAV 파일로 캡처되고, 오프라인 faster-whisper 모델이 사용자의 기기에서 직접 변환을 처리합니다 — 클라우드 음성 API는 사용되지 않으며, 오디오가 기기 밖으로 나가지 않습니다. 이 기능은 2026년 5월 31일자 릴리스 2026.5.31에 추가되었으며 , 인터뷰 페이지에 녹음(Record)·전송(Send) 컨트롤과 WAV 업로드 API가 함께 포함되었습니다 .
동작 방식은 간단합니다. 녹음 버튼을 누르고 답변을 말한 뒤 전송하면, 캡처된 WAV가 업로드 엔드포인트로 전송됩니다. faster-whisper가 오디오를 로컬에서 텍스트로 변환하고, 그 변환 결과가 채점 루프와 후속 질문 생성기에서 실제로 사용됩니다. 변환이 LLM 호출 이전에 완료되기 때문에, Whisper 경로는 설정된 모든 텍스트 지원 모델에서 동작합니다 — 이 모드에서 모델이 보는 것은 오디오가 아닌 변환된 텍스트뿐입니다. 멀티모달 엔드포인트가 필요 없는 범용적인 방식입니다.
이전 릴리스 2026.5.24에서 기반을 마련했습니다. 오프라인 Whisper 음성 입력과 함께 선택적 Piper TTS를 탑재해 질문을 음성으로 읽어줄 수 있게 되었습니다 . Piper는 출력 측 질문 오디오를, faster-whisper는 입력 측 답변 처리를 각각 담당하며, 둘 다 로컬에서 실행됩니다. 단점은 용량입니다 — Piper 로케일 음성 팩은 하나당 약 60 MB이므로 , 여러 언어를 추가하면 첫 사용 전에 그만큼의 다운로드가 필요합니다. 고정 의존성은 Python 3.12+ 환경에서 faster-whisper 1.2.1+, piper-tts 1.4.2+입니다 .
구분이 필요한 두 번째 음성 모드가 있습니다. Whisper 변환 결과 대신 오디오를 모델이 직접 받아 처리하게 하려면, data/llm_models.json의 해당 모델 항목에 accepts_audio_input: true를 설정해야 합니다 . 이 플래그는 2026.5.31에 새로 추가된 것으로, 오디오 네이티브 답변을 활성화하며 Whisper 설정과 멀티모달 모델이 모두 갖춰진 환경을 전제로 합니다 . 대부분의 환경에서는 텍스트 모델 외에 별도 요건 없이 사용 가능한 변환 경로로 충분합니다. accepts_audio_input 플래그는 멀티모달 모델에 원본 오디오를 직접 전달해야 하는 경우에만 사용하세요.
Ollama 또는 /v1 호환 엔드포인트 연결

GrillKit은 단일 OpenAI 호환 어댑터를 통해 언어 모델과 통신하므로, 코드가 아닌 URL만 바꿔 백엔드를 선택할 수 있습니다. 로컬 Ollama를 사용하려면 프로바이더 주소를 http://localhost:11434/v1로 설정하면 되며, 같은 방식으로 OpenAI, vLLM, 또는 호환 /v1 엔드포인트를 노출하는 모든 서비스를 연결할 수 있습니다 . 이 하나의 추상화 덕분에 동일한 인터뷰 세션을 완전한 클라우드, 완전한 로컬, 또는 하이브리드 환경 어디서든 실행할 수 있습니다.
GrillKit이 인식하는 모델 목록은 카탈로그 파일 data/llm_models.json에 정의되어 있으며, 타이머와 오프라인 Whisper 입력과 함께 릴리스 2026.5.24에서 도입되었습니다 . 각 항목은 설정 시 선택 가능한 모델을 등록합니다. 변환 텍스트 대신 원본 오디오를 모델이 직접 받게 하려면 해당 항목에 accepts_audio_input: true 플래그를 설정하세요 — 2026.5.31에 추가된 모델별 오디오 플래그입니다 . Whisper가 먼저 변환하고 모델은 텍스트만 받는 일반적인 경우에는 플래그를 설정하지 않아도 됩니다.
선택하는 백엔드에 따라 인터뷰 데이터의 처리 위치가 달라집니다. OpenAI와 같은 클라우드 프로바이더를 사용하면, 매 라운드마다 프롬프트·음성 답변 변환 텍스트·채점 페이로드가 해당 프로바이더 서버로 전송됩니다 . 실제 시스템에 관한 질문으로 연습할 경우, 편의성·모델 품질과 인터뷰 이력을 서드파티에 넘기는 것 사이의 트레이드오프를 따져봐야 합니다.
완전 로컬 구성은 이 문제를 해소합니다. OpenAI 호환 로컬 모델(Ollama 또는 vLLM)과 faster-whisper 변환, Piper 질문 오디오를 함께 실행하면, 첫 질문부터 최종 점수까지 인터뷰 세션의 어떤 데이터도 기기 밖으로 나가지 않습니다 . GrillKit의 '로컬 우선' 지향을 실제로 구현하는 구성입니다.
| 백엔드 | 프로바이더 URL | 데이터 외부 전송 여부 |
|---|---|---|
| Ollama (로컬) | http://localhost:11434/v1 | 아니오 |
| vLLM (로컬/자체 호스팅) | 사용자의 /v1 엔드포인트 | 아니오 (자체 네트워크 내 운영 시) |
| OpenAI (클라우드) | OpenAI /v1 | 예 — 매 라운드 프롬프트·변환 텍스트·채점 페이로드 전송 |
| 기타 호환 API | 임의의 /v1 URL | 호스트에 따라 다름 |
어댑터가 프로바이더에 종속되지 않으므로, 처음에는 클라우드 모델로 설정을 검증한 뒤 프라이버시가 필요할 때 URL만 로컬 엔드포인트로 바꾸면 됩니다 — 마이그레이션도, 코드 수정도 필요 없습니다.
사전 탑재된 인터뷰 주제: Kafka, Kubernetes, Observability 외
GrillKit은 9개의 사전 탑재 인터뷰 트랙을 제공하므로 질문을 직접 작성하지 않아도 바로 연습을 시작할 수 있습니다. 아키텍처 문서에 따르면 최상위 트랙은 Python, Database/SQL, System Design, Kafka, RabbitMQ, Docker, Kubernetes, Observability, Airflow입니다 . 이 구성은 언어 기초부터 시니어 백엔드 및 SRE 인터뷰를 지배하는 분산 시스템·플랫폼 주제까지 폭넓게 다룹니다.
최신 릴리스는 단순히 트랙을 추가하는 데 그치지 않고 기존 카탈로그를 심화했습니다. 2026년 5월 31일자 릴리스 2026.5.31은 Kafka, RabbitMQ, Docker, Kubernetes, Observability, Airflow 문제 뱅크를 확장하고 영어와 러시아어 질문 항목을 추가했습니다 . Python·SQL 중심의 이전 빌드를 마지막으로 살펴봤다면, 메시징·오케스트레이션 트랙이 지금은 훨씬 풍부해졌습니다.
| 트랙 | 2026.5.31에서 확장됨? |
|---|---|
| Python | 아니요 (첫 릴리스에 포함) |
| Database/SQL | 아니요 (첫 릴리스에 포함) |
| System Design | 2026.5.31에 추가됨 |
| Kafka | 예 |
| RabbitMQ | 예 |
| Docker | 예 |
| Kubernetes | 예 |
| Observability | 예 |
| Airflow | 예 |
현지화는 부분적으로만 지원됩니다. GrillKit은 en, ru, fr, es, de 로케일 코드를 인식하지만, 아키텍처 문서에서도 인정하듯 비영어 로케일에서 여전히 영어로 폴백되는 항목이 많습니다 .
"현재 많은 질문 뱅크 항목이 영어로 폴백됩니다," — GrillKit ARCHITECTURE 문서 (source: GrillKit/grillkit).
팀에 유용한 실용적 정보: 질문 뱅크는 일반 YAML 파일입니다. 사내 시스템 설계 루브릭이나 회사 특화 Kubernetes 시나리오 등 자체 인터뷰 형식에 맞는 질문을 추가하는 것은 코드 변경이 아닌 파일 편집으로 끝납니다 . 제공된 뱅크를 포크하고 커스텀 트랙을 추가해 배포 환경 내에서 비공개로 유지할 수 있습니다.
Docker Compose로 GrillKit 구동하기

GrillKit 실행은 클론 한 번, docker compose up 한 번으로 완료됩니다. README의 빠른 시작 명령이 아닌 github.com/GrillKit/grillkit에서 클론하세요 — README의 명령은 실제 조직 저장소 대신 플레이스홀더인 github.com/yourusername/grillkit.git을 여전히 가리킵니다 . Compose는 FastAPI 앱을 빌드하고 포트 8000으로 게시하므로 컨테이너가 정상 상태가 되면 http://localhost:8000에서 인터뷰 UI에 접속할 수 있습니다 .
데이터 영속성은 단일 바인드 마운트로 처리됩니다. Compose 파일은 ./data:/app/data를 매핑하고 기본 SQLite 데이터베이스를 sqlite:////app/data/db/grillkit.db에 저장합니다. 호스트 디렉터리가 유지되는 한 컨테이너를 다시 빌드해도 이전 세션, 점수, 설정된 프로바이더가 그대로 보존됩니다 .
핵심 환경 변수는 세 가지입니다:
DATABASE_URL— 다른 백엔드를 사용할 경우 기본 SQLite 경로를 재정의합니다 .PUID/PGID— 마운트된./data볼륨에 기록되는 파일의 소유자 UID/GID를 설정하여 컨테이너가 호스트에 root 소유 파일을 남기지 않도록 합니다 .HF_TOKEN— 음성 전사에 사용되는 Whisper 모델의 Hugging Face 다운로드를 인가합니다 .
Docker 없이 설치하려면 일반 Python 스택을 사용하면 됩니다. Python 3.12 이상이 필요하며, 고정된 의존성은 FastAPI 0.136.1, Uvicorn 0.47.0, SQLAlchemy 2.0.49, faster-whisper 1.2.1+, piper-tts 1.4.2+, OpenAI 2.38.0, Pydantic 2.13.4, 스키마 마이그레이션용 Alembic 1.18.4+를 포함합니다 . 처음 시작할 때 Alembic 마이그레이션을 실행해 데이터베이스 스키마를 코드와 일치시켜야 합니다 — 2026.5.31 릴리스에서 바로 이를 관리하기 위해 Alembic이 도입되었습니다 .
코드 품질 측면에서 이 프로젝트는 약속이 아닌 CI로 증명합니다. GitHub Actions 워크플로우는 main 브랜치 푸시 및 풀 리퀘스트마다 Ruff(ruff check 및 포맷 검사), mypy 타입 검사, pytest를 실행합니다 . 커밋 11개, 릴리스 3개짜리 프로젝트임에도 처음부터 린트·타입·테스트를 게이팅한다는 점은 유지보수 의지를 가늠할 수 있는 합리적인 신호입니다 .
기본 인증 없음: 네트워크에 올리기 전에 반드시 읽으세요
GrillKit은 인증 레이어 없이 제공되므로, 공유 네트워크나 퍼블릭 네트워크에 노출하는 용도가 아닌 직접 관리하는 머신에서 단일 사용자 도구로 취급해야 합니다. 프로젝트의 SECURITY 정책에는 로그인 시스템이 없으며, 운영 환경에서 HTTPS 뒤에 배치하지 않는 한 WebSocket 연결이 일반 HTTP로 암호화 없이 실행된다고 명시되어 있습니다 . 로컬호스트에서는 문제없지만, LAN이나 퍼블릭 IP에서는 포트 8000에 접근할 수 있는 누구든 세션을 열어 읽을 수 있습니다.
"GrillKit은 로컬 또는 셀프 호스팅 단일 사용자 용도로 설계되었습니다. 인증 시스템이 없으며, WebSocket 연결은 HTTPS 뒤에 배치하지 않는 한 HTTP로 암호화되지 않습니다." — GrillKit SECURITY 정책 (source: SECURITY.md)
머신 외부에서 접근해야 한다면 앞에 리버스 프록시를 두고 기본 사항을 빠뜨리지 마세요:
- HTTPS 종료 — 앱 자체가 이를 처리하지 않으므로, WebSocket 트래픽이 암호화되도록 nginx, Caddy, 또는 Traefik으로 앞단을 구성하세요 .
- 인증 — 최소한 프록시에 HTTP 기본 인증을 추가하세요. 앱이 접근을 차단하지 않습니다.
- 범위 제한 — 로컬호스트 또는 신뢰할 수 있는 네트워크에 바인딩하고, 컨테이너의 포트 8000을 퍼블릭 인터페이스에 매핑하지 마세요 .
한 가지 더 짚을 경계: 웹 앱을 로컬에서 실행한다고 해서 데이터가 로컬에 머무는 것은 아닙니다. GrillKit을 클라우드 LLM에 연결하면 모든 프롬프트, 전사된 답변, 채점 컨텍스트가 해당 공급자의 API를 거칩니다. 완전한 프라이버시를 원한다면 Ollama나 vLLM 같은 OpenAI 호환 로컬 모델로 요청을 처리해야 합니다 .
핵심 정리: GrillKit은 신뢰할 수 있는 단일 운영자를 전제로 한 면접 트레이너입니다. 로컬 모델과 함께 자신의 머신에서만 사용하면 완전히 비공개로 유지되지만, 프록시·HTTPS·인증 없이 외부에 노출하면 포트를 찾은 누구에게나 연습 세션이 공개됩니다.
자주 묻는 질문
GrillKit은 무료 오픈소스인가요?
그렇습니다. GrillKit은 Apache-2.0 라이선스로 공개된 셀프 호스팅 무료 도구로, 호스팅형 SaaS 티어나 가격 페이지가 없습니다 . 구독할 것이 없으며, 저장소를 클론해 자신의 하드웨어에서 실행하면 로컬 데이터베이스에 저장된 모든 면접 세션과 API 키를 직접 소유합니다. 그 대신 설치·업데이트·보안은 모두 사용자 책임입니다.
클라우드 서비스에 데이터를 보내지 않고 GrillKit을 사용할 수 있나요?
가능합니다. OpenAI 호환 어댑터를 Ollama(http://localhost:11434/v1)나 vLLM 같은 로컬 엔드포인트로 지정하고, 음성 답변은 오프라인 faster-whisper로 전사하며, 질문 음성은 Piper로 생성하면 됩니다 . 이 구성에서는 아무것도 머신 밖으로 나가지 않습니다. LLM을 OpenAI 같은 호스팅 공급자로 전환하는 순간, 프롬프트·답변·채점 컨텍스트가 해당 공급자로 전송되어 로컬 전용 보장이 더 이상 유효하지 않습니다 .
사전 탑재된 면접 주제는 무엇인가요?
아키텍처 문서에는 최상위 트랙이 9개 정의되어 있습니다: Python, Database/SQL, System Design, Kafka, RabbitMQ, Docker, Kubernetes, Observability, Airflow . 질문 뱅크는 일반 YAML 파일이므로, 애플리케이션 코드를 수정하지 않고 data 디렉터리에 새 파일을 추가하는 것만으로 원하는 주제·난이도·언어를 직접 추가할 수 있습니다.
음성 모드에 특정 LLM이 필요한가요?
경로에 따라 다릅니다. Whisper 기반 전사는 어떤 LLM과도 작동합니다. faster-whisper가 녹음된 답변을 텍스트로 변환하면, 해당 텍스트가 설정된 모델로 전송됩니다. 모델이 오디오를 직접 수신하려면 data/llm_models.json의 해당 항목에 accepts_audio_input: true가 설정되어 있어야 하며, 이는 멀티모달 모델만 지원합니다 . 해당 오디오 입력 플래그와 WAV 업로드 API는 2026년 5월 31일 릴리스 2026.5.31에 추가되었습니다 .
GrillKit을 퍼블릭 URL에 노출해도 안전한가요?
추가 보안 강화 없이는 안전하지 않습니다. SECURITY 정책에는 인증 시스템이 없으며, 이 도구가 로컬 또는 셀프 호스팅 단일 사용자 용도로 설계되었기 때문에 HTTPS 뒤에 배치하지 않는 한 WebSocket 연결이 HTTP로 암호화 없이 실행된다고 명시되어 있습니다 . 로컬호스트 외부에 노출하기 전에 HTTPS를 종료하고 인증을 적용하는 리버스 프록시를 앞에 두세요. 그렇지 않으면 포트를 찾은 누구든 세션을 읽을 수 있습니다.