AAYMA
RU
Войти

Аким на 5 часов

Полноценный продукт-симулятор Астаны: карта районов, 14 инициатив, 5 решений, Score и AI-разбор.

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

О проекте

Команда: Djem
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Доведённый продукт

Задача кейса: «Аким на 5 часов»: городской симулятор, распределяющий бюджет по 5 направлениям и 5 районам

Суть

Полноценный продукт-симулятор Астаны: карта районов, 14 инициатив, 5 решений, Score и AI-разбор. Есть миссии, городские события (паводок, смог, снегопад), личный кабинет, библиотека сценариев, HTML-презентация и админ-агент для редактирования данных.

Как устроено

Python считает Score = 0.7·взвешенный средний + 0.3·слабейший район − число показателей ниже 40 с лагом (8−lag)/8 и синергиями. Лучший план ищется полным перебором (694 395 допустимых сценариев); для каждой меры сравнивается план с ней и без неё. AI на gpt-4.1-mini через OpenAI Responses API с вызовами Python-инструментов объясняет результат, а админ-агент меняет данные через проверяемые функции с версионированием и аудитом. Данные в SQLite, аккаунты с PBKDF2.

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

  • exhaustive search
  • leave-one-out attribution
  • OpenAI Responses API tool calling
  • dataset versioning
  • PBKDF2 auth

Метрики

Исходный Score 52.55768; лучший по полному перебору 57.236735 (694 395 сценариев, стоимость 9.8 млрд ₸)

Особенности

Кроме симулятора есть AI-агент администратора с версиями датасета и журналом действий: у агента нет доступа к SQL и .env. Городские события резервируют часть бюджета. Интерфейс показывает, доказан ли оптимум полным перебором или поиск ограничен по времени.

Стек

Python · FastAPI · SQLite · JavaScript · GeoJSON · Docker · Nginx · NVIDIA Brev

Модели

GPT-4.1-mini


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

README

README.md

Аким на 5 часов

Открыть сайт — akim-o237lkzkv.gobrev.dev

«Аким на 5 часов» — AI-симулятор управления Астаной. Распределяйте бюджет в тенге, принимайте 5 решений и сравнивайте сценарии. Карта, прогнозы и Score показывают эффект, а AI объясняет риски и предлагает улучшения. Результаты сохраняются в кабинете.

Проект создан для хакатона на Python / FastAPI + SQLite. Стартовый бюджет — 10 млрд ₸, одна единица кейса — 100 млн ₸. Датасет, цены и эффекты инициатив синтетические. Числа рассчитывает Python по правилам модели; AI объясняет результат и предлагает улучшения.

Что умеет продукт

  • Гостевая главная: карта, показатели районов, бюджет и каталог доступны для просмотра без входа. Данные обновляются из БД каждые 30 секунд, пока вкладка открыта.
  • Пять направлений: транспорт, озеленение и экология, социальная инфраструктура, безопасность, городские сервисы. В каталоге 14 инициатив с ценами в тенге, эффектами, задержками и выбором района.
  • Пять решений: сервер проверяет бюджет, повторы и несовместимые меры; допускается не более двух инициатив одного направления.
  • Карта и прогноз: контуры районов Астаны, сравнение факта и прогноза по районам и направлениям, подробные показатели.
  • Объяснение результата: цепочка «инициатива → показатели → район → изменение Score», сильные стороны, риски и компромиссы.
  • Три миссии: повышение качества жизни, баланс районов и подготовка к паводку. Итоговая сводка показывает достижение цели, расходы по направлениям, остаток бюджета и ключевой эффект.
  • Лучший сценарий + AI: поиск допустимого сочетания мер и автоматический подробный разбор. Интерфейс указывает, доказан ли оптимум полным перебором или поиск ограничен временем.
  • Улучшение плана: сравнение одиночных замен с численным приростом Score и применением подходящего варианта.
  • Городские события: снегопад, паводок и смог меняют условия и резервируют часть бюджета. Прежний план сохраняется при неудачной загрузке новых условий.
  • Личный кабинет: аккаунты, автосохранение рабочего плана, библиотека сценариев, AI-разборов, рекомендаций и результатов поиска.
  • Презентация: пять HTML-слайдов с бюджетом, инициативами, прогнозом и рисками; просмотр на сайте, скачивание и печать в PDF.
  • Администрирование: редактор данных, AI-агент с инструментами изменения, версии датасета, восстановление версий и журнал действий.

