AAYMA
RU
Войти

AstanaSIM AI

Веб-симулятор «Аким на 5 часов»: пользователь выбирает 5 из 14 городских инициатив в рамках бюджета 100, система пересчитывает показатели 5 районов…

Рабочий MVP
Команда «it solution» 3💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: it solution
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Рабочий MVP

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

Суть

Веб-симулятор «Аким на 5 часов»: пользователь выбирает 5 из 14 городских инициатив в рамках бюджета 100, система пересчитывает показатели 5 районов и выдаёт Astana Quality of Life Score с AI-объяснением.

Как устроено

Параметры районов, веса, меры, эффекты, синергии и несовместимости лежат в data/model-data.json. Браузер (vanilla JS) отправляет только коды мер и районы. Серверное ядро model_engine.py заново валидирует бюджет и ограничения, применяет эффекты с лагами и синергиями и считает Score = 0,7·D_avg + 0,3·D_min − N_crit. Результат уходит в OpenAI Responses API за текстовым разбором, а если API недоступен, срабатывает детерминированный fallback.

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

  • взвешенный индекс районов
  • формула Score 0.7·avg+0.3·min−штраф
  • временные лаги и синергии мер
  • серверная валидация
  • детерминированный fallback
  • localStorage-сравнение команд

Особенности

Сервер не доверяет клиенту: цены, эффекты и Score пересчитываются из канонического JSON. Статический сервер закрывает доступ к .env и исходникам. Всё написано на стандартной библиотеке Python без зависимостей. Есть 9 unittest-тестов модели и лаунчеры для Windows и macOS.

Стек

Python · http.server · JavaScript · HTML · CSS · unittest

Модели

OpenAI Responses API · gpt-5-mini


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

README

README.md

AstanaSIM AI — «Аким на 5 часов»

Веб-симулятор для оценки управленческих решений в условном городе. Пользователь распределяет единый бюджет между городскими инициативами, моделирует последствия для районов и получает итоговую оценку Astana Quality of Life Score с понятным объяснением от AI.

Интерфейс

Выбор инициатив и контроль бюджета

Главная страница AstanaSIM AI с выбранными инициативами

Итоговый дашборд, карта и AI-анализ

Итоговый экран AstanaSIM AI с картой районов и сравнением команд

1. Проблема и пользователи

При развитии города нельзя улучшать транспорт, экологию, социальную инфраструктуру, безопасность и сервисы независимо друг от друга: бюджет ограничен, а решение в одном направлении способно улучшить или ухудшить другой показатель. В результате сложно быстро сравнивать сценарии и объяснять их компромиссы.

Проект предназначен для:

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

Все данные в текущей версии синтетические: проект не использует персональные, закрытые или оперативные городские данные.

2. Что реализовано

