cd /news/ai-tools/grillkit-self-hosted-ai-technical-in… · home topics ai-tools article
[ARTICLE · art-14557] src=github.com pub= topic=ai-tools verified=true sentiment=↑ positive

GrillKit – self-hosted AI technical interview trainer

GrillKit, an open-source AI technical interview trainer, has been released, allowing users to configure OpenAI-compatible models and practice from YAML question banks. The tool features real-time scoring, optional voice input and question audio, and supports multiple tracks including Python, Database, and System Design. It runs locally via Docker Compose, storing data in SQLite, and is designed for self-hosted interview preparation.

read4 min publishedMay 26, 2026

Open-source AI technical interview trainer. Configure an OpenAI-compatible model, practice from YAML question banks, and get real-time scoring with optional voice input and question audio.

Quick start · Changelog · Architecture

Demo video — full flow from setup to scored feedback

Dashboard — recent sessions and quick start

Interview setup — question-bank tracks, levels, topics, and session options

Interview session — real-time Q&A with AI scoring and final evaluation

Interviews— multi-track setup (Python, Database, System Design, …), several topics per session, WebSocket Q&A, AI scoring 1–5, up to 2 follow-ups per questionTimer— optional per-round time limit; expired rounds score 0 and the session moves on** Voice**— offline Whisper dictation for answers; optional Piper TTS to read questions aloud** Question banks**— Python, Database/SQL, and System Design (data/questions/{track}/

), junior / middle / seniorSetup— model catalog on/config

, interview locale (AI feedback language), Whisper/Piper downloads from the UIDashboard— recent interview history on the home page** Persistence**— SQLite (data/db/grillkit.db

); Docker Compose on port 8000 with./data

volume

Planned

  • Session-wide time limit (total interview duration)
  • More question banks (Go, JavaScript, Java, C++, …)
  • Code editor in the interview UI
  • Custom question banks, PWA / standalone frontend

DockerandDocker Compose- API key for a cloud provider, or a local OpenAI-compatible server (Ollama, vLLM, …)

git clone https://github.com/yourusername/grillkit.git
cd grillkit
docker compose up --build

Open http://localhost:8000.

Optional question voice (Piper TTS, same app

container):

  • Run docker compose up

(oruv run uvicorn app.main:app

for development). - Open /config

, enableRead questions aloud, save. - On the Configuration page, use Download question voice when prompted (~60 MB per locale voice from Hugging Face). - Start an interview — questions can play aloud; WAV cache lives under data/tts-cache/v2/{locale}/

.

./data

on the host holds SQLite, config.json

, llm_models.json

, Whisper/Piper models, and TTS cache. Question banks, templates, and static files are in the image.

If bind-mounted data/

is not writable (Linux UID mismatch):

PUID=$(id -u) PGID=$(id -g) docker compose up --build

Configuration(/config

) — add one or more OpenAI-compatible models to the catalog, select an interview model, set interview locale; test connection, then save.New interview(/setup

) — enable one or more question-bank tracks (level per track), select multiple topics, set total question count (at least one per selected topic; interview locale is read-only from config).Interview(/interview/{id}

) — page loads history; answers and completion go over WebSocket.

Without saved provider config, /setup

redirects to /config

.

uv sync --extra dev
uv run uvicorn app.main:app --reload

Same first-time flow at http://127.0.0.1:8000.

Any OpenAI-compatible HTTP API works (single adapter in code):

Provider Example base URL
OpenAI https://api.openai.com/v1
Ollama http://localhost:11434/v1
vLLM / others your endpoint + /v1

On /config

, use Add model to catalog to save OpenAI-compatible providers (base URL, model name, optional API key). Entries are stored in data/llm_models.json (gitignored). Select an interview model from the list, run

Test Connection, then save.

Application settings and interview locale (AI feedback and dictation language) live in data/config.json

(gitignored). Do not commit secrets.

After saving configuration, choose a Whisper model size (small

, medium

, or large

) and download it from the Configuration page (stored under data/whisper-models/<size>/

). Dictation uses the locale snapshot from config. The app loads the model into memory when the download finishes or on the next startup.

Read questions aloud (question_voice_enabled

) requests synthesized audio for question text only (never code blocks). Download the Piper voice on /config

after enabling the option (~60 MB per voice from Hugging Face).

Optional environment variables:

Variable Purpose
HF_TOKEN
Hugging Face read token for faster, more reliable Whisper and Piper model downloads (
docker compose when set on the host.

WHISPER_DEVICE

cpu

or cuda

(default cpu

)WHISPER_COMPUTE_TYPE

int8

or float16

(default int8

on CPU)

data/
├── config.json              # Locale, speech/TTS flags, timer defaults (gitignored)
├── llm_models.json          # Interview model catalog (gitignored)
├── db/grillkit.db           # SQLite (gitignored, created on startup)
├── whisper-models/          # Offline Whisper models per size (gitignored content)
├── piper-voices/            # Piper ONNX voices for question TTS (gitignored content)
├── tts-cache/               # Cached question WAVs per locale (gitignored content)
└── questions/               # YAML banks: {track}/{level}/{category}.yaml

Schema and selection_spec

data migrations run automatically on startup via Alembic (uv run alembic upgrade head

). For a clean dev DB, remove data/db/grillkit.db

and restart the app.

app/
├── main.py              # FastAPI app, routers, lifespan
├── interview/           # Sessions, WebSocket chat, scoring, timer
├── speech/              # Whisper download + dictation
├── question_voice/      # Piper TTS, cache, question audio API
├── platform/            # Provider config, LLM catalog (/config)
├── shared/              # DB, UoW, locales, artifact download helpers
└── ai/                  # OpenAI-compatible + faster-whisper adapters
templates/               # Jinja2 UI
static/                  # CSS, JS (dictation, timer, question voice)
tests/
ARCHITECTURE.md          # Layers, routes, data flows

CI runs on every pull request and on pushes to main

(ruff, mypy, pytest). See .github/workflows/ci.yml.

uv sync --frozen --extra dev
uv run pytest
uv run ruff check --fix .
uv run ruff format .
uv run mypy .

See CONTRIBUTING.md for contribution guidelines.

Report vulnerabilities as described in SECURITY.md. Do not open public issues for security problems.

Apache License 2.0 (see also NOTICE)

── more in #ai-tools 4 stories · sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/grillkit-self-hosted…] indexed:0 read:4min 2026-05-26 ·