Как попробовать

  1. Откройте сайт и изучите исходные показатели.
  2. Войдите в аккаунт сотрудника и на главной выберите миссию или «Найти лучший сценарий».
  3. Соберите пять допустимых решений и нажмите «Завершить и рассчитать».
  4. Посмотрите сводку, диаграмму расходов и подробный разбор; раскройте детали, чтобы изучить цепочки влияния.
  5. Сохраните сценарий или создайте презентацию. Готовые материалы доступны в «Мои результаты» на главной.

Демонстрационный сотрудник: user / 12345678. На новой установке этот аккаунт автоматически не создаётся: сотрудников добавляет администратор.

Аккаунты и сохранение

РольВозможности
ГостьПросмотр главной, карты, показателей и каталога
СотрудникСобственные планы, сценарии, результаты инструментов, AI-разбор и презентации
АдминистраторУправление пользователями, общими данными, настройками и агентом; доступ ко всем сценариям для сравнения

При первом запуске создаётся admin; начальный пароль задаётся INITIAL_ADMIN_PASSWORD в .env, по умолчанию — admin. Изменение переменной не сбрасывает пароль уже существующего аккаунта. Пароль меняется в «Главная → Настройки аккаунта», сотрудники создаются в «Данные и агент → Аккаунты сотрудников». Для публичной установки задайте собственный пароль администратора.

План, событие, версия данных, выбранные районы, миссия, итоговая сводка, фильтры, поля форм и полученный AI-разбор сохраняются в персональном workspace. Автосохранение отправляется через 400 мс после изменения; локальная копия помогает при перезагрузке страницы. Конфликт двух вкладок не перезаписывает более свежую серверную версию.

Библиотека «Мои результаты» показывает черновик, сценарии, результаты поиска, AI-разборы, рекомендации и презентации. Открытие карточки не заменяет рабочий план: для этого есть отдельная кнопка. Результаты хранятся с владельцем и снимком прогноза; повторное получение одинакового результата обновляет карточку без дубликатов. Старые презентации, которые ранее только скачивались и не сохранялись на сервере, нужно создать заново.

SQLite хранит хеши паролей PBKDF2-SHA256 с индивидуальной солью. Сессии действуют 7 дней через HttpOnly cookie; в БД сохраняется хеш токена. Выход и смена пароля отзывают сессии. Пароли и API-ключи не записываются в рабочий черновик. Миграции при запуске сохраняют существующие аккаунты и сценарии.

Численная модель

В исходном датасете 5 районов, 5 направлений и 10 показателей на район. На карте дополнительно показан Сарайшык; его показатели пока не предоставлены. Границы взяты из опубликованного слоя геосервиса Астаны, локальная копия — от 23.09.2026. Контуры, легенда и переход к району работают с локальным GeoJSON; подложка OpenStreetMap требует интернета.

Горизонт расчёта — 8 кварталов. Эффект меры умножается на (8 - lag_quarters) / 8, учитываются синергии, показатели ограничиваются диапазоном 0–100. Веса находятся в seed/dataset.json.

Score = 0.7 × средний Score районов, взвешенный по населению
      + 0.3 × Score слабейшего района
      − количество показателей ниже 40

Правила используемого датасета: ровно 5 различных мер, не больше 2 в направлении. Выбор идёт из пяти направлений, без требования ровно одной меры каждого вида. M1/M3 конфликтуют глобально; M4/M7 и M5/M13 — в одном районе.

Для исходной версии без городского события:

ПоказательЗначение
Исходный Score52,55768
Лучший Score полного перебора57,236735
Допустимых сценариев проверено694 395
Стоимость лучшего плана9,8 млрд ₸
ПланM2 — весь город; M3, M8, M9 — Нура; M14 — весь город

Поддержка слабейшего района и устранение критических показателей дают основной прирост. Эти значения относятся к исходному учебному набору; после изменения данных или события результат будет другим. Для честного сравнения команды используют одинаковую версию данных и одинаковое событие.

