AAYMA
RU
Войти

Career Quest

Навигатор развития сотрудника Halyk Bank: рекомендует 1–3 учебные активности под требования следующего грейда с объяснением, есть AI-наставник…

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

О проекте

Команда: NovaAI
Кейс HackAlem.ai: Менеджмент — Halyk Bank · кейс 1
Стадия: Доведённый продукт

Задача кейса: «Career Quest»: AI-навигатор, связывающий навыки сотрудника с шагами развития

Суть

Навигатор развития сотрудника Halyk Bank: рекомендует 1–3 учебные активности под требования следующего грейда с объяснением, есть AI-наставник, личный прогресс, демо-магазин наград и HR-аналитика дефицитов компетенций.

Как устроено

Импорт официального датасета (employees, events, skills, activity_history) с валидацией. Для каждого события score = Σ gap × effective_gain × criticality × acceptance, где gap берётся из требований роли и грейда, critical_skills имеют вес 3, acceptance сглажен по Лапласу по истории навыка и формата. Учитываются prerequisites, будущие сессии и исключение обязательных и пройденных активностей. AI-коуч в режиме только чтения опирается на факты профиля (prompts/coach.md), есть офлайн-режим. Роли employee/HR/manager с разграничением доступа, SQLite, интерфейс на KK/RU/EN.

Ключевые решения

  • скоринг разрыва навыков с весами критичности
  • сглаживание Лапласа по истории участия
  • проверка prerequisites
  • RBAC по токенам
  • i18n KK/RU/EN

Особенности

Рекомендация не сводится к «прокачай самый слабый навык»: отдельный тест test_jury_case_no_minimum_skill_rule проверяет, что учитываются критичность и история отказов. Геймификация без публичных рейтингов, демо-Coins только за добровольное закрытие разрывов. В README честно разделены проверенный и ожидаемый эффект.

Стек

Python 3.12 · SQLite · React · TypeScript · Vite · pnpm · nginx · Docker Compose


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-7840be72-novaai.

README

README.md

Career Quest · NovaAI

AI-навигатор развития сотрудника для HackAlem AI, кейс Halyk Bank. Приложение связывает обучение с требованиями следующего грейда: показывает 1–3 шага, объясняет выбор через разрыв навыков, критичность и историю участия, обновляет личный прогресс и предоставляет HR служебную аналитику. Публичных рейтингов сотрудников нет.

Зачем мы создали Career Quest

Сотрудник получает приглашения на курсы и напоминания о дедлайнах, но не всегда понимает, как конкретная активность поможет его карьере. Обучение превращается в формальность, добровольные мероприятия пропускаются, а HR видит отдельные результаты вместо понятной картины развития.

Наша цель — помочь сотруднику ответить на три вопроса: куда я расту, что сделать следующим и почему именно этот шаг важен сейчас. Для банка это способ связать каталог обучения с реальными дефицитами компетенций и сделать помощь HR адресной.

Как это работает для сотрудника

  1. Сотрудник видит свой профиль, личного персонажа и требования следующего грейда.
  2. Получает до трёх доступных активностей с объяснением: какой разрыв они закрывают, насколько навык важен для следующего уровня и что показывает история участия.
  3. Может обсудить рекомендацию с AI-наставником, который опирается на факты профиля.
  4. После выполнения видит рост соответствующих навыков и продвижение к цели.
  5. За добровольное закрытие разрывов получает личные демо-Coins и выбирает награду.

Например, самый слабый навык не обязательно является лучшим следующим шагом: если сотрудник неоднократно пропускал публичные выступления, а для Senior критичен System Design, алгоритм учитывает оба обстоятельства. Выбор не сводится к минимуму одного показателя. Точная проверка этого сценария описана ниже.

Персонаж — визуальное отражение собственного развития. Выбор аниме или футбольного стиля не влияет на навыки. Сотрудник не соревнуется с коллегами, а видит свои достижения и следующий доступный шаг.

Польза для Halyk Bank

Для когоЧто даёт решение
СотрудникПонятную связь обучения с карьерой и объяснимый следующий шаг
HRСрез дефицитных компетенций и признаки, по которым можно предложить помощь
РуководительСлужебную картину развития своей команды в пределах разрешённого доступа
БанкОснование для более адресного использования обучения и проверки его востребованности

