О проекте
Команда: NAN
Кейс HackAlem.ai: Менеджмент — Halyk Bank · кейс 1
Стадия: Доведённый продукт
Задача кейса: «Career Quest»: AI-навигатор, связывающий навыки сотрудника с шагами развития
Суть
Веб-приложение, в котором сотрудник видит разрывы навыков до целевого грейда и получает 1–3 персональные HR-активности с объяснением, а HR видит агрегированную аналитику дефицитов навыков и участия.
Как устроено
Датасет (сотрудники, навыки, события, история активностей) загружается в PostgreSQL. Рекомендательный движок фильтрует события по роли, грейду, prerequisites и обязательности, затем ранжирует их взвешенной формулой: покрытие skill gap, критичность навыка, прирост, вероятность завершения по Logistic Regression, история участия, штрафы; Top-3 подбирается с учётом разнообразия форматов. OpenAI (gpt-4.1-mini) только объясняет уже выбранные активности по evidence, ответ проверяется на неизменность ID и чисел; есть детерминированный fallback. После завершения активности навыки и готовность пересчитываются.
Ключевые решения
- Logistic Regression (scikit-learn)
- multi-factor weighted scoring
- diversity selection Top-3
- evidence-grounded LLM explanation
- deterministic fallback
- evidence hash caching (RecommendationSnapshot)
- Idempotency-Key
Особенности
Жёсткое разделение: ML и правила решают, ЧТО рекомендовать, а LLM объясняет ПОЧЕМУ. Ответ модели валидируется, чтобы она не могла поменять event ID, порядок или числа. В LLM не уходят ФИО и полная история, объяснения кэшируются по хэшу evidence. Роли сотрудника и HR разграничены на бэкенде.
Стек
Python · Django · Django REST Framework · PostgreSQL · Next.js · React · TypeScript · scikit-learn · pandas · Docker Compose · Gunicorn · drf-spectacular
Модели
OpenAI gpt-4.1-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-891a2861-nan.
README
README.mdCareer Quest
AI-навигатор развития сотрудников для трека Halyk Bank на HackAlem AI.
Career Quest превращает разрозненные HR-активности в понятную карьерную траекторию. Сотрудник видит требования следующего грейда, получает 1–3 персональные рекомендации и подробное объяснение, зачем ему нужна каждая активность. HR получает агрегированный обзор дефицитов навыков и участия без публичного рейтинга сотрудников.
Содержание
- Проблема и пользователи
- Что реализовано
- Как работает решение
- Технологии
- Архитектура
- Установка и запуск
- Как проверить решение
- Данные и интеграции
- Тестирование
- Ограничения
- Развёрнутая версия
Проблема и пользователи
Сотрудники получают уведомления об обучении, менторстве и других HR-активностях, но не всегда понимают, как эти действия связаны с карьерным ростом. Из-за этого обязательные программы выполняются формально, а добровольные активности получают низкую вовлечённость.
Career Quest предназначен для двух ролей:
- сотрудник — видит только собственный профиль, историю, карьерную траекторию и рекомендации;
- HR — видит агрегированную аналитику по навыкам и участию, а также может импортировать новый датасет.
Проект работает только с синтетическими данными из набора хакатона.
Что реализовано
Кабинет сотрудника
- профиль с ролью, грейдом, стажем и подразделением;
- уровни навыков по шкале
0–5; - траектория от текущего к целевому грейду;
- процент готовности и список разрывов по навыкам;
- история пройденных и пропущенных активностей;
- 1–3 персональные рекомендации;
- развёрнутый ответ «Почему мне нужна эта активность?»;
- проверяемые факты и расчёт под текстовым объяснением;
- завершение активности с немедленным пересчётом навыков и траектории.
Рекомендательная система
- фильтрация по роли, грейду, обязательности, prerequisites и прошлым завершениям;
- исключение обязательных мероприятий из рекомендаций;
- учёт карьерной цели и
focus_skills, если они заданы; - учёт требований целевого профиля и критических навыков;
- учёт положительной и отрицательной истории участия;
- прогноз вероятности завершения с помощью Logistic Regression;
- штраф за повторные незавершённые похожие активности;
- разнообразие форматов в Top-3;
- повторная рекомендация завершённого события разрешена только для recurring-события
EV_036.
Итоговый score:
0.35 × покрытие skill gap
+ 0.20 × критичность навыка
+ 0.10 × достижимый прирост
+ 0.15 × ML-вероятность завершения
+ 0.10 × соответствие истории участия
+ 0.10 × доступность
- штраф за негативный паттерн
- штраф за повторение
AI-объяснение
Рекомендательный движок определяет, что рекомендовать. OpenAI, если настроен, объясняет, почему уже выбранные активности полезны сотруднику.
Recommendation Engine
↓
Evidence Builder
↓
OpenAI Explanation Service
↓
Structured Explanation
↓
Frontend
- один компактный запрос формирует объяснения сразу для всего Top-3;
- в модель не передаются ФИО, manager ID и полная история сотрудника;
- evidence содержит целевой грейд, выбранные event ID, skill gaps, gain, историю и вероятность завершения;
- ответ проверяется: AI не может изменить event ID, порядок рекомендаций или числовые значения;
- поддерживаются объяснения на английском, русском и казахском языках;
- при отсутствии ключа, таймауте, ошибке API или некорректном JSON используется подробный детерминированный fallback;
- evidence hash и
RecommendationSnapshotпозволяют повторно использовать объяснение, пока данные сотрудника и набор рекомендаций не изменились; - логируется время вызова и источник объяснения, но не секреты.
Основная функциональность полностью работает без OpenAI.
HR-экран
- количество сотрудников;
- общий completion rate;
- наиболее частые skill gaps;
- сотрудники без доступного следующего шага;
- участие, завершения, пропуски и отказы по активностям;
- импорт четырёх файлов датасета через интерфейс.
Безопасность и воспроизводимость
- отдельные права сотрудника и HR проверяются backend-сервисом;
- сотрудник не может открыть профиль другого сотрудника;
- токен входа подписывается Django и действует 12 часов;
- изменение прогресса транзакционно и поддерживает
Idempotency-Key; - импорт выполняется атомарно;
- приложение запускается через Docker Compose одной командой;
- доступны health checks и Swagger/OpenAPI.
Как работает решение
- При первом запуске backend применяет миграции и загружает стартовый датасет в PostgreSQL.
- Пользователь входит под ролью сотрудника или HR.
- Для сотрудника backend определяет целевой профиль из
career_goal. Если цель отсутствует, используется следующий грейд текущей роли. - Требования
role_profiles.required_skillsсравниваются с текущими навыками. Отсутствующий навык считается равным0. - Из каталога исключаются обязательные, неподходящие, недоступные и уже завершённые события. Проверяются prerequisites.
- Для оставшихся событий рассчитываются карьерная полезность, ожидаемый прирост, история участия и вероятность завершения.
- Движок формирует Top-3 и evidence для каждого результата.
- OpenAI формирует один структурированный ответ для Top-3 либо включается локальный fallback.
- Frontend показывает развёрнутое объяснение и раскрываемый блок с исходными фактами.
- После завершения активности применяются правила
gainиmax_level, затем пересчитывается готовность к целевому грейду.
Технологии
Backend
- Python
3.12+; - Django
5.2–6.0; - Django REST Framework;
- PostgreSQL 17;
- psycopg;
- Gunicorn;
- django-cors-headers;
- drf-spectacular — OpenAPI и Swagger UI;
- WhiteNoise — статические файлы;
- pytest, pytest-django и Ruff — тестирование и проверка кода.
Frontend
- TypeScript 5.8;
- Next.js 16;
- React 19;
- ESLint.
ML и AI
- scikit-learn;
- pandas;
- joblib;
- Logistic Regression для оценки вероятности завершения активности;
- OpenAI Chat Completions API для опционального объяснения рекомендаций;
- evidence-grounded fallback без внешнего API.
Инфраструктура
- Docker;
- Docker Compose;
- health checks для PostgreSQL и backend.
Архитектура
┌─────────────────────┐
│ Next.js Frontend │
│ employee / HR views │
└──────────┬──────────┘
│ REST + Bearer token
▼
┌────────────────────────────────────────────┐
│ Django REST API │
│ │
│ Auth ─ Employee/Profile ─ Activity service │
│ │ │
│ ▼ │
│ Recommendation Engine │
│ ├─ eligibility filters │
│ ├─ multi-factor scoring │
│ ├─ completion ML model │
│ └─ diversity selection │
│ │ │
│ ▼ │
│ Evidence + Explanation Service │
│ ├─ OpenAI, если настроен │
│ └─ deterministic fallback │
│ │
│ HR Analytics ─ Dataset Import │
└──────────┬─────────────────────────────────┘
│ Django ORM
▼
┌─────────────────────┐
│ PostgreSQL │
│ profiles, history, │
│ skills, snapshots │
└─────────────────────┘
Структура репозитория:
backend/ Django API, доменные сервисы, ML и тесты
frontend/ Next.js приложение
data/starter/ стартовые JSON/CSV
data/ml/ модель, обучающая выборка, метрики и коэффициенты
docs/ архитектура, системный дизайн и контракт данных
compose.yaml локальная инфраструктура
Дополнительная документация:
Установка и запуск
Вариант 1 — Docker Compose
Требования:
- Docker;
- Docker Compose v2;
- свободные порты
3000и18000.
cp .env.example .env
docker compose up --build
После запуска:
- приложение: http://localhost:3000
- Swagger UI: http://localhost:18000/api/docs/
- Django Admin: http://localhost:18000/admin/
- readiness check: http://localhost:18000/api/v1/health/ready/
Первый запуск автоматически:
- создаёт PostgreSQL;
- применяет миграции;
- загружает
data/starter; - создаёт демонстрационные аккаунты.
Повторные запуски сохраняют PostgreSQL volume и прогресс сотрудников.
Остановить приложение:
docker compose down
Полностью удалить локальную базу и заново загрузить seed:
docker compose down -v
docker compose up --build
Команда с
-vудаляет все локальные изменения прогресса.
Настройка OpenAI
OpenAI не обязателен. Для включения AI-текста заполните .env:
OPENAI_API_KEY=...
OPENAI_MODEL=gpt-4.1-mini
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_TIMEOUT_SECONDS=8
После изменения переменных перезапустите сервисы:
docker compose up --build -d
Реальный API-ключ в репозитории не хранится.
Локальная разработка без Docker
Backend:
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
python manage.py migrate
python manage.py load_starter_data --if-empty --path ../data/starter
python manage.py runserver 0.0.0.0:8000
Frontend в отдельном терминале:
cd frontend
npm install
cp .env.example .env.local
npm run dev
При локальном запуске без Docker по умолчанию backend использует SQLite, если не заданы переменные PostgreSQL.
Как проверить решение
Сценарий сотрудника
- Откройте http://localhost:3000/login.
- Выберите роль Employee.
- Войдите как
e0028с паролемemployee-demo. - Проверьте профиль, навыки и траекторию
Middle → Senior. - Изучите Top-3 и блок «Почему этот шаг».
- Обратите внимание: низкий Public Speaking не обязан становиться рекомендацией №1 — учитываются критичность System Design и история участия.
- Раскройте «Show evidence and calculation» и сопоставьте объяснение с уровнями навыков и историей.
- Нажмите завершение рекомендованной активности.
- Убедитесь, что изменились уровень навыка и процент готовности.
Сценарий HR
- Выйдите из аккаунта сотрудника.
- Войдите как
hrс паролемhr-demo. - Проверьте частые skill gaps, completion rate и статистику участия.
- Откройте экран импорта и убедитесь, что он принимает четыре файла стартового формата.
Доступен вход для любого стартового сотрудника: логин — employee ID в нижнем регистре, например e0001, пароль — employee-demo.
Данные и интеграции
Стартовый датасет
При запуске используются:
data/starter/employees.json— 200 синтетических профилей;data/starter/events.json— 40 событий;data/starter/skills.json— 60 навыков и role profiles;data/starter/activity_history.csv— 24 месяца истории, 2743 записи.
Правила данных, реализованные в коде:
- уровень навыка находится в диапазоне
0–5; - отсутствующий навык означает уровень
0; - требования берутся из
role_profiles.required_skills; critical_skillsполучают повышенный приоритет;- обязательные активности не рекомендуются;
- прирост ограничивается
gain,max_levelи верхней границей5; - prerequisites являются жёстким фильтром;
- завершённые события обычно не рекомендуются повторно;
- исключение для повторяемого события —
EV_036; career_goal: nullозначает переход к следующему грейду текущей роли.
Импортированный уровень навыков считается актуальным assessment snapshot. Исторические завершения после last_review_date повторно автоматически не применяются. Новый completion через приложение обновляет прогресс сразу.
ML-артефакты
В data/ml/ находятся:
activity_completion_logistic.joblib;activity_completion_logistic.csv;activity_completion_logistic_metrics.json;activity_completion_logistic_coefficients.csv.
Зафиксированные в файле метрик показатели temporal validation:
- ROC-AUC:
0.654; - PR-AUC:
0.774; - F1:
0.805.
Если joblib-модель недоступна или несовместима, backend использует сглаженные исторические completion rates.
Внешняя интеграция
Единственная опциональная внешняя интеграция — OpenAI API. Векторная база, RAG, web search и multi-agent pipeline не используются.
Тестирование
Backend:
cd backend
pytest
ruff check .
python manage.py check
python manage.py makemigrations --check --dry-run
Frontend:
cd frontend
npm run lint
npm run build
Тесты OpenAI используют mocks и не расходуют API-кредиты. Покрыты fallback без ключа, ошибка API, три языка, нейтральное описание негативной истории, защита ID и числовых фактов, а также один вызов для Top-3.
Ограничения
- Это hackathon MVP, а не production HR-система.
- Используется общий демонстрационный пароль сотрудников.
- Подписанные токены не имеют refresh flow и серверного revoke/logout списка.
- Корпоративный OIDC/SSO не подключён.
- Для HR не реализованы ограничения по подразделениям: HR-роль видит общую агрегированную статистику.
- Frontend переключается между русским и английским; казахское объяснение доступно через backend параметр
locale=kk, но отдельного переключателяKKв UI пока нет. - После импорта новых employee ID пользовательские аккаунты для них автоматически не создаются; импортированные профили доступны данным и HR API, но для входа потребуется отдельное создание пользователя.
- HR dashboard вычисляет часть агрегатов во время запроса; отдельный background worker и Redis-кэш не используются.
- Без
OPENAI_API_KEYпоказывается подробный шаблонный fallback, а не сгенерированный OpenAI текст. - Качество рекомендаций зависит от полноты синтетического профиля, истории и каталога событий.
- Публичный рейтинг сотрудников намеренно отсутствует.
Развёрнутая версия
Публичная deployed-версия в репозитории не указана. Решение воспроизводится локально через Docker Compose:
Лицензия и данные
Отдельный файл лицензии в репозитории отсутствует. Датасет синтетический и предназначен для демонстрации решения в рамках хакатона.
Авторы коммитов
История коммитов
- 2026-09-23 17:46readme finalNursultan Renatuly
- 2026-09-23 17:38final metrics updatedNursultan Renatuly
- 2026-09-23 17:00datasteNurda
- 2026-09-23 16:50recommendation (#1)nenurd44
- 2026-09-23 16:49recommendationNurda
- 2026-09-23 16:41fixed login errorsNursultan Renatuly
- 2026-09-23 16:33Delete update_employee_skills.ipynbalikhrzh
- 2026-09-23 16:33Delete train_activity_completion_logistic.ipynbalikhrzh
Все коммиты (25)
- 2026-09-23 16:33Delete skills.jsonalikhrzh
- 2026-09-23 16:33Delete prepare_activity_history_ml.ipynbalikhrzh
- 2026-09-23 16:33Delete events.jsonalikhrzh
- 2026-09-23 16:32Delete employees_updated.jsonalikhrzh
- 2026-09-23 16:32Delete activity_history_enriched.csvalikhrzh
- 2026-09-23 16:32Delete activity_history.csvalikhrzh
- 2026-09-23 16:32Delete activity_completion_logistic_validation_predictions.csvalikhrzh
- 2026-09-23 16:32Delete activity_completion_logistic_metrics.jsonalikhrzh
- 2026-09-23 16:32Delete activity_completion_logistic_coefficients.csvalikhrzh
- 2026-09-23 16:31Delete activity_completion_logistic.joblibalikhrzh
- 2026-09-23 16:31Delete activity_completion_logistic.csvalikhrzh
- 2026-09-23 16:31Delete employees.jsonalikhrzh
- 2026-09-23 16:28dataset preparing and changesalikhrzh
- 2026-09-23 16:03enhanced app runNursultan Renatuly
- 2026-09-23 15:52main codeNursultan Renatuly
- 2026-09-23 14:56backbone codeNursultan Renatuly
- 2026-09-23 14:00first commitNursultan Renatuly
Структура репозитория (131 файлов)
.env.example .gitignore README.md backend/.dockerignore backend/.env.example backend/Dockerfile backend/README.md backend/apps/__init__.py backend/apps/accounts/__init__.py backend/apps/accounts/admin.py backend/apps/accounts/apps.py backend/apps/accounts/authentication.py backend/apps/accounts/migrations/0001_initial.py backend/apps/accounts/migrations/__init__.py backend/apps/accounts/models.py backend/apps/accounts/serializers.py backend/apps/accounts/views.py backend/apps/activities/__init__.py backend/apps/activities/admin.py backend/apps/activities/apps.py backend/apps/activities/migrations/0001_initial.py backend/apps/activities/migrations/0002_activityhistory_assigned_by_and_more.py backend/apps/activities/migrations/__init__.py backend/apps/activities/models.py backend/apps/activities/services.py backend/apps/activities/views.py backend/apps/analytics/__init__.py backend/apps/analytics/apps.py backend/apps/analytics/services.py backend/apps/analytics/views.py backend/apps/catalog/__init__.py backend/apps/catalog/admin.py backend/apps/catalog/apps.py backend/apps/catalog/migrations/0001_initial.py backend/apps/catalog/migrations/0002_eventskillgain_event_gain_1_5_and_more.py backend/apps/catalog/migrations/0003_event_prerequisites_event_upcoming_sessions_and_more.py backend/apps/catalog/migrations/__init__.py backend/apps/catalog/models.py backend/apps/core/__init__.py backend/apps/core/apps.py backend/apps/core/exceptions.py backend/apps/core/permissions.py backend/apps/core/urls.py backend/apps/core/views.py backend/apps/employees/__init__.py backend/apps/employees/admin.py backend/apps/employees/apps.py backend/apps/employees/migrations/0001_initial.py backend/apps/employees/migrations/0002_employeeskill_employee_skill_level_0_5.py backend/apps/employees/migrations/0003_employee_career_goal_employee_hire_date_and_more.py backend/apps/employees/migrations/__init__.py backend/apps/employees/models.py backend/apps/employees/serializers.py backend/apps/employees/services.py backend/apps/employees/views.py backend/apps/imports/__init__.py backend/apps/imports/apps.py backend/apps/imports/management/__init__.py backend/apps/imports/management/commands/__init__.py backend/apps/imports/management/commands/load_starter_data.py backend/apps/imports/management/commands/seed_demo.py backend/apps/imports/services.py backend/apps/imports/views.py backend/apps/recommendations/__init__.py backend/apps/recommendations/admin.py backend/apps/recommendations/apps.py backend/apps/recommendations/completion.py backend/apps/recommendations/engine.py backend/apps/recommendations/explainer.py backend/apps/recommendations/migrations/0001_initial.py backend/apps/recommendations/migrations/__init__.py backend/apps/recommendations/models.py backend/apps/recommendations/scoring.py backend/apps/recommendations/views.py backend/career_quest_backend.egg-info/PKG-INFO backend/career_quest_backend.egg-info/SOURCES.txt backend/career_quest_backend.egg-info/dependency_links.txt backend/career_quest_backend.egg-info/requires.txt backend/career_quest_backend.egg-info/top_level.txt backend/config/__init__.py backend/config/asgi.py backend/config/settings.py backend/config/urls.py backend/config/wsgi.py backend/manage.py backend/pyproject.toml backend/tests/__init__.py backend/tests/test_explainer.py backend/tests/test_health.py backend/tests/test_mvp.py compose.yaml data/ml/activity_completion_logistic.csv data/ml/activity_completion_logistic.joblib data/ml/activity_completion_logistic_coefficients.csv data/ml/activity_completion_logistic_metrics.json data/starter/README.kz.md data/starter/README.md data/starter/README.ru.md data/starter/activity_history.csv data/starter/employees.json data/starter/events.json data/starter/skills.json docs/ARCHITECTURE.md docs/DATASET.md docs/DECISIONS.md docs/SYSTEM_DESIGN.md docs/reference-recommender/README.md frontend/.dockerignore frontend/.env.example frontend/Dockerfile frontend/README.md frontend/app/employee/[id]/page.tsx frontend/app/globals.css frontend/app/hr/page.tsx frontend/app/import/page.tsx frontend/app/layout.tsx frontend/app/login/page.tsx frontend/app/page.tsx frontend/components/auth-provider.tsx frontend/components/header.tsx frontend/components/locale-provider.tsx frontend/components/progress-ring.tsx frontend/eslint.config.mjs frontend/lib/api.ts frontend/lib/i18n.ts frontend/lib/types.ts frontend/next-env.d.ts frontend/next.config.mjs frontend/package-lock.json frontend/package.json frontend/tsconfig.json
Ветки (2)
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.