В блоке «Почему изменился Score» для каждой меры сравнивается полный план с планом без неё в тех же условиях. Показаны задержка, синергии, переход через порог 40 и компоненты Score. Такие эффекты отдельных мер нельзя складывать. Изменение относительно исходного факта и эффект решений относительно сценария с тем же событием показаны отдельно. Например, цель миссии с паводком проверяется относительно паводка без решений.

Это учебная модель для сравнения сценариев, а не статистически подтверждённый прогноз реального города или обоснование реальных расходов.

AI и API

Для внешнего AI заполните OPENAI_API_KEY в серверном .env и перезапустите приложение. OPENAI_MODEL задаёт модель разбора, OPENAI_AGENT_MODEL — модель агента; в текущих настройках по умолчанию обе — gpt-4.1-mini. Без ключа численный расчёт, карта и интерфейс работают, а недоступность AI обозначается явно.

После поиска плана AI получает рассчитанные данные и объясняет причины выбора мер, положительные и отрицательные последствия, риски, нерешённые проблемы, этапы внедрения и возможные улучшения. Готовый ответ сохраняется и после перезагрузки не запрашивается заново. Интеграция использует OpenAI Responses API и вызовы инструментов Python.

AI-редактор доступен администратору. Он может менять показатели, цены, эффекты, бюджет, совместимость мер, сценарии и тексты сайта через проверяемые функции. Правки создают версии и записи аудита; старые сценарии остаются связаны со своими исходными данными. Агенту не предоставляются произвольный SQL, команды сервера или чтение .env.

Документация API доступна по /docs, схема — /openapi.json. Браузер использует сессию вошедшего пользователя и его роль. Для внешних интеграций поддерживается Authorization: Bearer <ADMIN_API_TOKEN или AGENT_API_TOKEN>; оба служебных токена дают административные права на рабочие данные. Обзор и численный прогноз открыты, поиск оптимума, внешний AI, личные результаты и изменения требуют авторизации.

Инструменты внешнего агента: GET /api/agent/tools, POST /api/agent/execute. Встроенный чат: POST /api/agent/chat.

Локальный запуск

Нужен Python 3.11+. Выполните команды из каталога проекта.

Linux / macOS:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
python init_env.py
# Настройте .env: ключ AI при необходимости и INITIAL_ADMIN_PASSWORD.
python run.py

Windows PowerShell (активация окружения не требуется):

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe init_env.py
# Настройте .env: ключ AI при необходимости и INITIAL_ADMIN_PASSWORD.
.\.venv\Scripts\python.exe run.py

При стандартных настройках локальный адрес — http://127.0.0.1:8000. База создаётся в data/akim.sqlite3. init_env.py создаёт .env из шаблона с независимыми служебными токенами и не перезаписывает существующий файл. Настройте ключ AI и начальный пароль администратора до первого запуска.

Сервер NVIDIA Brev

Публичный сайт проекта: https://akim-o237lkzkv.gobrev.dev/.

Jupyter использует 8888, сайт — 8080. При прямом запуске через Brev Python слушает 8080; в варианте с Nginx/Docker внешний порт остаётся 8080, а Python слушает 8000 за прокси. В .env укажите домен сайта:

ALLOWED_HOSTS=localhost,127.0.0.1,testserver,akim-o237lkzkv.gobrev.dev

Полная установка: DEPLOY_BREV.md. Обновление и откат: docs/UPDATE_GUIDE.md. Для установленного проекта с прямым запуском:

.venv/bin/python backup_db.py
# Обновите исходники из GitHub или архива, сохранив .env и data/.
bash deploy/restart_brev.sh
curl -fsS http://127.0.0.1:8080/health

Скрипт перезапуска относится к прямому запуску на 8080. Для Docker обновление выполняется через docker compose up -d --build. Не удаляйте Docker-том с БД при обновлении. Push в GitHub сам по себе не обновляет работающий сайт.

Проверки

Из каталога проекта, в активированном Python-окружении:

python -m pip install -r requirements-dev.txt
python -m pytest -q

Проверки интерфейсной логики требуют Node.js 22+; для работы самого сайта Node.js не нужен:

node --check static/app.js
node tests/test_missions.mjs
node tests/test_api_response.mjs