Категории наград «Для работы», «Для себя», «Для семьи и детей» связывают профессиональный рост с личными интересами сотрудника. Семейный поход в кино или мастер-класс — пример заботы о близких, а не отдельная игровая задача. Coins связаны только с добровольным развитием профессиональных навыков; обязательные процессы и публичность профиля не вознаграждаются. Все награды в текущей версии демонстрационные.

Ожидаемый эффект, который ещё нужно проверить в пилоте: рост завершения добровольных активностей и доли закрытых разрывов, более понятные карьерные шаги, возможное улучшение удовлетворённости сотрудников. Измерять предлагаем долю принятых рекомендаций, завершение добровольных активностей, изменение skill gaps и обратную связь о полезности объяснений. Рост eNPS, снижение оттока и экономию бюджета мы пока не заявляем как достигнутые результаты.

Быстрый запуск для жюри (Windows, без Docker)

Требуются Python 3.12+, Node.js 24 и pnpm 11. В корне репозитория один раз установить зависимости:

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r backend/requirements.txt
pnpm --dir frontend install --frozen-lockfile

Затем запуск одной командой:

.\start.bat

Дождитесь строки Career Quest is ready: http://127.0.0.1:... и откройте именно этот адрес. Порты выбираются автоматически; занятому порту находится замена. Окно нужно оставить открытым. Ctrl+C останавливает только запущенный им экземпляр. После перезагрузки компьютера команду запуска нужно повторить.

Без локального .env используются демонстрационные аккаунты:

ТокенДоступ
demo-employeeСвой профиль E0028
demo-hrHR-аналитика и импорт
demo-managerСлужебные данные только E0028
demo-colleagueПолучатель адресованной ему карточки E0029

Если настроен .env, действуют токены из него; переменные среды имеют приоритет. Демо-токены предназначены для локальной проверки. Серверы слушают только 127.0.0.1. Для Linux/macOS после установки зависимостей запуск: .venv/bin/python run.py.

Официальный набор и произвольный сотрудник

Для отдельной демонстрации официального набора, без изменения существующего прогресса:

.\start.bat --dataset examples/official --database .runtime/jury.sqlite3 --employee E0028 --offline

Для другого профиля остановить этот экземпляр и выполнить:

.\start.bat --database .runtime/jury.sqlite3 --employee E0030 --offline

Войти тем же employee-токеном. --employee привязывает аккаунт к ID на сервере при запуске; браузер не может переключиться на чужой профиль. Подходит и для новых ID, загруженных жюри. Если ID отсутствует, профиль не открывается; войдите HR и загрузите соответствующий набор. --offline отключает внешний AI только для этого запуска.

--dataset требует отдельного --database. Набор загружается при создании новой базы. Существующая база сохраняется: изменить её содержимое можно через HR-импорт. По умолчанию база .runtime/career-quest.sqlite3; CQ_DB_PATH задаёт другой путь. Ранее использовавшийся локальный сеанс может находиться в .runtime/qa.sqlite3.

Проверка основного сценария за 5 минут

  1. Запустить отдельную базу с официальным набором командой выше.
  2. Войти сотрудником. Проверить роль, грейд, навыки, историю, траекторию и дату среза.
  3. Раскрыть «Почему именно это?» у рекомендации: требования Senior, разрыв, критичность, история и оценка принятия формата показаны явно.
  4. Нажать «Демо: завершить активность». Навык растёт с учётом gain/max_level, траектория пересчитывается. Повторное завершение не даёт повторного роста.
  5. Открыть Halyk Store: за добровольное закрытие разрыва появились демо-Coins. Выбрать доступную награду, проверить сумму и подтвердить демо-обмен.
  6. Выйти и войти как HR. Проверить дефициты компетенций, обязательное обучение, фильтры «без рекомендованного шага» и стагнации, черновик персонального предложения.
  7. Переключить интерфейс KK/RU/EN. Нестандартные названия входного датасета остаются на исходном языке; уровень грейда не изменяется при переводе.