ВозможностьЧто делает
Единые стартовые условияВсе сценарии начинаются с бюджета 100 условных единиц и одного набора районных показателей.
Каталог инициативДоступно 14 мероприятий в пяти направлениях: транспорт, экология, социальная сфера, безопасность и городские сервисы.
Выбор пяти решенийМожно выбрать ровно пять инициатив, максимум две из одного направления.
Контроль бюджетаСистема не позволяет выбрать набор дороже 100 условных единиц.
Ограничения моделиПроверяются несовместимые мероприятия и условия выбора для отдельных инициатив.
Пересчёт в реальном времениДо подтверждения показываются выбранные меры, расходы, остаток бюджета и ожидаемые изменения.
Итоговый экранПосле подтверждения сценария открывается отдельная страница с бюджетом, общим баллом, оценками направлений, изменениями по районам и синергиями.
Схема районовНа итоговом экране показана интерактивная условная карта пяти синтетических районов: цвет отражает индекс, а подсказка — точное изменение.
Демо-сценарииТри готовых набора — «Сбалансированный», «Фокус на Нуру» и «Цифровой город» — заполняют выбор для быстрого показа.
Сравнение командДо трёх результатов можно сохранить в браузере по названию команды и сравнить по Score, приросту и бюджету.
Серверная валидацияСервер заново проверяет идентификаторы, районы, бюджет, ограничения и рассчитывает Score из канонического JSON. Клиентские цены и результаты не принимаются на доверии.
Защита локальных секретовВеб-сервер раздаёт только публичные файлы приложения; прямой доступ к .env, исходному Python-коду и служебным каталогам закрыт.
AI-анализСервер передаёт рассчитанный результат в OpenAI API и получает текстовое объяснение сильных сторон, рисков и рекомендации.
Надёжный fallbackЕсли ключ отсутствует, API недоступен или отвечает ошибкой, сервер создаёт детерминированный анализ по уже рассчитанным данным — итог не остаётся пустым.
Прозрачные данныеПараметры районов, веса, меры, эффекты, синергии и ограничения вынесены в редактируемый JSON.
Проверка моделиДевять Python-тестов проверяют базовый Score, контрольный и демо-сценарии, бюджет, ограничения, районы и защиту сервера от подмены клиентских значений.

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

  1. Приложение загружает исходные показатели пяти условных районов и параметры модели из data/model-data.json.
  2. Пользователь загружает один из трёх демо-сценариев либо вручную выбирает пять мер и назначает район там, где это требуется.
  3. Интерфейс сразу проверяет бюджет, лимит в два решения на направление, несовместимость мер и дополнительные условия.
  4. После подтверждения браузер передаёт серверу только коды мер и районы. Единое ядро model_engine.py повторно проверяет сценарий и применяет эффекты, временные лаги и синергии.
  5. Рассчитываются новые районные индексы, средний городской индекс, минимальный районный индекс, критические показатели и итоговый Astana Quality of Life Score. Условная карта окрашивает районы по их итоговому индексу.
  6. На экран результата выводятся численные итоги. Затем OpenAI API формирует человеческое объяснение; при недоступности API его заменяет встроенный детерминированный анализ.
  7. Результат можно сохранить под названием команды и сравнить ещё с двумя сценариями в этом браузере. Кнопка «Начать заново» возвращает к исходному экрану.

4. Математическая модель

Показатели

Каждый из десяти показателей имеет шкалу от 0 до 100: чем больше значение, тем лучше. Районный индекс — взвешенная сумма его показателей:

$$ D_d = \sum_{k=1}^{10} w_k \cdot x_{d,k} $$

где $D_d$ — индекс района, $x_{d,k}$ — значение показателя $k$ в районе $d$, а $w_k$ — вес критерия $k$. Сумма всех весов равна 1.

КодКритерийВес
T1Скорость и доступность транспорта0,10
T2Надёжность общественного транспорта0,10
E1Обеспеченность зелёными зонами0,09
E2Качество воздуха0,11
S1Доступность социальных объектов0,11
S2Качество социальных услуг0,11
B1Уровень преступности и личной безопасности0,09
B2Безопасность улиц и дорог0,09
C1Качество коммунальной инфраструктуры0,10
C2Доступность цифровых городских сервисов0,10

Городской средний индекс учитывает население районов:

$$ D_{avg} = \sum_d p_d \cdot D_d $$

где $p_d$ — доля населения района $d$. Минимальный индекс $D_{min}$ — значение самого отстающего района.

Итоговый Astana Quality of Life Score

$$ \text{Score} = 0{,}7 \cdot D_{avg} + 0{,}3 \cdot D_{min} - N_{crit} $$

$N_{crit}$ — количество показателей со значением ниже 40. Таким образом, модель одновременно поощряет рост качества жизни в среднем по городу, поддерживает самый слабый район и штрафует сценарии, оставляющие критические проблемы.

Для меры могут задаваться:

  • прямое изменение конкретного показателя;
  • временной лаг в кварталах;
  • эффект для всего города;
  • синергия двух совместимых мероприятий;
  • ограничение совместимости выбранных мероприятий.

Расчёт выполняется детерминированно единым серверным ядром model_engine.py, поэтому один и тот же набор решений всегда даёт один и тот же численный результат. Браузер не передаёт серверу готовый Score, цены или эффекты. AI объясняет проверенный расчёт, но не заменяет его.

