Career Quest
Веб-приложение Career Quest для Halyk Bank.
О проекте
Команда: Qarakus
Кейс HackAlem.ai: Менеджмент — Halyk Bank · кейс 1
Стадия: Доведённый продукт
Задача кейса: «Career Quest»: AI-навигатор, связывающий навыки сотрудника с шагами развития
Суть
Веб-приложение Career Quest для Halyk Bank. Сотруднику предлагается до трёх добровольных шагов развития к целевому грейду с прогнозом прироста навыков, HR получает сводку дефицитов компетенций. ИИ объясняет выбор через function calling.
Как устроено
store.py берёт последнюю оценку сотрудника и применяет завершения после last_review_date. engine.py считает gap = required − current и score = gap × 2 для критичных навыков (иначе × 1). Из каталога событий исключаются неподходящие по роли, грейду и предпосылкам, а также уже завершённые активности; из оставшихся выбирается до трёх шагов с прогнозом gain/max_level. По кнопке gpt-4o-mini через function calling вызывает get_skill_history и get_alternative_events и пишет объяснение. Код отклоняет текст, если инструменты не были вызваны. Без API-ключа используется шаблонное объяснение. HR загружает JSON/CSV и видит пробелы в программах развития.
Ключевые решения
- weighted skill-gap scoring
- function calling
- enforced tool use
- deterministic progress forecast
- CSRF auth
- i18n RU/KK/EN
Метрики
200 сотрудников → 439 рекомендованных шагов; прогноз совпал с результатом у 179 из 179 сотрудников; 42 автотеста passed
Особенности
Модель только объясняет выбор, а код принудительно проверяет вызов инструмента истории по каждому навыку. Профиль DEMO_TRAP показывает, чем подход отличается от правила «курс по самому слабому навыку». Прогноз 88%→94% проверяется фактическим выполнением шага. Для профилей без данных честно выводится «недостаточно данных».
Стек
Python · Docker Compose · Tailwind CSS · pytest · ruff · GitHub Actions · OpenAI API
Модели
gpt-4o-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-226429c9-qarakus.
README
README.mdCareer Quest — понятный следующий шаг в карьере
Не ещё один каталог курсов: сотрудник видит, почему нужен именно этот шаг и что изменится после него.
HackAlem AI · Halyk Bank · кейс 1. Веб-приложение связывает навыки и историю участия с требованиями целевого грейда, предлагает до трёх добровольных активностей и пересчитывает прогресс после выполнения. HR видит дефициты компетенций и пробелы в доступных программах развития.
Работает без API-ключа. С ключом появляется ИИ-объяснение с реальными вызовами инструментов; решение и числовой прогноз остаются проверяемыми.
Запуск · Пример решения · Проверка · Критерии ТЗ · AI и архитектура · Ограничения
| Проверено на данных репозитория | Результат |
|---|---|
| 200 сотрудников, 40 событий, 60 навыков | 439 рекомендованных шагов; все доступны и дают прирост нужного навыка |
| Выполнение первого шага у каждого из 179 сотрудников с рекомендациями | 179 из 179 прогнозов совпали с результатом; навыки не уменьшились |
| Автотесты в Docker без сети и API-ключа | 42 passed |
| Проверка интерфейса | RU / KK / EN, ширина 390 px, вход сотрудника и HR |
Это проверки корректности на синтетических данных, не доказательство роста вовлечённости. Машиночитаемый результат генерируется открытым скриптом, а не прописан в движке. 21 профиль без рекомендаций не считается автоматически успешным: HR отдельно показывает отсутствие подходящего шага и неизвестные требования.
Запуск за одну команду
Из корня клонированного репозитория, при установленном Docker с Compose:
docker compose up --build
Открыть http://localhost:8000. Для первой сборки нужен интернет, после сборки основной сценарий не требует внешних сервисов. Python, Node.js и ключи на машине проверяющего не нужны; CSS и синтетический датасет находятся в репозитории.
| Роль | Логин | Пароль | Доступ |
|---|---|---|---|
| Сотрудник | E0028 | employee-demo | Только свой профиль и действия |
| HR / проверка решения | hr | hr-demo | Все профили, HR-сводка, загрузка JSON/CSV |
Это публичные учебные учётные записи, не защита реальных данных. Проверка состояния: http://localhost:8000/health. Развёрнутого публичного сервиса нет; воспроизводимый артефакт — этот репозиторий.
Почему не просто курс по самому слабому навыку
Один проверяемый пример вместо обещания «персонализации».
Дополнительный профиль DEMO_TRAP: Backend Engineer, Middle → Senior.
| Фактор | Public Speaking | System Design |
|---|---|---|
| Уровень → требование Senior | 0 → 2 | 3 → 4 |
| Критичность для перехода | Нет | Да |
| История по навыку в этом примере | Три отказа/пропуска | Нет записей |
| Правило «самый низкий уровень» | Выбрало бы этот навык | Пропустило бы |
| Career Quest | Не первый приоритет | Первый шаг — EV_006 |
Разрывы имеют одинаковый взвешенный балл: 2 × 1 = 1 × 2.
При равенстве приоритет получает критичный навык. История затем влияет на выбор
конкретной активности и явно присутствует в объяснении — не выдаём её за
скрытый множитель ранжирования навыков.
До выполнения: 88% готовности. Прогноз первого шага: System Design 3 → 4, готовность 88% → 94%. После отметки выполнения получаются именно эти значения. Готовность — доля выполненных требований, а не вероятность повышения.
Посмотреть реальную карточку с факторами и прогнозом