Магазин и демо-завершение доступны при DEMO_MODE=true (launcher включает этот режим по умолчанию, если переменная не задана). Это не подтверждение реального обучения.

Загрузка проверочных файлов жюри

Войти HR, выбрать четыре файла с исходными именами: employees.json, events.json, skills.json, activity_history.csv. Поддерживаются схема организаторов v1.0 и небольшой пример из data/. ZIP напрямую не принимается. Лимит комплекта — 12 MiB, кодировка UTF-8, BOM допустим.

  1. «Проверить файлы» выполняет валидацию и показывает состав и дату среза без записи.
  2. «Заменить датасет» заменяет профили/историю, сбрасывает демо-Coins и обмены, отзывает выданные карточки. Предупреждение показано до подтверждения.
  3. Изменение файлов или ревизии между проверкой и импортом возвращает 409.
  4. Неизвестная ссылка, дубликат ID, навык 6, неверный CSV-статус или повреждённый JSON отклоняются; действующая база сохраняется.

Официальный комплект: 200 профилей, 40 мероприятий, 60 навыков, 2743 записи истории. Дополнительные профили и история принимаются в той же схеме; количество не зафиксировано на 200. Для просмотра нового сотрудника использовать --employee ID после импорта. Менеджеры и токены не создаются из данных автоматически.

Датасет предоставлен только для хакатона. Репозиторий предназначен для участников и жюри; комплект examples/official нельзя переносить в публичные материалы вне разрешённого организаторами контура. README организаторов сохранены рядом с файлами.

Скоринг и обработка истории

Для навыка события:

gap = max(0, required(next_grade, current_role) - current)
effective_gain = min(gap, gain, max(0, max_level - current))
p_skill = (completed_skill + 1) / (attempts_skill + 2)
p_format = (completed_format + 1) / (attempts_format + 2)
acceptance = (p_skill + p_format) / 2
score_event = sum(gap * effective_gain * criticality * acceptance)
  • Требования роли/грейда берутся из role_profiles. Вес critical_skills = 3, остальных = 1: это явно выбранные веса алгоритма.
  • Учитываются роль, грейд, prerequisites и будущие сессии. self_paced не требуют даты сессии. mandatory и уже начатые курсы не рекомендуются как новые.
  • Завершённые неповторяемые события исключаются; EV_036 допускает повторение.
  • completed повышает оценку принятия; dropped/no_show/declined учитываются как незавершённые попытки. in_progress, overdue и обязательные активности не ухудшают оценку добровольного формата. При отсутствии истории действует сглаживание 0.5.
  • Это эвристическая оценка, не калиброванная вероятность и не прогноз увольнения.
  • Официальная дата расчётов — meta.as_of_date (2026-10-01). Навыки из профиля дополняются completed строго после last_review_date с ограничением max_level. Пересчёт происходит один раз при импорте исходного набора, а не при чтении базы.
  • Цель — следующий грейд текущей роли. career_goal сохраняется, но траектория смены профессии пока не реализована. Для Lead используются требования Lead.

Почему это не выбор самого низкого навыка

Тест test_jury_case_no_minimum_skill_rule задаёт System Design=2, Public Speaking=2, три no_show клуба и доступный EV_006. Приоритет получает System Design с учётом требований Senior, критичности и истории.

На полном исходном наборе у E0028 System Design после пересчёта становится 3, а ряд курсов уже пройден. Поэтому первые рекомендации — Kubernetes in Practice, Cloud Certification Prep и Mentor Track. Мы не заставляем алгоритм выбирать System Design вопреки данным. Отдельный тест использует изменённую копию профиля.

AI-наставник

Скоринг выбирает мероприятия; LLM объясняет переданные факты и предлагает план. Без API приложение работает в явно обозначенном режиме правил. Для внешней модели скопировать .env.example в .env и заполнить локально:

OPENAI_API_KEY=YOUR_API_KEY
OPENAI_MODEL=gpt-6-luna
ALLOW_EXTERNAL_AI=true

