{"slug": "grillkit-self-hosted-ai-technical-interview-trainer", "title": "GrillKit – self-hosted AI technical interview trainer", "summary": "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.", "body_md": "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.\n\n[Quick start](#quick-start) · [Changelog](/GrillKit/grillkit/blob/main/CHANGELOG.md) · [Architecture](/GrillKit/grillkit/blob/main/ARCHITECTURE.md)\n\n**Demo video** — full flow from setup to scored feedback\n\n**Dashboard** — recent sessions and quick start\n\n**Interview setup** — question-bank tracks, levels, topics, and session options\n\n**Interview session** — real-time Q&A with AI scoring and final evaluation\n\n**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 question**Timer**— 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}/`\n\n), junior / middle / senior**Setup**— model catalog on`/config`\n\n, interview locale (AI feedback language), Whisper/Piper downloads from the UI**Dashboard**— recent interview history on the home page** Persistence**— SQLite (`data/db/grillkit.db`\n\n); Docker Compose on port 8000 with`./data`\n\nvolume\n\n**Planned**\n\n- Session-wide time limit (total interview duration)\n- More question banks (Go, JavaScript, Java, C++, …)\n- Code editor in the interview UI\n- Custom question banks, PWA / standalone frontend\n\n[Docker](https://docs.docker.com/get-docker/)and[Docker Compose](https://docs.docker.com/compose/install/)- API key for a cloud provider,\n**or** a local OpenAI-compatible server (Ollama, vLLM, …)\n\n```\ngit clone https://github.com/yourusername/grillkit.git\ncd grillkit\ndocker compose up --build\n```\n\nOpen [http://localhost:8000](http://localhost:8000).\n\nOptional **question voice** (Piper TTS, same `app`\n\ncontainer):\n\n- Run\n`docker compose up`\n\n(or`uv run uvicorn app.main:app`\n\nfor development). - Open\n`/config`\n\n, enable**Read questions aloud**, save. - On the Configuration page, use\n**Download question voice** when prompted (~60 MB per locale voice from Hugging Face). - Start an interview — questions can play aloud; WAV cache lives under\n`data/tts-cache/v2/{locale}/`\n\n.\n\n`./data`\n\non the host holds SQLite, `config.json`\n\n, `llm_models.json`\n\n, Whisper/Piper models, and TTS cache. Question banks, templates, and static files are in the image.\n\nIf bind-mounted `data/`\n\nis not writable (Linux UID mismatch):\n\n```\nPUID=$(id -u) PGID=$(id -g) docker compose up --build\n```\n\n**Configuration**(`/config`\n\n) — add one or more OpenAI-compatible models to the catalog, select an interview model, set interview locale; test connection, then save.**New interview**(`/setup`\n\n) — 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}`\n\n) — page loads history; answers and completion go over WebSocket.\n\nWithout saved provider config, `/setup`\n\nredirects to `/config`\n\n.\n\n```\nuv sync --extra dev\nuv run uvicorn app.main:app --reload\n```\n\nSame first-time flow at [http://127.0.0.1:8000](http://127.0.0.1:8000).\n\nAny **OpenAI-compatible** HTTP API works (single adapter in code):\n\n| Provider | Example base URL |\n|---|---|\n| OpenAI | `https://api.openai.com/v1` |\n| Ollama | `http://localhost:11434/v1` |\n| vLLM / others | your endpoint + `/v1` |\n\nOn `/config`\n\n, 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](/GrillKit/grillkit/blob/main/data/llm_models.json) (gitignored). Select an interview model from the list, run\n\n**Test Connection**, then save.\n\nApplication settings and interview **locale** (AI feedback and dictation language) live in `data/config.json`\n\n(gitignored). Do not commit secrets.\n\nAfter saving configuration, choose a **Whisper** model size (`small`\n\n, `medium`\n\n, or `large`\n\n) and download it from the Configuration page (stored under `data/whisper-models/<size>/`\n\n). Dictation uses the locale snapshot from config. The app loads the model into memory when the download finishes or on the next startup.\n\n**Read questions aloud** (`question_voice_enabled`\n\n) requests synthesized audio for question text only (never code blocks). Download the Piper voice on `/config`\n\nafter enabling the option (~60 MB per voice from Hugging Face).\n\nOptional environment variables:\n\n| Variable | Purpose |\n|---|---|\n`HF_TOKEN` |\nHugging Face read token for faster, more reliable Whisper and Piper model downloads (\n`docker compose` when set on the host. |\n\n`WHISPER_DEVICE`\n\n`cpu`\n\nor `cuda`\n\n(default `cpu`\n\n)`WHISPER_COMPUTE_TYPE`\n\n`int8`\n\nor `float16`\n\n(default `int8`\n\non CPU)\n\n```\ndata/\n├── config.json              # Locale, speech/TTS flags, timer defaults (gitignored)\n├── llm_models.json          # Interview model catalog (gitignored)\n├── db/grillkit.db           # SQLite (gitignored, created on startup)\n├── whisper-models/          # Offline Whisper models per size (gitignored content)\n├── piper-voices/            # Piper ONNX voices for question TTS (gitignored content)\n├── tts-cache/               # Cached question WAVs per locale (gitignored content)\n└── questions/               # YAML banks: {track}/{level}/{category}.yaml\n```\n\nSchema and `selection_spec`\n\ndata migrations run automatically on startup via **Alembic** (`uv run alembic upgrade head`\n\n). For a clean dev DB, remove `data/db/grillkit.db`\n\nand restart the app.\n\n```\napp/\n├── main.py              # FastAPI app, routers, lifespan\n├── interview/           # Sessions, WebSocket chat, scoring, timer\n├── speech/              # Whisper download + dictation\n├── question_voice/      # Piper TTS, cache, question audio API\n├── platform/            # Provider config, LLM catalog (/config)\n├── shared/              # DB, UoW, locales, artifact download helpers\n└── ai/                  # OpenAI-compatible + faster-whisper adapters\ntemplates/               # Jinja2 UI\nstatic/                  # CSS, JS (dictation, timer, question voice)\ntests/\nARCHITECTURE.md          # Layers, routes, data flows\n```\n\nCI runs on every pull request and on pushes to `main`\n\n(ruff, mypy, pytest). See [ .github/workflows/ci.yml](/GrillKit/grillkit/blob/main/.github/workflows/ci.yml).\n\n```\nuv sync --frozen --extra dev\nuv run pytest\nuv run ruff check --fix .\nuv run ruff format .\nuv run mypy .\n```\n\nSee [CONTRIBUTING.md](/GrillKit/grillkit/blob/main/CONTRIBUTING.md) for contribution guidelines.\n\nReport vulnerabilities as described in [SECURITY.md](/GrillKit/grillkit/blob/main/SECURITY.md). Do not open public issues for security problems.\n\n[Apache License 2.0](/GrillKit/grillkit/blob/main/LICENSE) (see also [NOTICE](/GrillKit/grillkit/blob/main/NOTICE))", "url": "https://wpnews.pro/news/grillkit-self-hosted-ai-technical-interview-trainer", "canonical_source": "https://github.com/GrillKit/grillkit", "published_at": "2026-05-26 14:56:03+00:00", "updated_at": "2026-05-26 15:09:03.478619+00:00", "lang": "en", "topics": ["ai-tools", "artificial-intelligence", "large-language-models", "generative-ai", "ai-products"], "entities": ["GrillKit", "Whisper", "Piper", "OpenAI", "SQLite", "Docker", "Python", "System Design"], "alternates": {"html": "https://wpnews.pro/news/grillkit-self-hosted-ai-technical-interview-trainer", "markdown": "https://wpnews.pro/news/grillkit-self-hosted-ai-technical-interview-trainer.md", "text": "https://wpnews.pro/news/grillkit-self-hosted-ai-technical-interview-trainer.txt", "jsonld": "https://wpnews.pro/news/grillkit-self-hosted-ai-technical-interview-trainer.jsonld"}}