Career Quest
AI-навигатор развития: сотруднику показывает готовность к цели и 1–3 объяснимых шага развития, HR получает аналитику пробелов навыков, участия и…
О проекте
Команда: Arqau
Кейс HackAlem.ai: Менеджмент — Halyk Bank · кейс 1
Стадия: Доведённый продукт
Задача кейса: «Career Quest»: AI-навигатор, связывающий навыки сотрудника с шагами развития
Суть
AI-навигатор развития: сотруднику показывает готовность к цели и 1–3 объяснимых шага развития, HR получает аналитику пробелов навыков, участия и каталога. Есть чат Career AI и импорт данных жюри.
Как устроено
Датасет (сотрудники, история активностей, события, навыки) загружается с кросс-проверками. Текущий уровень считается как оценка на аттестации плюс рост от активностей, разрыв равен требованию грейда минус текущий уровень. Детерминированный RecommendationEngine отсекает недопустимые события (пререквизиты, аудитория, уже пройдено) и ранжирует остальные взвешенным скорингом. В скоринге учитываются критичность навыка, соответствие цели и «трения» из истории неявок. LLM gpt-4.1-mini через function calling с read-only инструментами только объясняет результат и симулирует «что если». Ответ, где упомянута активность не из данных, отбрасывается, без ключа работает fallback по правилам.
Ключевые решения
- weighted scoring
- eligibility filters
- function calling
- grounding-проверка ответов LLM
- HMAC-SHA256 токены
- тепловая карта отдел × навык
Метрики
Первая рекомендация закрывает критический навык: 97% (98/101) против 14% у наивного правила; невыполнимых рекомендаций 0 против 59%; расчёт для 200 сотрудников ~70 мс; ответ AI ~4.4 с
Особенности
Решения принимает детерминированный код, LLM только объясняет, и это обосновано для банка. Качество сравнивается с наивным бейзлайном «бери минимальный навык» на всех 200 сотрудниках. Честно помечаются «заблокированные» пробелы, когда каталог не может закрыть навык. Для проверки импорта подготовлен профиль-ловушка.
Стек
Python · FastAPI · Pydantic · React · TypeScript · Vite · Tailwind CSS · Docker · pytest · Vitest · Playwright
Модели
gpt-4.1-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-53d6003c-arqau.
README
README.md✦ Career Quest
AI-навигатор развития сотрудника: объяснимый следующий шаг вместо разрозненных HR-уведомлений
HackAlem AI · трек Halyk Bank · кейс «Career Quest»
1. Проблема и для кого
Сотрудник получает поток обучений, аттестаций и дедлайнов, но не видит, куда они ведут, поэтому проходит их формально. HR тратит бюджет на развитие полностью, но не видит, какие компетенции проседают и у кого нет следующего шага.
Career Quest показывает сотруднику его траекторию и подбирает 1–3 шага с понятным обоснованием, а HR получает срез по навыкам, участию и пробелам каталога.
| Пользователь | Что получает |
|---|---|
| 👤 Сотрудник (стаж 1–5 лет) | Профиль и цель, готовность к следующему грейду, 1–3 рекомендации с объяснением, пересчёт прогресса после выполнения, чат Career AI |
| 🧭 HR | Проседающие навыки, участие по активностям, сотрудники без подходящего шага, пробелы каталога, поддерживающие сигналы, AI-инсайты, импорт данных |
2. Что реализовано
- Профиль и траектория. Роль, грейд, навыки, пройденные активности, цель (своя, «следующий грейд» или смена роли), готовность в % с формулой расчёта.
- Рекомендации 1–3 шагов. Детерминированный движок: фильтры допустимости, взвешенный скоринг, метки
Strong / Good match / Exploratoryбез фиктивных вероятностей. - Объяснение по многим факторам. Грейд и цель, разрыв по навыку с цифрами, критичность навыка, ожидаемый эффект, история участия (неявки, отказы, успешные прохождения), формат, нагрузка, ближайшая сессия. На русском, казахском или английском.
- Честные «заблокированные» пробелы. Если ни одна активность каталога не может закрыть критический навык, система прямо говорит об этом, а не подсовывает случайный курс.
- Обновление прогресса. «Отметить выполненным» → навыки, готовность и рекомендации пересчитываются сразу, экран «Что изменилось» показывает разницу.
- Оценка ≠ сертификация. Формальный уровень с последней аттестации хранится отдельно; активности меняют только расчётную оценку.
- HR-панель. KPI, тепловая карта «отдел × навык», топ пробелов, участие по активностям, воронка карьерного пайплайна, люди без следующего шага, пробелы каталога, поддерживающие сигналы («что знаем / чего не знаем / как поддержать»).
- Career AI (OpenAI). Чат сотрудника и AI-инсайты для HR. Модель только объясняет данные бэкенда и не принимает решений; без ключа работает по правилам.
- Импорт данных жюри. Загрузка
employees.json/activity_history.csv(иevents.json/skills.json) в формате датасета с проверкой и предпросмотром; новые профили работают сразу, без перезапуска. - Роли и приватность. Сотрудник видит только себя; HR не видит чатов сотрудников; без рейтингов, стриков и баллов за обязательные процессы.
Результаты на датасете кейса
Сравнение с правилом «бери минимальный навык», от которого предостерегает ТЗ. Все 200 сотрудников, без ручного отбора; воспроизводится командой python scripts/evaluate.py.
| Метрика | Наивное правило | Career Quest |
|---|---|---|
| Первая рекомендация закрывает критический навык (у кого он закрываем каталогом) | 14% (14/101) | 97% (98/101) |
| Рекомендует событие, которое сотрудник пройти не может (уже пройдено, пререквизиты, не та аудитория) | 59% (118/200) | 0 |
| Итого непригодная или уже проваленная рекомендация | 67% (134/200) | — |
| Время расчёта для всех 200 сотрудников | — | ~70 мс |
Даже если наивному правилу дать те же фильтры допустимости, критический навык оно выбирает лишь в 24% случаев. Когда Career Quest ставит первым событие, которое человек раньше пропускал (35 случаев), в 34 из них это единственная активность каталога для нужного навыка: рейтинг снижен, а причина названа в объяснении.
Real AI: ответы gpt-4.1-mini через API приложения — около 4,4 с на вопрос (лимит ТЗ — 10 с).
Почему решения принимает не LLM
Это осознанный выбор для банка. Выбор шага — детерминированный код: каждое решение воспроизводимо, объяснимо цифрами и проверяется тестами. LLM не может выдумать курс или «повысить» сотрудника. AI отвечает за то, что у него получается лучше: диалог с сотрудником, объяснение «почему», симуляцию «что будет, если», инсайты для HR. Ответ модели проверяется: упоминание активности не из данных → ответ отбрасывается.
3. Как это работает
flowchart LR
A["📄 Профиль, история,<br/>события, навыки"] --> B["🎯 Цель и<br/>требования грейда"]
B --> C["📊 Пробелы:<br/>оценка + активности<br/>после аттестации"]
C --> D["🧮 Фильтры и<br/>скоринг событий"]
D --> E["✅ 1–3 шага<br/>с объяснением"]
E --> F["✔️ Выполнено"]
F -->|пересчёт| C
E -.-> G["✦ Career AI<br/>объясняет и отвечает"]
- Цель. Берётся
career_goalсотрудника; если её нет — следующий грейд в текущей роли. - Прогресс.
текущий уровень = оценка на аттестации + рост от активностей после неё;разрыв = max(требование − текущий уровень, 0). - Фильтры. Исключаются обязательные (они в отдельном блоке «Обязательно»), чужая аудитория, уже пройденные (кроме клуба EV_036), начатые, с невыполненными пререквизитами, не закрывающие разрыв, упёршиеся в
max_level, без будущей сессии. - Скоринг. Вклад в критические навыки весит больше всего; учитываются полезный прирост, соответствие цели, позитивная история, трения (неявки/срывы/отказы на тех же и похожих активностях), формат, нагрузка, разнообразие шагов.
- Результат. До 3 рекомендаций с числовыми факторами, ожидаемым эффектом и текстовым объяснением.
Пример: у сотрудника самый низкий навык — Public Speaking, но он трижды пропускал Public Speaking Club, а для Senior критичен System Design. Система рекомендует System Design и объясняет почему — правило «бери минимальный навык» здесь бы ошиблось.
4. Технологии
| Слой | Стек |
|---|---|
| Бэкенд | Python 3.11+, FastAPI, Pydantic 2, Uvicorn, httpx |
| Фронтенд | React 19, TypeScript, Vite, Tailwind CSS, React Router |
| AI | OpenAI Chat Completions API с function calling, модель по умолчанию gpt-4.1-mini (настраивается) |
| Безопасность | Токены с подписью HMAC-SHA256, разделение ролей сотрудник / HR |
| Тесты | pytest, Vitest + Testing Library, Playwright (e2e) |
| Запуск | Docker, Docker Compose, Makefile |
5. Архитектура
flowchart TB
UI["React SPA<br/>сотрудник — mobile · HR — desktop"] -->|REST + Bearer token| API["FastAPI"]
API --> P["SkillProgressService<br/>цель, уровни, готовность"]
API --> R["RecommendationEngine<br/>фильтры, скоринг, объяснения"]
API --> H["AnalyticsService + EngagementSignalService<br/>HR-аналитика и сигналы"]
API --> AI["AI-слой (ai.py)<br/>инструменты только для чтения"]
AI -->|function calling| OAI[("OpenAI API")]
AI --> P & R & H
P & R & H --> DS["DataStore<br/>импорт, выполнение, сброс"]
DS --> L["DatasetLoader<br/>схемы + кросс-проверки"]
L --> F[("dataset/*.json, *.csv")]
- Решения принимает детерминированный код, а не LLM: все расчёты воспроизводимы и покрыты тестами.
- AI-слой вызывает инструменты, привязанные к вошедшему сотруднику: прогресс, рекомендации, альтернативы, симуляция «что будет, если пройду», история. Ответ, где упомянута активность не из данных, отбрасывается; при отсутствии ключа, ошибке или превышении 8 секунд работает ответ по правилам.
- HR-AI получает только обезличенные агрегаты; ответы с числами, которых нет в данных, отклоняются.
- FastAPI отдаёт и API, и собранный фронтенд — один контейнер, один порт.
6. Установка и запуск
Вариант A — одна команда (Docker):
git clone https://github.com/BAITC-Hacks/hack-53d6003c-arqau.git
cd hack-53d6003c-arqau
docker compose up --build
Откройте http://localhost:8000 · документация API: http://localhost:8000/docs
Вариант B — локально (Python 3.11+, Node.js 22):
make install # venv + npm-зависимости
make dev # API на :8000, интерфейс на http://127.0.0.1:5173
make test # тесты бэкенда и фронтенда
Включить AI (необязательно). Без ключа всё работает, Career AI отвечает по правилам. Чтобы подключить OpenAI:
- через интерфейс: войти как HR → AI settings → вставить ключ → Save key (ключ хранится только в памяти сервера и не возвращается API);
- или через файл:
cp .env.example .envи указатьOPENAI_API_KEY=sk-...перед запуском.
7. Как проверить (сценарий для жюри)
- Сотрудник. На экране входа выберите сотрудника E0028 (Backend Engineer, Middle).
- Главная: готовность к Senior и предупреждение, что критический навык System Design не закрывается каталогом.
- События → «Почему?»: факторы рекомендации с цифрами.
- «Отметить завершённым»: окно «Что изменилось» — уровень навыка, готовность до/после, новые рекомендации.
- Career AI (вкладка AI): «Почему я ещё не готов к цели?», «Что будет, если я пройду главную рекомендацию?». Над ответом виден режим:
✦ AI · gpt-4.1-miniили «Ответ по правилам»; под ним — «Почему такой ответ?» с источниками. - HR. Выйдите и войдите как HR partner: Overview (KPI, тепловая карта), People (сигналы и «нет следующего шага»), Skills, Events, AI settings → Generate insights, строка Ask AI.
- Импорт профиля-ловушки. HR → Import data → выберите оба файла из
samples/jury_demo/→ Dry-run preview → Import. Выйдите и на экране входа найдите через поиск E9001: у него низкий Public Speaking и 3 неявки на Public Speaking Club, но первые рекомендации — по критическому System Design (EV_006, EV_007) с объяснением. - Свои профили жюри загружаются так же, в формате датасета. Для повторного прогона: перезапустите контейнер или вызовите
POST /admin/resetпод HR.
8. Данные и интеграции
- Датасет кейса (
dataset/, синтетический): 200 сотрудников, 40 событий, 60 навыков, 8 ролей × 4 грейда, 2 743 записи истории за 24 месяца. «Сегодня» — дата снимка2026-10-01. - Дополнительные данные в той же схеме: через экран Import,
POST /importили переменнуюCAREER_QUEST_EXTRA_DATA_DIR. - Внешний сервис: только OpenAI API, и только если задан ключ. Для чата сотрудника отправляются его собственные данные о навыках и рекомендациях (без имени), для HR — обезличенные агрегаты. Без ключа данные не покидают сервер.
Персональные данные и комплаенс
- В прототипе данные синтетические. Без ключа OpenAI данные не покидают сервер.
- В OpenAI для чата уходят только навыки и рекомендации самого сотрудника, без имени и ID; для HR — только обезличенные агрегаты.
- Закон РК «О персональных данных и их защите» требует хранить персональные данные в базах на территории Казахстана. Для банка: (1) работать без внешнего LLM — всё функционирует на правилах, или (2) указать
OPENAI_BASE_URLна OpenAI-совместимую модель, развёрнутую в контуре банка.
Путь к пилоту
- Подключить HR-систему и LMS банка вместо файлов (формат данных уже совпадает со схемой кейса).
- Хранилище (PostgreSQL) вместо памяти, SSO вместо демо-входа, аудит-лог.
- LLM внутри контура банка.
- Пилот на одном подразделении: метрики — доля завершённых добровольных активностей и число сотрудников без следующего шага.
9. Ограничения
- Нет QR-подтверждения участия. Выполнение отмечает сам сотрудник (API также принимает источник
hr_confirmed). - Демо-вход без пароля и SSO. Роль выбирается на экране входа.
- Состояние в памяти. Импорт и отметки о выполнении сбрасываются при перезапуске; базы данных нет.
- Нет экрана руководителя (Manager view).
- Не моделируются вместимость событий, листы ожидания и календарная запись.
- Названия навыков и событий — на английском, как в датасете; интерфейс и объяснения — на русском, казахском и английском.
- AI требует ключа OpenAI; без него — ответы по правилам из тех же данных.
10. Развёртывание и deployed-версия
Публичной ссылки нет: данные кейса не выносятся за пределы хакатона. При этом решение готово к развёртыванию на любом сервере с Docker:
- Один контейнер. Многоэтапный
Dockerfileсобирает фронтенд (Node 22) и запускает FastAPI (Python 3.12), который отдаёт и API, и интерфейс на порту 8000. Отдельный веб-сервер не нужен. - Без базы данных и внешних зависимостей. Датасет встроен в образ;
compose.yamlможет подменить его своим каталогом (монтируется только для чтения). - Конфигурация через переменные окружения (шаблон —
.env.example):
| Переменная | Назначение |
|---|---|
CAREER_QUEST_SECRET | Ключ подписи токенов; для сервера задайте длинную случайную строку, иначе токены сбрасываются при перезапуске |
OPENAI_API_KEY, OPENAI_MODEL | Включают Career AI (необязательно) |
CAREER_QUEST_DATA_DIR | Каталог базового датасета |
CAREER_QUEST_EXTRA_DATA_DIR | Каталог с дополнительными профилями, загружаемыми при старте |
docker build -t career-quest .
docker run -p 8000:8000 -e CAREER_QUEST_SECRET=<случайная-строка> -e OPENAI_API_KEY=<ключ> career-quest
- Проверка работоспособности:
GET /healthвозвращает статус и число загруженных записей. - Для продакшена потребуется: база данных вместо хранения в памяти, SSO вместо демо-входа, HTTPS и хранилище секретов (см. раздел 9).
Подробная техническая документация (эндпоинты, веса скоринга, пороги сигналов, импорт): docs/TECHNICAL.md
Авторы коммитов
История коммитов
- 2026-09-23 17:55Merge pull request #13 from BAITC-Hacks/docs/readme-evidencemedgeland
- 2026-09-23 17:54docs: measured results vs lowest-skill baseline, AI rationale, compliance, pilot pathMargarita Serebrennikova
- 2026-09-23 17:53docs: add deployability section to READMEMargarita Serebrennikova
- 2026-09-23 17:49docs: add deployability section to READMEMargarita Serebrennikova
- 2026-09-23 17:45merge: reconcile remote branchMargarita Serebrennikova
- 2026-09-23 17:45Merge pull request #12 from BAITC-Hacks/docs/readme-rumedgeland
- 2026-09-23 17:44docs: precise wording for the sample profileMargarita Serebrennikova
- 2026-09-23 17:44docs: concise Russian README for the jury; move technical docsMargarita Serebrennikova
Все коммиты (37)
- 2026-09-23 17:41merge: sync latest mainMargarita Serebrennikova
- 2026-09-23 17:39Merge main into fix/step-9-login-navigationMargarita Serebrennikova
- 2026-09-23 17:37Merge pull request #10 from BAITC-Hacks/fix/ai-levels-and-hr-latencymedgeland
- 2026-09-23 17:35fix: polish localization and interactive HR viewsMargarita Serebrennikova
- 2026-09-23 17:34fix: AI quotes current skill level; HR insights fit the deadlineMargarita Serebrennikova
- 2026-09-23 17:30Merge pull request #9 from BAITC-Hacks/feat/step-7-aimedgeland
- 2026-09-23 17:30fix: navigate after demo loginMargarita Serebrennikova
- 2026-09-23 17:26feat: grounded Career AI and HR insights with offline fallbackMargarita Serebrennikova
- 2026-09-23 17:05fix: navigate after demo loginMargarita Serebrennikova
- 2026-09-23 16:58Merge pull request #8 from BAITC-Hacks/feat/step-8-reproducible-demomedgeland
- 2026-09-23 16:54docs: one-command startup and complete READMEMargarita Serebrennikova
- 2026-09-23 16:45Merge pull request #7 from BAITC-Hacks/feat/step-5-frontendmedgeland
- 2026-09-23 16:41feat: employee and HR web appMargarita Serebrennikova
- 2026-09-23 16:12Merge pull request #6 from BAITC-Hacks/feat/step-4-hr-analyticsmedgeland
- 2026-09-23 16:10feat: HR analytics, support signals and opportunity gapsMargarita Serebrennikova
- 2026-09-23 15:58Merge pull request #5 from BAITC-Hacks/feat/step-3-permissionsmedgeland
- 2026-09-23 15:57feat: employee and HR permissionsMargarita Serebrennikova
- 2026-09-23 15:48Merge pull request #4 from BAITC-Hacks/feat/step-2-runtime-statemedgeland
- 2026-09-23 15:47feat: jury data import and activity completion with live recalculationMargarita Serebrennikova
- 2026-09-23 15:28Merge pull request #3 from BAITC-Hacks/fix/step-1-engine-hardeningmedgeland
- 2026-09-23 15:26fix: same-event friction, blocked critical gaps, clean explanationsMargarita Serebrennikova
- 2026-09-23 14:55feat: implement explainable recommendation engineMargarita Serebrennikova
- 2026-09-23 14:37Merge pull request #2 from BAITC-Hacks/fix/test-data-dir-and-loader-warningsmedgeland
- 2026-09-23 14:36fix: make tests resolve dataset dir and soften convention checksMargarita Serebrennikova
- 2026-09-23 14:32test: cover dataset and career progressmedgeland
- 2026-09-23 14:31feat: add Career Quest backend servicesmedgeland
- 2026-09-23 14:23Merge pull request #1 from BAITC-Hacks/feature/career-quest-mvpmedgeland
- 2026-09-23 14:23feat: initialize Career Quest backend and progress domainmedgeland
- 2026-09-23 13:58Add files via uploadmedgeland
Структура репозитория (76 файлов)
.dockerignore .env.example .gitignore Dockerfile Makefile README.md backend/app/__init__.py backend/app/ai.py backend/app/analytics.py backend/app/auth.py backend/app/career_progress.py backend/app/data_loader.py backend/app/data_store.py backend/app/main.py backend/app/models.py backend/app/recommendations.py backend/tests/test_ai.py backend/tests/test_analytics.py backend/tests/test_auth.py backend/tests/test_health.py backend/tests/test_loader.py backend/tests/test_progress.py backend/tests/test_recommendations.py backend/tests/test_runtime.py compose.yaml dataset/README.kz.md dataset/README.md dataset/README.ru.md dataset/activity_history.csv dataset/employees.json dataset/events.json dataset/skills.json docs/CAREER_QUEST_CODEX_TASK_v2.md docs/TECHNICAL.md docs/design/SCREENS.md docs/design/reference/M-AI.dc.html docs/design/reference/M-Events.dc.html docs/design/reference/M-Growth-Updated.dc.html docs/design/reference/M-Growth.dc.html docs/design/reference/M-Home.dc.html docs/design/reference/M-Path.dc.html docs/design/reference/M-QR.dc.html docs/design/reference/M-Verified.dc.html docs/design/reference/W-HR-Events.dc.html docs/design/reference/W-HR-Import.dc.html docs/design/reference/W-HR-Overview.dc.html docs/design/reference/W-HR-People.dc.html docs/design/reference/W-HR-Skills.dc.html docs/design/tokens.json frontend/e2e/employee-flow.spec.ts frontend/index.html frontend/package-lock.json frontend/package.json frontend/playwright.config.ts frontend/postcss.config.js frontend/src/App.tsx frontend/src/ai.tsx frontend/src/api.ts frontend/src/components.tsx frontend/src/i18n.ts frontend/src/main.tsx frontend/src/styles.css frontend/src/test/components.test.tsx frontend/src/test/setup.ts frontend/src/vite-env.d.ts frontend/tailwind.config.js frontend/tsconfig.app.json frontend/tsconfig.json frontend/tsconfig.node.json frontend/vite.config.ts frontend/vitest.config.ts pyproject.toml samples/jury_demo/README.md samples/jury_demo/activity_history.csv samples/jury_demo/employees.json scripts/evaluate.py
Ветки (14)
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.