Проверить самостоятельно за 3 минуты
- Войти как HR и на
/hrзагрузить одновременно employees.json и activity_history.csv. - Открыть http://localhost:8000/employee/DEMO_TRAP — проверить первый шаг, факторы, описание, сессию и прогноз 88% → 94%.
- Отметить первый шаг выполненным — увидеть фактическое изменение навыка и готовности.
- Открыть
/employee/DEMO_HISTORY: завершение после последней оценки уже учтено, готовность 100%, лишних рекомендаций нет. - Открыть
/employee/DEMO_UNKNOWN: «недостаточно данных», а не ложные 100%; профиль выделен на HR-панели.
Это наши демонстрационные профили, не неизвестные заранее профили жюри.
Новые профили проходят тот же код: ветвлений по DEMO_* в приложении нет.
Подробности сценария · Проверка через JSON API
Воспроизвести результат
Команды выполняются из корня репозитория после сборки образа. Они создают отдельное хранилище в процессе и не меняют данные работающего демо.
Все тесты, без ключа:
docker compose run --rm --no-deps -e OPENAI_API_KEY= \
-v "$PWD:/submission:ro" -w /submission/backend \
career-quest pytest tests -q -p no:cacheprovider
Проверки всех 200 профилей и JSON-отчёт, без сторонних Python-пакетов:
python3 scripts/evaluate.py
Если Python не установлен:
docker compose run --rm --no-deps -e OPENAI_API_KEY= \
-v "$PWD:/submission:ro" career-quest python /submission/scripts/evaluate.py
Скрипт возвращает код 0 только при успешных проверках, иначе 1.
JSON содержит результаты проверок, ожидаемый/фактический прогресс и SHA-256
входных файлов. Сохранённый отчёт можно сравнить с новым запуском.
Это дополняет, а не заменяет HTTP-тесты авторизации, импорта и обработки ошибок.
Соответствие критериям
Баллы ниже — веса из ТЗ, не самостоятельно выставленная оценка.
| Критерий | Вес | Что проверять в репозитории |
|---|---|---|
| Соответствие задаче и работоспособность | 25 | Сквозной тест: импорт → рекомендация → выполнение → HR; профиль сотрудника |
| Техническая реализация | 25 | Движок, AI tools и дедлайн, права и CSRF, тесты AI |
| README и воспроизводимость | 25 | Один Docker-запуск, учебные учётные записи, фикстуры, JSON-отчёт, API-инструкция |
| Ценность и применимость | 15 | Видимый результат шага до выполнения, добровольность, HR-срез; план проверки эффекта ниже |
| Потенциал и оригинальность | 10 | Проверяемый прогноз + история после оценки + ИИ с инструментами и независимым от модели расчётом; развитие без смены схемы навыков |
Подробная матрица обязательных требований и границы проверки · Контрольный разбор: возможные причины снижения оценки
Как работает AI
Используется гибридный подход, а не рекомендация по одному полю и не непроверяемое решение языковой модели:
store.pyзагружает последнюю оценку и применяет завершения послеlast_review_dateпо порядку дат. Повторный импорт не начисляет прирост дважды.engine.pyопределяет цель:career_goalили следующий грейд; считаетgap = required − current,score = gap × (2, если критичен, иначе 1). При равенстве баллов идут критичность, затем стабильный ID.- Из каталога исключаются обязательные, неподходящие по роли/грейду/предпосылкам, уже завершённые неповторяемые и не дающие прироста активности. Среди кандидатов предпочитаются ранее не отклонённые, затем больший реальный прирост.
- До трёх выбранных шагов получают факторы и прогноз по тем же правилам
gain / max_level, что используются при фактическом выполнении. - По кнопке модель через function calling запрашивает
get_skill_historyи при необходимостиget_alternative_events, после чего формулирует объяснение. Интерфейс показывает реально вызванные инструменты.
Граница ответственности модели: объяснить, а не менять рейтинг, навыки или историю. Вызов истории обязателен для каждого навыка шага; без него AI-текст не принимается. При отказах/пропусках обязателен и вызов альтернатив — это контролирует код, а не только инструкция модели. Если по навыку нет истории, используется базовый текст без API-вызова: модель не должна выводить отсутствие опыта из отсутствия записей. Это проверяет использование инструментов, не гарантирует истинность каждой фразы: числовые факторы остаются видимыми отдельно.
Реальный пример: E0005, System Design 2 → требуется 4, одно завершение и один пропуск. Модель проверила историю и альтернативы, затем объяснила выбор и назвала онлайн-альтернативу. Скриншоты и инструкция · Ответы приложения в JSON.