Ключ не отправлять в чат, не писать в .env.example и не коммитить. После изменения настроек перезапустить приложение без --offline. Статус «LLM настроена» означает наличие настроек; успешный ответ помечается LLM. Ошибка/таймаут провайдера даёт явно обозначенный резервный ответ по правилам. Доступность модели и API-биллинг зависят от проекта владельца ключа.

Провайдер получает вопрос, до шести сообщений и факторы только своего профиля. ID и сырая история автоматически не передаются. Текст вопроса может содержать то, что написал пользователь. Используются Responses API, store=false, пустой список инструментов. Это не обещание отсутствия хранения на стороне провайдера. Промпт: backend/coach.py: PROMPT. Максимум 8с на генерацию, 3 параллельных запроса, 20 запросов/минуту на аккаунт в процессе. Диалог в нашей БД не сохраняется.

У чата нет API записи: он не подтверждает обучение, не изменяет навыки/Coins и не читает чужие профили. Текст LLM может ошибаться; рядом доступны исходные факторы. Официальная документация OpenAI.

HR, приватность и награды

Сотрудник видит свой профиль. HR — агрегаты, служебные ID/роль/грейд, статус следующего шага и обязательное обучение. Руководитель ограничен серверным MANAGER_ACCOUNTS_JSON. Личные уровни навыков, добровольная история и диалоги в служебную проекцию не входят. Сигнал стагнации — более шести календарных месяцев без completed; отсутствие истории не доказывает отсутствие обучения. «Три пропуска рекомендаций» применяется только при явном recommended=true в расширенном демо-CSV. assigned_by=manager/hr в официальном наборе не считается журналом AI-рекомендаций. Подбор ментора — черновик запроса, без выдуманного имени и без отправки сообщений.

Повторные обязательные назначения есть в официальной истории: показывается последнее назначение с индивидуальным due_date, старый completed не скрывает новую просрочку. Баллов за mandatory нет. Демо-награда = 100 Coins за закрытый уровень разрыва в добровольной активности. Импорт и старые завершения не начисляют Coins задним числом. Начисление и прогресс атомарны в SQLite. Повтор event_id не награждается; повтор request_id не списывает повторно. Транзакция защищает от одновременной двойной траты. Награды условные, настоящие сертификаты и банковские обязательства не создаются.

Добровольная карточка показывает только псевдоним, стиль и выбранные завершённые добровольные достижения конкретным зарегистрированным получателям. Уровни навыков, баланс, грейд и история не публикуются. Доступ можно отозвать; уже увиденное нельзя «забрать обратно». Рейтингов, наград за публичность и сравнения коллег нет.

Архитектура

КомпонентНазначение
backend/dataset.py, official.pyСтрогая валидация, адаптер официального формата
backend/engine.pyСкоринг, фильтры, прогресс
backend/main.pyFastAPI, роли, импорт, ревизии
backend/storage.pySQLite, транзакции, постоянное состояние
backend/reporting.py, insights.pyHR/manager-проекции и сигналы поддержки
backend/coach.pyЧат, факты, опциональная LLM и fallback
backend/rewards.py, sharing.pyЛичный кошелёк и адресный показ достижений
frontend/srcReact + TypeScript + Vite, адаптивный CSS, KK/RU/EN
run.py, start.batЛокальный запуск, свободные порты, проверка proxy

Авторизация демо использует Bearer-токены в памяти вкладки, не URL/localStorage. В localStorage хранятся только язык и стиль. Секреты находятся в серверной среде/.env. .env читается как буквальные KEY=value, без исполнения команд и интерполяции.

Проверки и воспроизводимость

$env:ALLOW_EXTERNAL_AI="false"
.\.venv\Scripts\python.exe -m unittest discover -s tests -v
.\start.bat --smoke --offline

Тесты используют отдельные временные SQLite. Они проверяют официальный набор, пересчёт всех 200 профилей, кейс жюри, роли, ошибки импорта, ревизии, повторное завершение, обмен и конкурентное списание, fallback AI и конфигурацию. --smoke собирает интерфейс, запускает оба сервера, проверяет страницу и API через proxy и останавливает свои процессы. Реальный внешний AI в тестах не вызывается. Результаты последней проверки: docs/verification.md.