5. Исходные данные

В модели пять условных районов. Начальный общий Score — 52,56.

РайонНаселениеСтартовый районный индексХарактерный вызов
Есиль0,2762,99Транспортная нагрузка и социальная инфраструктура.
Алматы0,2457,06Состояние коммунальной инфраструктуры и транспорт.
Сарыарка0,2054,65Экология и городская среда.
Байконур0,1356,63Уличная безопасность и сервисы.
Нура0,1649,18Наиболее слабый район, требующий приоритетного внимания.

Направления инициатив:

НаправлениеПримеры доступных решений
ТранспортВыделенные автобусные полосы, умные светофоры, линия ЛРТ или расширение.
ЭкологияПарк или сквер, чистое топливо, озеленение и ветрозащитные полосы.
Социальная сфераШкола и детсад, центр семейного здоровья, спортивные хабы.
БезопасностьОсвещение и камеры Safe City, безопасные переходы и школьные зоны.
Городские сервисыЕдиная цифровая платформа обращений, модернизация сетей, аварийные бригады ЖКХ.

Полный набор исходных цифр, стоимостей, эффектов и правил находится в data/model-data.json.

6. Правила сценария

ПравилоЗначение
Общий бюджет100 условных единиц
Горизонт моделирования8 кварталов
Число решенийРовно 5
Лимит направленияНе более 2 мер из одного направления
Критический показательЗначение ниже 40
Превышение бюджетаЗаблокировано интерфейсом и моделью

7. Технологии

ОбластьИспользование в проекте
Клиентская частьHTML, CSS, JavaScript без внешнего frontend-фреймворка.
Интерфейсapp.js: выбор решений, демо-сценарии, вызов API, карта и локальное сравнение результатов.
Ядро моделиmodel_engine.py: единая серверная реализация валидации, эффектов, синергий и формулы Score.
Данные моделиJSON-файл data/model-data.json.
СерверPython стандартной библиотеки (http.server, urllib) в server.py.
AIOpenAI Responses API; используемая модель задаётся переменной OPENAI_MODEL (по умолчанию gpt-5-mini).
Настройка ключаПеременные окружения в локальном файле .env; run.bat на Windows и run.command на macOS запрашивают ключ, если файла или ключа нет.
ТестыPython unittest, без сторонних зависимостей.

8. Архитектура

data/model-data.json
   ├────────► app.js ─────────► index.html + styles.css
   │             │                   │
   │             │ коды мер          │ выбор, карта, localStorage
   │             ▼                   ▼
   └────► model_engine.py ◄──── server.py
                ▲                   │
                │                   ├────► OpenAI API
       tests/model_test.py          │          │
                                    └─ fallback
                                         │
                              итоговый Score и объяснение

Компоненты взаимодействуют так:

  • index.html задаёт структуру стартового и итогового экранов;
  • styles.css отвечает за адаптивность, анимацию ожидания AI и плавающую карточку бюджета;
  • app.js загружает каталог, управляет выбором, вызывает API и хранит до трёх сравнений в localStorage;
  • server.py раздаёт приложение, публикует /api/health, /api/model-summary, /api/simulate и /api/analyze;
  • model_engine.py является единственным ядром итогового расчёта для приложения и тестов;
  • run.bat и run.command подготавливают окружение и запускают сервер на Windows и macOS;
  • tests/model_test.py импортирует рабочее ядро и проверяет модель и защиту от подмены клиентских значений.

9. Установка и запуск

Требования

  • Windows или macOS;
  • установленный Python 3 (py на Windows или python3 на macOS);
  • ключ OpenAI API — только для получения внешнего AI-анализа. Без ключа приложение и математическая модель продолжают работать, а текст анализа создаётся встроенным fallback.

Запуск на Windows

  1. Откройте терминал в папке проекта.

  2. Запустите:

    run.bat
    

Запуск на macOS

Рекомендуемый способ — запуск через Terminal. Он не требует отключать Gatekeeper или менять настройки безопасности:

cd /путь/к/hack-bc9ad702-it-solution
bash run.command

Если macOS уже переместила run.command в корзину после двойного нажатия, восстановите файл из корзины или заново получите репозиторий, а затем запустите его указанной выше командой. Это реакция Gatekeeper на скачанный скрипт без подписи Apple, а не ошибка запуска проекта.

Для запуска через Finder нажмите на run.command правой кнопкой, выберите Открыть, затем ещё раз подтвердите Открыть. Если такой кнопки нет, используйте рекомендуемый запуск через Terminal.

При первом запуске любой из скриптов создаст .venv. Если OPENAI_API_KEY ещё не задан, скрипт предложит вставить ключ. При пустом вводе приложение всё равно запустится, а объяснение результата сформирует детерминированный fallback. В .env не записывается шаблонный или выдуманный ключ.

После запуска браузер автоматически откроет веб-приложение. Если этого не произошло, откройте адрес, показанный в терминале. По умолчанию это http://localhost:8081. Если порт занят, скрипт автоматически выберет следующий свободный порт в диапазоне 8081–8090.

Файл .env не должен попадать в репозиторий: он содержит секретный ключ. Для смены модели достаточно указать в .env, например:

OPENAI_MODEL=gpt-5-mini

Если сценарий не подтверждается

Если основной порт занят старой версией сервера, скрипт запуска выведет предупреждение и запустит актуальную версию на следующем свободном порту. Откройте именно адрес из терминала. При сообщении «Сервер не рассчитал сценарий» выполните принудительное обновление страницы (Ctrl+F5 на Windows или Command+Shift+R на macOS) и проверьте, что адрес и порт совпадают с указанными в терминале.

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

Быстрая ручная проверка

  1. Запустите приложение через run.bat на Windows или run.command на macOS.
  2. Выберите пять инициатив; интерфейс должен показывать остаток бюджета и не дать превысить 100 условных единиц.
  3. Убедитесь, что кнопка подтверждения появляется только после корректного выбора пяти решений.
  4. Подтвердите сценарий. Отобразится анимация расчёта, затем — отдельный итоговый экран.
  5. Проверьте, что показаны затраты, Score до и после, оценки направлений, влияние на районы, синергии и AI-анализ либо fallback-анализ.
  6. Введите название команды и сохраните результат. Повторите сценарий ещё раз и проверьте сравнение результатов.
  7. Нажмите «Начать заново» и убедитесь, что открывается исходный экран.

Быстрая проверка демо-сценариев

СценарийБюджетИтоговый ScoreПриростКритические показатели
Сбалансированный8355,50+2,941
Фокус на Нуру9355,61+3,051
Цифровой город7855,75+3,191

Эти результаты детерминированы текущей версией data/model-data.json и проверяются автоматическим тестом.

Контрольный сценарий

Для воспроизводимой проверки выберите следующие меры:

МераРайонСтоимость
M7 — Школа + детсадНура24
M8 — Центр семейного здоровьяНура20
M10 — Освещение и камеры Safe CityНура12
M12 — Единая цифровая платформа обращенийГород14
M5 — Чистое топливо для частного сектораСарыарка25

Ожидаемый результат текущей модели: расходы 95 из 100, Score 52,56 → 56,54 (рост +3,98), критических показателей 0 и одна синергия M10 + M12 для Нуры.

Автоматические тесты

Запустите:

test.bat

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

11. Данные и интеграции

Источник или компонентРоль
data/model-data.jsonЕдинственный активный и достаточный источник модели в репозитории: районы, веса, стартовые оценки направлений, инициативы, эффекты, синергии и ограничения.
model_engine.pyКаноническая реализация расчёта, одинаково используемая сервером и автоматическими тестами.
OpenAI Responses APIФормирует текстовое объяснение рассчитанного сценария при наличии действующего ключа.

Интеграция с OpenAI является дополнительной: финансовые расчёты, выбор инициатив и итоговый Score не зависят от ответа внешнего API.