Сетевой цикл имеет общий дедлайн 8 секунд, без повторов SDK; при ошибке остаётся шаблонное объяснение. Страница вообще не ждёт API. Успешные ответы кэшируются на 5 минут по фактам и языку; лимит — 12 новых запросов в минуту, 4 одновременно на процесс.
Для реального AI скопировать .env.example в .env, указать OPENAI_API_KEY
и выполнить docker compose up -d --force-recreate.
Модель по умолчанию — gpt-4o-mini; переменная OPENAI_MODEL позволяет заменить её.
Не публикуйте ключ. Имя сотрудника модели не передаётся; факты о навыках и участии
передаются провайдеру при запросе объяснения.
Без ключа: рекомендации, три фактора, прогноз, выполнение, HR и импорт работают;
генеративное объяснение заменяется локальным шаблоном. Это не имитация ответа модели:
в API явно различаются source: template и source: llm-agentic.
Ценность и следующий этап
| Проблема | Механизм в прототипе | Как проверить пользу на пилоте |
|---|---|---|
| «Не понимаю, зачем мне курс» | Связь с целевым грейдом и прогноз изменения навыка | Доля добровольно начатых и завершённых рекомендаций |
| Повторные приглашения на нежелательные активности | История отказов при выборе события, видимое объяснение | Повторные пропуски относительно текущей рассылки |
| HR не видит пробелы в программе развития | Разрывы навыков и сотрудники без доступного шага | Доля сотрудников с разрывами, для которых есть подходящая активность |
Эффект на реальных сотрудниках не измерен. Для пилота: сравнить текущую рассылку и рекомендации на сопоставимых группах, учитывать исходные грейды/разрывы, измерять добровольное участие и закрытие критичных требований; не превращать эти метрики в публичный рейтинг сотрудников.
Отличие прототипа — не заявление о новой категории HR-продуктов, а связка «объяснимый выбор → проверяемый прогноз → подтверждённое изменение». Следующие этапы: постоянная БД и корпоративный вход; обратная связь «подходит / не подходит»; интеграция с LMS и календарём для подтверждения участия. Это план, не готовые функции. Ядро использует справочники роли/грейда/навыков; расширение на другую организацию потребует её матрицы компетенций и проверки правил доступности.
Архитектура и данные
Python 3.13 · FastAPI · Jinja2 · локальный Tailwind CSS · OpenAI SDK · pytest. Серверный HTML не требует сборки фронтенда при запуске.
| Компонент | Ответственность |
|---|---|
| store.py | Данные, история, применение прироста и атомарный импорт |
| engine.py | Ранжирование, доступность, прогноз и HR-агрегаты |
| explain.py | Локальные объяснения и асинхронный AI-цикл |
| auth.py / main.py | Сессии, права, CSRF, HTML/JSON API |
| templates / static | Интерфейс RU/KK/EN, мобильная версия, запрос AI по кнопке |
| tests | Регрессии, маршруты, права, импорт, таймауты и сценарии |
| seed | Синтетический стартовый датасет и его правила |
Дата сценария — 2026-10-01, из датасета, не из часов компьютера.
Импорт поддерживает JSON-профили и CSV-историю, UTF-8 с BOM, до 5 МБ на файл.
Если last_review_date не задана, уровни считаются текущими: исторические завершения
не начисляются повторно. Неизвестная роль/цель даёт неопределённую готовность,
а не ложные 100%. Lead без явной цели сравнивается с требованиями текущего грейда.
Границы прототипа
- Данные в памяти одного процесса. Перезапуск сбрасывает импорт и отметки выполнения.
- Демодоступ публичен. Есть серверные проверки ролей/владельца и CSRF, но нет SSO,
MFA, аудита и защиты уровня production. Для пилота отключить
DEMO_MODE, настроить учётные данные,SESSION_SECRETи HTTPS. Параметры. - AI-текст может ошибаться. Тесты не являются оценкой лингвистического качества; вычисленные факторы служат отдельным источником проверки.
- Готовность — не аттестация. Выполнение в демо подтверждается самим пользователем, а рост навыка следует условному правилу датасета, не результату экзамена.
- Сигнал вовлечённости — эвристика, а не обученная модель вероятности увольнения.
- Награды, внутренняя валюта и геймификация не реализованы: по ТЗ они опциональны. Обязательные активности не входят в добровольный рекомендательный контур.
- Локальные замеры скорости не доказывают SLA под нагрузкой; промышленный масштаб не проверен.
Интерфейс и дополнительные материалы
| Сотрудник | HR |
|---|---|
![]() | ![]() |
Казахский интерфейс · Английский интерфейс · Экран входа · Сценарий проверки · API · Сверка с ТЗ
Разработка без Docker: cd backend, создать окружение Python 3.13, установить
pip install -r requirements.txt, запустить uvicorn app.main:app --reload.
Локальные проверки: pytest tests -q, ruff check app tests (Ruff установить отдельно).
Пересборка CSS нужна только при изменении классов:
cd backend && npx --yes --package [email protected] tailwindcss --input styles/tailwind.css --output app/static/tailwind.css --content './app/templates/*.html' --minify.
Авторы коммитов
История коммитов
- 2026-09-23 17:36проверил ИИ-объяснения и добавил реальные примерыAbylay Muratov
- 2026-09-23 17:23подготовил питч репозитория и проверяемый отчётAbylay Muratov
- 2026-09-23 17:16проверил сценарии жюри и обновил демоAbylay Muratov
- 2026-09-23 17:09исправил расчёт навыков и добавил роли и ИИ-объясненияAbylay Muratov
- 2026-09-23 16:21улучшил карточки рекомендованных шаговAbylay Muratov
- 2026-09-23 16:09обновил интерфейс сотрудника и HR-панелиAbylay Muratov
- 2026-09-23 15:49исправил загрузку профилей и проверку активностейAbylay Muratov
- 2026-09-23 15:25фикс скрытой 100 готовности, честные факторыAbylay Muratov
Все коммиты (19)
- 2026-09-23 15:10убрал ci-бейджAbylay Muratov
- 2026-09-23 15:05ci workflowAbylay Muratov
- 2026-09-23 15:03диаграмма, риск вовлечённости, toc, ruffAbylay Muratov
- 2026-09-23 14:43favicon healthcheckAbylay Muratov
- 2026-09-23 14:32фикс регресса навыка, бюджет времени, ТЗ до буквыAbylay Muratov
- 2026-09-23 14:16локализация и скриншотыAbylay Muratov
- 2026-09-23 13:59полировка uiAbylay Muratov
- 2026-09-23 13:57agentic объяснениеAbylay Muratov
- 2026-09-23 13:55обработка ошибокAbylay Muratov
- 2026-09-23 13:51тесты и приватностьAbylay Muratov
- 2026-09-23 13:43первая версияAbylay Muratov
Структура репозитория (61 файлов)
.env.example .github/workflows/ci.yml .gitignore AGENTS.md README.md backend/.dockerignore backend/Dockerfile backend/app/__init__.py backend/app/auth.py backend/app/data/seed/README.kz.md backend/app/data/seed/README.md backend/app/data/seed/README.ru.md backend/app/data/seed/activity_history.csv backend/app/data/seed/employees.json backend/app/data/seed/events.json backend/app/data/seed/skills.json backend/app/engine.py backend/app/explain.py backend/app/i18n.py backend/app/main.py backend/app/static/app.js backend/app/static/tailwind.css backend/app/store.py backend/app/templates/base.html backend/app/templates/employee.html backend/app/templates/error.html backend/app/templates/hr.html backend/app/templates/index.html backend/requirements.txt backend/ruff.toml backend/styles/tailwind.css backend/tests/__init__.py backend/tests/conftest.py backend/tests/helpers.py backend/tests/test_auth.py backend/tests/test_demo.py backend/tests/test_engine.py backend/tests/test_explain.py backend/tests/test_history.py backend/tests/test_routes.py backend/tests/test_upload.py docker-compose.yml docs/AI_EXAMPLES.md docs/API.md docs/AUDIT.md docs/DEMO.md docs/REVIEW.md docs/ai-examples.json docs/architecture.svg docs/demo/activity_history.csv docs/demo/employees.json docs/evaluation.json docs/screenshots/ai-alternatives-ru.png docs/screenshots/ai-critical-ru.png docs/screenshots/demo-ai-ru.png docs/screenshots/employee-en.png docs/screenshots/employee-kk.png docs/screenshots/employee-ru.png docs/screenshots/hr-ru.png docs/screenshots/index-ru.png scripts/evaluate.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.