Диагностика: ERR_CONNECTION_REFUSED означает, что сервер по этому адресу не отвечает; запустите start.bat и используйте новый напечатанный адрес. Если процесс завершился, смотрите .runtime/backend-*.log и .runtime/frontend-*.log. При 409 обновите экран. При ошибке токена используйте токен из серверной конфигурации, без кавычек и пробелов.

Docker (альтернатива)

docker compose up --build

Интерфейс: http://localhost:8080. Нужен работающий Docker Engine. В текущей среде контейнерный запуск не проверен; основной проверенный путь — start.bat без Docker.

Границы демо

Нет SSO, интеграции LMS, реальной выдачи наград и каталога конкретных менторов. Демо-кнопка имитирует выполнение доступной активности в дату среза и не доказывает посещение. Статус готовности по навыкам не гарантирует повышение. Карта навыков использует шкалы требований; радар 60 навыков не реализован. Защита агрегатов малых групп, промышленный аудит и нагрузочная проверка нужны перед банковским внедрением.

Ключевой бизнес-эффект — сделать связь обучения с карьерой понятной и дать HR инструмент помощи. Рост завершаемости, eNPS и снижение оттока пока гипотезы, а не измеренные результаты пилота.

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

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

abilmnnsur 13

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

  • 2026-09-23 16:48Merge pull request #1 from BAITC-Hacks/masterabilmnnsur
  • 2026-09-23 16:37Explain project purpose and business valueadmin
  • 2026-09-23 16:35Prepare submission docs and jury verificationadmin
  • 2026-09-23 16:24Support official Career Quest datasetadmin
  • 2026-09-23 16:11Add Halyk Store, local launcher and AI configurationadmin
  • 2026-09-23 15:52Add Halyk Store and personal rewardsadmin
  • 2026-09-23 15:38Fix login token validationadmin
  • 2026-09-23 15:23Add read-only career coach and verify applicationadmin
Все коммиты (13)
  • 2026-09-23 15:08feat: add trilingual UI and stagnation supportadmin
  • 2026-09-23 14:53feat: redesign employee workspaceadmin
  • 2026-09-23 14:46feat: add scoped manager access and employee training overviewadmin
  • 2026-09-23 14:38feat: add validated imports, persistent progress and private card sharingadmin
  • 2026-09-23 14:08feat: bootstrap Career Quest with explainable recommendationsadmin
Структура репозитория (67 файлов)
.dockerignore
.env.example
.gitattributes
.gitignore
README.md
backend/Dockerfile
backend/__init__.py
backend/coach.py
backend/config.py
backend/dataset.py
backend/engine.py
backend/insights.py
backend/main.py
backend/official.py
backend/reporting.py
backend/requirements.txt
backend/rewards.py
backend/sharing.py
backend/storage.py
compose.yaml
data/activity_history.csv
data/employees.json
data/events.json
data/skills.json
docs/verification.md
examples/official/README.kz.md
examples/official/README.md
examples/official/README.ru.md
examples/official/activity_history.csv
examples/official/employees.json
examples/official/events.json
examples/official/skills.json
examples/stagnation/activity_history.csv
examples/stagnation/employees.json
examples/stagnation/events.json
examples/stagnation/skills.json
frontend/.dockerignore
frontend/Dockerfile
frontend/index.html
frontend/nginx.conf
frontend/package.json
frontend/pnpm-lock.yaml
frontend/pnpm-workspace.yaml
frontend/src/Coach.tsx
frontend/src/EmployeeWorkspace.tsx
frontend/src/HrDashboard.tsx
frontend/src/Rewards.tsx
frontend/src/Sharing.tsx
frontend/src/i18n.ts
frontend/src/main.tsx
frontend/src/style.css
frontend/src/translations.json
frontend/vite.config.js
prompts/coach.md
prompts/explanation.md
run.py
start.bat
tests/test_api.py
tests/test_coach.py
tests/test_config.py
tests/test_dataset.py
tests/test_engine.py
tests/test_insights.py
tests/test_official.py
tests/test_reporting.py
tests/test_rewards.py
tests/test_sharing.py
Ветки (2)

Обсуждение 0 комментариев

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

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