AAYMA
RU
Войти

Career Quest

Веб-приложение, в котором сотрудник видит разрывы навыков до целевого грейда и получает 1–3 персональные HR-активности с объяснением, а HR видит…

Доведённый продукт
Команда «NAN» 11💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: 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.md

Career 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.

Как работает решение

  1. При первом запуске backend применяет миграции и загружает стартовый датасет в PostgreSQL.
  2. Пользователь входит под ролью сотрудника или HR.
  3. Для сотрудника backend определяет целевой профиль из career_goal. Если цель отсутствует, используется следующий грейд текущей роли.
  4. Требования role_profiles.required_skills сравниваются с текущими навыками. Отсутствующий навык считается равным 0.
  5. Из каталога исключаются обязательные, неподходящие, недоступные и уже завершённые события. Проверяются prerequisites.
  6. Для оставшихся событий рассчитываются карьерная полезность, ожидаемый прирост, история участия и вероятность завершения.
  7. Движок формирует Top-3 и evidence для каждого результата.
  8. OpenAI формирует один структурированный ответ для Top-3 либо включается локальный fallback.
  9. Frontend показывает развёрнутое объяснение и раскрываемый блок с исходными фактами.
  10. После завершения активности применяются правила 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

После запуска:

Первый запуск автоматически:

  1. создаёт PostgreSQL;
  2. применяет миграции;
  3. загружает data/starter;
  4. создаёт демонстрационные аккаунты.

Повторные запуски сохраняют 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.

Как проверить решение

Сценарий сотрудника

  1. Откройте http://localhost:3000/login.
  2. Выберите роль Employee.
  3. Войдите как e0028 с паролем employee-demo.
  4. Проверьте профиль, навыки и траекторию Middle → Senior.
  5. Изучите Top-3 и блок «Почему этот шаг».
  6. Обратите внимание: низкий Public Speaking не обязан становиться рекомендацией №1 — учитываются критичность System Design и история участия.
  7. Раскройте «Show evidence and calculation» и сопоставьте объяснение с уровнями навыков и историей.
  8. Нажмите завершение рекомендованной активности.
  9. Убедитесь, что изменились уровень навыка и процент готовности.

Сценарий HR

  1. Выйдите из аккаунта сотрудника.
  2. Войдите как hr с паролем hr-demo.
  3. Проверьте частые skill gaps, completion rate и статистику участия.
  4. Откройте экран импорта и убедитесь, что он принимает четыре файла стартового формата.

Доступен вход для любого стартового сотрудника: логин — 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:

http://localhost:3000

Лицензия и данные

Отдельный файл лицензии в репозитории отсутствует. Датасет синтетический и предназначен для демонстрации решения в рамках хакатона.

Звёзды
⭐ 2
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
25
Авторы
3
Файлы
131
Ветки
2

Авторы коммитов

alikhrzh 15Nursultan Renatuly 7Nurda 3

История коммитов

  • 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 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.