12. Ограничения текущей версии

  • Данные синтетические и предназначены для демонстрации, а не для реального бюджетного планирования.
  • Результат — учебная модель с фиксированными весами и эффектами; он не заменяет экспертную, экономическую или общественную оценку.
  • AI-анализ зависит от доступности и настроек OpenAI API. При ошибке используется локальный шаблонный анализ, а не языковая модель.
  • Сравнения сохраняются только в localStorage текущего браузера: общей базы команд, авторизации и синхронизации между устройствами нет.
  • Автоматический экспорт презентации не реализован.
  • Деплой-версии в текущем репозитории нет: приложение запускается локально.

13. Дальнейшее развитие

Ближайшие задачи, которые усилили бы демонстрацию для жюри:

  1. Добавить графики динамики показателей по кварталам рядом с уже реализованной схемой районов.
  2. Реализовать неожиданное городское событие с необходимостью перераспределить бюджет.
  3. Перенести сравнение команд из localStorage в общую базу с авторизацией.
  4. Добавить отдельный расширенный режим модели с убывающей отдачей и сценарным анализом, сохранив базовую формулу неизменной для воспроизводимости.
  5. Подготовить скриншоты или короткое видео основного пользовательского сценария для презентации проекта.
Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
26
Авторы
2
Файлы
17
Ветки
2

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

iskanderCabbie 22iskanderCabbie 4

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

  • 2026-09-23 17:571iskanderCabbie
  • 2026-09-23 17:57Open simulator automatically after launchiskanderCabbie
  • 2026-09-23 17:50Document Gatekeeper-safe macOS startupiskanderCabbie
  • 2026-09-23 17:47Merge remote-tracking branch 'origin/main'iskanderCabbie
  • 2026-09-23 17:47Add macOS launcheriskanderCabbie
  • 2026-09-23 17:38Remove deployed version section from READMEiskanderCabbie
  • 2026-09-23 17:34Fix mathematical formulas in READMEiskanderCabbie
  • 2026-09-23 17:33Organize README screenshotsiskanderCabbie
Все коммиты (26)
  • 2026-09-23 17:30Release AstanaSIM AI final versioniskanderCabbie
  • 2026-09-23 17:30Finalize startup checks and project documentationiskanderCabbie
  • 2026-09-23 17:19Update README with current model data and demo scenariosiskanderCabbie
  • 2026-09-23 17:15Rename project to AstanaSIM AIiskanderCabbie
  • 2026-09-23 17:14Merge pull request #2 from BAITC-Hacks/codexiskanderCabbie
  • 2026-09-23 17:09Fix initial model loadingiskanderCabbie
  • 2026-09-23 17:06Add verified scenarios and team comparisoniskanderCabbie
  • 2026-09-23 16:41Remove source documents from repositoryiskanderCabbie
  • 2026-09-23 16:39Ignore source dataset filesiskanderCabbie
  • 2026-09-23 16:35Rewrite README with comprehensive project documentationiskanderCabbie
  • 2026-09-23 16:19Add scenario transition UI and deterministic analysis fallbackiskanderCabbie
  • 2026-09-23 16:06Externalize simulation model data into configurable JSONiskanderCabbie
  • 2026-09-23 15:35Merge pull request #1 from BAITC-Hacks/codexiskanderCabbie
  • 2026-09-23 15:29Implement MVP city planning simulation and document decision modeliskanderCabbie
  • 2026-09-23 14:43рабочая версияiskanderCabbie
  • 2026-09-23 13:54добавлен venv и run.batiskanderCabbie
  • 2026-09-23 13:46docs: add simulator implementation planiskanderCabbie
  • 2026-09-23 13:27docs: add MVP task checklistiskanderCabbie
Структура репозитория (17 файлов)
.gitattributes
.gitignore
README.md
app.js
data/model-data.json
docs/screenshots/results-screen.jpeg
docs/screenshots/selection-screen.jpeg
index.html
model_engine.py
run.bat
run.command
server.py
styles.css
test.bat
tests/model_test.py
Инструкция по работе с сайтом.docx
Отчет.docx
Ветки (2)

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

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

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