====== AI Anki: интервальные повторения с ИИ-экзаменатором ======
===== Введение =====
**AI Anki** — карточки для подготовки к собеседованиям и экзаменам. Ответ пишется своими словами, кодом или формулой, а модель Ollama оценивает понимание, задаёт уточняющие вопросы и по алгоритму интервальных повторений возвращает карточку в нужный момент.
* Сайт: ''https://anki.webmastermsk.ru''
* Исходный код: ''https://github.com/werwolf1000/ai-anki''
* На NAS: ''/mnt/storage/web/ai-anki'' (SMB: ''%%smb://truenas.local/web/ai-anki%%'')
Состав:
^ Часть ^ Технологии ^ Каталог ^
| Сервер (API) | Python, FastAPI | ''server/'', ''app/'' |
| Веб-интерфейс | React, Motion, AutoAnimate, Tailwind CSS (Vite) | ''web/'' |
| Приложение для Windows | Electron, окно без рамки, тот же интерфейс | ''desktop/'' |
| Колоды | JSON | ''decks/'' |
| Данные пользователей | SQLite + JSON | ''data/'' (том Docker) |
Внешние сервисы: **Ollama** (проверка ответов, статьи учебника, собеседования) и [[:truenas:application:whisper_asr|Whisper ASR]] (голосовые ответы).
===== Возможности =====
==== Аккаунты ====
* Вход и регистрация. У каждого пользователя свой прогресс, статистика и настройки обучения.
* **Первый зарегистрированный аккаунт становится администратором** и получает прогресс старой однопользовательской версии (''data/progress.json'').
* Настройки Ollama и Whisper общие для сервера — меняет только администратор.
* Приложение для Windows входит в тот же аккаунт: прогресс общий с сайтом.
==== Учебные сессии ====
* Режимы: повторение, только новые, слабые, вся колода; выбор темы.
* Типы карточек: текстовый ответ, исправление кода, live-coding (редактор Monaco), формулы (MathLive + KaTeX), анатомия с изображениями.
* Ответ голосом (Whisper) с ИИ-исправлением терминов.
==== Учебник (RAG) ====
Перед прохождением темы можно прочитать статью по ней (раздел **«Учебник»**).
* Источник — официальный **PHP Manual на русском** с php.net: справочник языка, нововведения PHP 7–8, массивы, строки, JSON, PDO, дата/время, SPL. Всего ~2600 страниц → ~6900 фрагментов.
* Поиск гибридный: полнотекстовый (BM25) + смысловой (векторы модели ''qwen3-embedding:8b'').
* Статью пишет Ollama по найденным фрагментам и карточкам темы, со сносками ''[n]'' на страницы php.net. Готовая статья сохраняется и в следующий раз открывается мгновенно.
* Есть оглавление, отметка «прочитано», вопросы к учебнику («Спросить учебник») и кнопка «Проверить себя».
* Для колод без официального источника (Go, Python, Agile и др.) статья строится по материалам карточек.
==== Профессии, собеседования, экзамены, сертификаты ====
9 треков: PHP-разработчик, Node.js-разработчик, Go-разработчик, DevOps-инженер, Forward Deployed Engineer, AI-тренер, специалист по промпт-инжинирингу, LLM-оценщик / AI QA, нейрокреатор / AI-художник.
^ Этап ^ Содержание ^ Условие ^
| Обучение | теория (8 предметов × 5 карточек) + практикум (10 заданий live-coding) | сдано ≥ 60% карточек трека |
| AI-собеседование | чат с интервьюером: 5 вопросов + практическое задание, уточняющие вопросы, отчёт с уровнем Junior/Middle/Senior | балл ≥ 65 |
| Экзамен | 9 теоретических + 3 практических задания за 60 минут, без подсказок | балл ≥ 70 |
| Сертификат | уникальный номер, печать в PDF, публичная проверка ''/verify/<номер>'' | выполнены все три условия |
Число вопросов, время и пороги настраиваются в ''decks/tracks.json''.
===== Требования =====
* TrueNAS Scale с Apps (Docker) и доступом в интернет (сборка образа скачивает ''node:22-alpine'' и npm-пакеты; учебник скачивает архив с php.net).
* Сервер **Ollama** с моделями ''qwen3-coder:30b'' (или другой) и ''qwen3-embedding:8b''.
* Сервер [[:truenas:application:whisper_asr|Whisper ASR]] — для голосовых ответов (необязательно).
* Для разработки и сборки приложения для Windows: Node.js 22+, Python 3.12.
===== Шаг 1: Первая установка на TrueNAS =====
Склонируйте репозиторий и создайте каталог данных:
cd /mnt/storage/web
git clone https://github.com/werwolf1000/ai-anki.git
mkdir -p /mnt/storage/web/ai-anki/data/decks
Соберите образ (несколько минут; на этапе ''web'' собирается React-интерфейс):
cd /mnt/storage/web/ai-anki
docker build -t ai-anki-web:latest .
В TrueNAS: **Apps** → **Discover Apps** → **Custom App** → вставьте ''docker-compose.truenas.yml'':
services:
ai-anki:
build: /mnt/storage/web/ai-anki
image: ai-anki-web:latest
container_name: ai-anki
restart: unless-stopped
ports:
- "8080:8080"
environment:
AI_ANKI_DATA_DIR: /data
# open — регистрация открыта; closed — новых аккаунтов после первого не создать
AI_ANKI_REGISTRATION: open
volumes:
- /mnt/storage/web/ai-anki/data:/data
- /mnt/storage/web/ai-anki/decks:/app/decks:ro
extra_hosts:
- "host.docker.internal:host-gateway"
**Save** → **Deploy**. Приложение доступно на ''%%http://:8080%%'' и через прокси на ''https://anki.webmastermsk.ru''.
===== Шаг 2: Первичная настройка =====
- Откройте сайт и **сразу зарегистрируйтесь** — первый аккаунт станет администратором.
- **Настройки** → **«Сервер»**: Ollama URL, модель, при необходимости API-ключ; ASR URL Whisper. Нажмите **«Проверить Ollama»**.
- **Настройки** → **«База знаний учебника»** → **«Скачать и проиндексировать»**. Разбор архива занимает ~1 минуту, векторизация — ~40 минут в фоне; учебником можно пользоваться сразу.
- При желании закройте регистрацию: ''AI_ANKI_REGISTRATION: closed'' в compose → **Save**.
===== Шаг 3: Обновление =====
**Важно:** кнопка **Redeploy** в TrueNAS только перезапускает контейнер из уже собранного образа ''ai-anki-web:latest'' и **не пересобирает** его. Новый код попадает на сайт только после ''docker build''.
Порядок обновления:
- На рабочей машине отправить изменения: ''git push origin main''.
- На NAS забрать код и пересобрать образ:
ssh truenas_admin@192.168.1.135
cd /mnt/storage/web/ai-anki
git pull
docker build -t ai-anki-web:latest .
- В TrueNAS: **Apps** → **anki** → **Stop**, затем **Start**.
- Открыть сайт и обновить страницу с очисткой кэша (**Ctrl+F5**).
Проверить, что контейнер запущен с новым образом:
docker images ai-anki-web
docker ps --format "{{.Names}} {{.Image}} {{.Status}}" | grep ai-anki
Время создания образа (''CREATED'') должно соответствовать последней сборке.
===== Шаг 4: Приложение для Windows =====
Сборка установщика (на рабочей машине):
cd F:\projects\ai_anki\web
npm install
cd ..\desktop
npm install
npm run dist
Результат: ''desktop\dist\AI-Anki-Setup-<версия>.exe''. Запуск без установки для разработки — ''npm start''.
* Окно без системной рамки, свой заголовок с кнопками свернуть/развернуть/закрыть.
* На экране входа указывается адрес сервера (по умолчанию ''https://anki.webmastermsk.ru'').
* Если после ''npm install'' нет ''node_modules\electron\dist\electron.exe'': ''node node_modules/electron/install.js''.
**Примечание:** при изменениях интерфейса установщик нужно пересобрать — он содержит копию веб-интерфейса.
===== Данные и резервные копии =====
^ Файл (в ''data/'') ^ Содержимое ^
| ''users.db'' | пользователи и токены входа |
| ''users//progress.json'' | прогресс интервальных повторений пользователя |
| ''users//settings.json'' | личные настройки обучения |
| ''users//textbook.json'' | прочитанные темы учебника |
| ''config.json'' | общие настройки сервера (Ollama, ASR, модели) |
| ''knowledge.db'' | база знаний учебника и сгенерированные статьи |
| ''tracks.db'' | попытки экзаменов и собеседований, реестр сертификатов |
| ''decks/'' | собственные колоды (JSON/TXT) — подхватываются без пересборки |
| ''progress.json'' | прогресс версии 1.x (копируется первому аккаунту) |
Для бэкапа достаточно копировать каталог ''/mnt/storage/web/ai-anki/data''.
===== Работа с колодами =====
* Встроенные колоды — ''decks/*.json'' в репозитории (монтируются в контейнер, пересборка не нужна — достаточно перезапуска).
* Свои колоды — положить в ''data/decks/''.
* После перегенерации колод скриптами ''decks/generate_*.py'' запустить очистку: ''python decks/clean_decks.py'' (удаляет карточки-заглушки и дубликаты, сохраняя прогресс).
* Профессии: контент в ''decks/pro_tracks/*.py'' → ''python decks/generate_pro_tracks.py''.
===== Проблемы и решения =====
^ Проблема ^ Причина ^ Решение ^
| После ''git pull'' и Redeploy сайт не изменился | образ не пересобран | ''docker build -t ai-anki-web:latest .'' → Stop/Start |
| Проверка ответов идёт минутами или ошибка «Ollama: timeout» | Ollama перегружен или модель не поместилась в видеопамять и работает на CPU | ''curl /api/ps'' — смотреть ''size_vram''; освободить GPU (''nvidia-smi''), не держать параллельно тяжёлые модели |
| Голос распознаётся с ошибками в терминах | слабая модель Whisper | см. [[:truenas:application:whisper_asr|Whisper ASR]]: ''large-v3-turbo'' |
| Кнопки «Голосом» нет | не задан ASR URL | Настройки → Сервер → ASR URL (под администратором) |
| Учебник пишет «официальный источник не подключён» | база знаний не загружена или колода не про PHP | Настройки → База знаний → «Скачать и проиндексировать» |
| Индексация прервалась после перезапуска | фоновая задача остановилась вместе с контейнером | Настройки → База знаний → «Довекторизовать» (продолжит с места остановки) |
| Забыт пароль | — | ''docker exec -it ai-anki python scripts/reset_password.py <логин> <новый_пароль>'' |
| Незавершённый экзамен или собеседование пропали | после перезапуска сервера активные попытки не сохраняются | начать заново; сохранённые результаты не теряются |
| «Фронтенд не собран» (503) | образ собран без этапа ''web'' | пересобрать образ по текущему ''Dockerfile'' |
===== Шпаргалка =====
# обновление на NAS
cd /mnt/storage/web/ai-anki && git pull && docker build -t ai-anki-web:latest .
# затем в TrueNAS: Apps → anki → Stop / Start
# логи
docker logs -f ai-anki
# состояние сервиса
curl -s https://anki.webmastermsk.ru/healthz
curl -s https://anki.webmastermsk.ru/api/auth/status
# сброс пароля
docker exec -it ai-anki python scripts/reset_password.py <логин> <новый_пароль>
# какие модели загружены в Ollama и сколько видеопамяти занимают
curl -s http://:30068/api/ps