Последняя локальная проверка: 20 тестов Python пройдены, проверки JavaScript пройдены. В браузере проверены миссии, выбор мер и районов, сводка, перезагрузка, сохранённая презентация, восстановление после ошибок и ширина 390 px. Интеграция OpenAI ранее проверена с локальным ключом; её доступность на другом сервере проверяется отдельно. Поправка проверки порта в restart_brev.sh проверена синтаксически; Linux-перезапуск после неё требует проверки на сервере.

Проверка установленного сайта:

python verify_install.py --url http://127.0.0.1:8080

Добавьте --live-ai для одного реального платного AI-разбора с серверным ключом. Проверьте публичную ссылку в приватном окне перед демонстрацией.

Структура и документация

ПутьНазначение
app/main.pyFastAPI, маршруты и проверка прав
app/model.py, app/optimizer.py, app/events.pyРасчёт, поиск сценариев и городские события
app/db.py, app/accounts.py, app/library.pySQLite, аккаунты, личное состояние и результаты
app/agent.py, app/presentation.pyAI-инструменты и презентации
static/Интерфейс, карта, миссии, диаграммы и итоговая сводка
seed/Синтетические исходные данные
deploy/, compose.yamlNginx, Docker и перезапуск на Brev
backup_db.pyСогласованная резервная копия SQLite
tests/Проверки API, модели и интерфейсной логики

.env, реальные API-ключи, рабочие базы, логи и резервные копии не включаются в исходники и переносимые архивы.

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

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

beka68 15ArturEnixx 5

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

  • 2026-09-23 17:57Delete outputs directorybeka68
  • 2026-09-23 17:56Update backup_db.pyArturEnixx
  • 2026-09-23 17:54Add files via uploadArturEnixx
  • 2026-09-23 17:44Update product README, demo URL and deployment instructionsbeka68
  • 2026-09-23 17:37Update README.mdbeka68
  • 2026-09-23 17:33Allow immediate Brev restarts with connections in TIME_WAITbeka68
  • 2026-09-23 17:28Merge mission UX while preserving accounts and saved resultsbeka68
  • 2026-09-23 17:21Update README.mdbeka68
Все коммиты (20)
  • 2026-09-23 17:11Polish session UX and document safe updateArturEnixx
  • 2026-09-23 17:06Move tools to homepage and add visual personal results librarybeka68
  • 2026-09-23 16:44Add read-only dashboard, user accounts, persistent workspaces and detailed AI advicebeka68
  • 2026-09-23 16:17Add mission briefing and session summaryArturEnixx
  • 2026-09-23 16:11Explain initiative impacts through indicators, districts and city scorebeka68
  • 2026-09-23 15:58Add published Astana district polygons with outlines, hover details and map controlsbeka68
  • 2026-09-23 15:44Add concise showcase pitchArturEnixx
  • 2026-09-23 15:18Complete city case with budget stress events, actionable recommendations and five-slide exportbeka68
  • 2026-09-23 14:48Ignore stale plan additions and clear outdated optimization statusbeka68
  • 2026-09-23 14:47Build Python city simulator with SQLite, KZT forecasts, map, AI tools and Brev deploymentbeka68
  • 2026-09-23 14:20Start Python city simulator with versioned dataset and server environmentbeka68
  • 2026-09-23 12:47Add test file to verify GitHub uploadbeka68
Структура репозитория (44 файлов)
.dockerignore
.env.example
.gitignore
ACCEPTANCE.md
DEPLOY_BREV.md
Dockerfile
README.md
app/__init__.py
app/accounts.py
app/agent.py
app/config.py
app/db.py
app/events.py
app/library.py
app/main.py
app/model.py
app/optimizer.py
app/presentation.py
backup_db.py
codex-upload-test.txt
compose.yaml
deploy/nginx-docker.conf
deploy/nginx.conf
deploy/restart_brev.sh
docs/MERGE_REPORT.md
docs/SHOWCASE_PITCH.md
docs/UPDATE_GUIDE.md
init_env.py
requirements-dev.txt
requirements.txt
run.py
seed/dataset.json
static/api-response.js
static/app.js
static/boundaries.js
static/data/astana-districts.geojson
static/impact.js
static/index.html
static/missions.js
static/style.css
tests/test_api_response.mjs
tests/test_app.py
tests/test_missions.mjs
verify_install.py
Ветки (3)

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

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

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