AAYMA
RU
Войти

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

Симулятор управления городом: пользователь выбирает пять инициатив для пяти районов Астаны в бюджете 100, сервер валидирует план и считает Astana…

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

О проекте

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

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

Суть

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

Как устроено

backend/engine.py на данных city_data.json детерминированно применяет эффекты мер с задержкой на горизонте 8 кварталов, синергии и ограничение 0–100. Score = 0,7 × средний районный балл с учётом населения + 0,3 × балл слабейшего района − число показателей ниже 40. Поиск улучшений перебирает замены одной меры или её района. AI-разбор идёт через OpenAI Responses API со Structured Outputs и проверкой ссылок на факты и чисел, при сбое показывается явно помеченный резервный отчёт. Рейтинг команд и суточная AI-квота хранятся в SQLite.

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

  • deterministic scoring model
  • lag/synergy effects
  • single-swap improvement search
  • Structured Outputs
  • numeric claim verification
  • configurable rulesets

Метрики

Контрольный план (стоимость 95): Score 56.54307 против базовых 52.55768 (+3.99), критических показателей 0 вместо 2; 38 тестов пройдено

Особенности

Неоднозначность условия («не более двух мер из направления» против «по одной на направление») вынесена в переключаемые RULESET, решение описано в отдельном документе. Клиент не может передать свои цены или Score, сервер всё пересчитывает сам. Есть городские события («Суровая зима», «Рост нового района») как дополнительные режимы.

Стек

Python 3.12 · FastAPI · SQLite · HTML/CSS/JS · Docker · GitHub Actions · pytest

Модели

OpenAI Responses API


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

README

README.md

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

Учебный AI-симулятор управления городом для HackAlem AI / Astana Innovations. Проект команды 3-Musketeers.

У всех участников одинаковые исходные данные и бюджет 100 условных единиц. Пользователь выбирает пять инициатив для пяти условных районов Астаны; сервер проверяет ограничения, пересчитывает показатели и выдаёт Astana Quality of Life Score. AI-советник объясняет сильные стороны и компромиссы уже рассчитанного сценария. Данные, границы районов и эффекты мер синтетические; стоимость не выражена в тенге.

Что можно проверить

  • Интерактивная схема пяти районов, десять показателей и каталог из 14 мер по пяти направлениям.
  • Предварительный расчёт цены и эффекта до добавления или замены меры. Бюджет, число решений, повторы, направления и конфликты проверяются сервером.
  • Итоговый Score, изменения по районам и разложение прироста на средний балл, положение слабейшего района и критические показатели.
  • До трёх допустимых улучшений заменой одной меры или её района.
  • AI-разбор через OpenAI Responses API. Если ключа нет или вызов не удался, приложение явно показывает локальный резервный отчёт; он не выдаётся за ответ модели.
  • Сравнение до четырёх сценариев в браузере, перенос через JSON, дополнительные городские события и общий демо-рейтинг команд.

Быстрый запуск

Нужен Python 3.12 и доступ к PyPI при установке. Основной способ запуска — один процесс на одном порту. Ключ OpenAI для расчёта Score не нужен.

git clone https://github.com/BAITC-Hacks/hack-390f12b4-3-musketeers.git
cd hack-390f12b4-3-musketeers

Если репозиторий закрыт, для клонирования нужен доступ через GitHub-аккаунт команды или организаторов.

Windows PowerShell (вставьте блок целиком):

$codexPython = Join-Path $env:USERPROFILE '.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe'
if (Test-Path $codexPython) {
    & $codexPython -m venv .venv
} else {
    py -3.12 -m venv .venv
}
if (-not (Test-Path '.\.venv\Scripts\python.exe')) { throw 'Python 3.12 не найден или .venv не создалась. Установите Python 3.12 и повторите запуск.' }
.\.venv\Scripts\python.exe -m pip install -r requirements.lock.txt
if (-not (Test-Path '.env')) { Copy-Item .env.example .env }
.\.venv\Scripts\python.exe serve.py

На компьютере с Codex блок использует его Python 3.12, если этот путь существует. На остальных компьютерах нужен установленный Python 3.12, доступный через py -3.12. При сообщении No suitable Python runtime found установите Python 3.12 и повторите блок. Проверка .venv останавливает выполнение, если окружение не создалось. Правильный путь к нему — .\.venv\Scripts\python.exe, не ..venv\Scripts\python.exe. Если порт 8520 уже занят, перед последней командой выполните $env:PORT = '8522' и откройте http://127.0.0.1:8522/.

Linux / macOS:

python3.12 -m venv .venv
.venv/bin/python -m pip install -r requirements.lock.txt
test -f .env || cp .env.example .env
.venv/bin/python serve.py

Откройте приложение. Проверка сервера. UI и API доступны с одного адреса; отдельный backend запускать не требуется. Остановить сервер можно Ctrl+C. Если порт занят, задайте PORT перед запуском; HOST по умолчанию 127.0.0.1, поэтому локальный сервер не открыт в интернет. Приоритет имеют переменные окружения процесса, затем значения из .env.

requirements.lock.txt фиксирует версии для воспроизведения, включая тестовые зависимости. requirements.txt содержит прямые зависимости приложения. Старый двухпроцессный запуск run.py сохранён для разработки, но для обычного запуска и демонстрации используйте serve.py.

Демонстрация за две минуты

  1. В «Обзоре города» выберите Нуру и посмотрите исходные слабые показатели. Схема условная, а не географическая карта.
  2. В «Инициативах» нажмите «Готовый пример». Будут выбраны пять решений на 95 единиц; останется 5.
  3. Нажмите «Оценить мой план». Ожидаемый Score — 56,54 вместо исходных 52,56; прирост +3,99, критических значений станет 0 вместо 2.
  4. Откройте изменения районов и «Найти улучшения». Рекомендации пересчитаны тем же движком, что и основной результат.
  5. Откройте отдельный раздел «AI-анализ», нажмите «Сформировать AI-анализ» и проверьте обозначение источника: OpenAI · модель либо «Резервный аналитический отчёт». Сохраните сценарий для сравнения или выгрузите JSON.

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

Подключение AI

В локальном .env заполните OPENAI_API_KEY и OPENAI_MODEL. Модель должна быть доступна вашему API-проекту и поддерживать Responses API со Structured Outputs. Подписка на ChatGPT сама по себе не настраивает API-доступ. После изменения .env перезапустите сервер. Ключ остаётся на сервере; .env исключён из Git.

OPENAI_API_KEY=ваш_ключ_локально
OPENAI_MODEL=модель_из_вашего_API_проекта
RULESET=dataset-v1

Раздел AI-анализа доступен после расчёта полного плана. Сервер сам пересчитывает сценарий, передаёт модели ограниченный набор фактов и проверенных альтернатив, затем проверяет структуру ответа, ссылки на факты и числовые утверждения. Score, цены и изменения показателей считает код, не LLM. Если AI недоступен, расчёт и поиск улучшений продолжают работать. DEMO_ACCESS_CODE необязательно ограничивает доступ к AI-анализу, а AI_DAILY_LIMIT задаёт суточный лимит новых вызовов провайдера. Никогда не вводите API-ключ в поле демо-кода. Подробности об AI и статусе живой проверки.

Правила и расчёт

По умолчанию действует dataset-v1: ровно пять разных мер, не более двух из одного направления, общая стоимость не выше 100. Для районной меры нужен район; городская действует во всех пяти районах и оплачивается один раз. Часть пар мер несовместима. Порядок решений не влияет на результат. Остаток бюджета не даёт бонуса.

Подробный синтетический датасет допускает две меры одного направления, хотя краткое задание можно прочесть как требование одной меры в каждом из пяти направлений. Поэтому реализован отдельный RULESET=one-per-direction-v1; сервер выбирает режим для всех участников, а сценарии разных режимов в рейтинге не смешиваются. Обоснование выбора правил.

Для каждого показателя модель применяет эффект меры с учётом задержки, затем синергии и предел 0–100. Горизонт — 8 кварталов. Районный балл — взвешенная сумма десяти показателей. Итог:

Score = 0,7 × средний районный балл с учётом населения
      + 0,3 × балл слабейшего района
      − число показателей строго ниже 40

Промежуточные значения не округляются; интерфейс округляет числа только для показа. Контрольный пример M7 Нура, M8 Нура, M10 Нура, M12 весь город, M5 Сарыарка стоит 95 и даёт точный Score 56.54307. База без мер — 52.55768. Формула, веса, синергии и ограничения модели.

Городские события «Суровая зима» и «Рост нового района» — дополнительные учебные режимы. Они меняют исходные условия до применения мер; прирост считается относительно состояния после события. Обычный режим воспроизводит исходный датасет.

Устройство проекта

Браузер (HTML/CSS/JS)
          │
          ▼
serve.py → backend.hosted:app (FastAPI, статические файлы и API)
                        ├── backend.engine: валидация, Score, рекомендации
                        ├── backend.advisor: AI-разбор и резервный отчёт
                        └── backend.leaderboard: SQLite-рейтинг и AI-квота
ПутьНазначение
data/city_data.jsonСинтетические районы, показатели, веса, меры и правила
frontend/web/Адаптивный интерфейс без сборщика и внешних CDN
backend/engine.pyДетерминированный расчёт и проверка сценариев
backend/main.py, backend/hosted.pyAPI и единый сервер UI + API
backend/advisor.py, backend/leaderboard.pyAI-разбор, SQLite-рейтинг и лимиты
tests/Проверки модели, API, AI-проверок и публичных маршрутов

Основные API-маршруты: GET /api/data, POST /api/preview (черновик), POST /api/simulate (ровно пять решений), POST /api/recommend, POST /api/analyze, GET /api/leaderboard, POST /api/submit. Интерактивная схема API. Клиент не может передать собственные цены, веса или готовый Score: сервер берёт их из датасета и пересчитывает результат.

План и до четырёх сценариев сравнения сохраняются в localStorage текущего браузера. При загрузке сервер повторно проверяет решения. Рейтинг команд и суточная AI-квота хранятся в SQLite (DATABASE_PATH, по умолчанию runtime/city.sqlite3). Названия команд и токены владельца в демо-рейтинге не удостоверяют личность.

Проверки и публикация

.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe -m pip check
.\.venv\Scripts\python.exe -m compileall -q backend frontend serve.py run.py
node --check frontend/web/app.js

На Linux/macOS замените путь Python на .venv/bin/python. Node.js нужен только для отдельной проверки синтаксиса браузерного JS. Локально пройдены 38 тестов, проверка зависимостей, компиляция Python и node --check; основной сценарий дополнительно проверен через запущенный сервер. Тесты не расходуют API-кредиты. GitHub Actions настроен, но запуск на аккаунте GitHub блокировался биллингом; это не отметка о прошедшем CI. Протокол проверки.

Dockerfile и compose.yaml подготовлены, но сборка Docker на этой машине не проверялась. Публичный хостинг ещё не подключён. Для размещения нужны Python/Docker-хостинг, HTTPS, переменные окружения и постоянный диск для SQLite; пошаговая инструкция. Секреты не коммитятся.

Ограничения и материалы

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

Исходное задание и синтетический датасет предоставлены участником. История первоначальных коммитов команды сохранена. Презентация команды · Использование AI · Сторонние компоненты.

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

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

yessensiv 20Asylkhan 1illidan111 1

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

  • 2026-09-23 17:41Refine results layout and action panelyessensiv
  • 2026-09-23 17:33Clarify Windows setup with Codex Pythonyessensiv
  • 2026-09-23 17:25Clarify Windows Python setup in READMEyessensiv
  • 2026-09-23 17:20Separate AI analysis and handle invalid asset pathsyessensiv
  • 2026-09-23 17:09Finalize reviewed simulator and documentationyessensiv
  • 2026-09-23 17:08Document verified single-server workflowyessensiv
  • 2026-09-23 17:02Separate initiative catalog and plan visuallyyessensiv
  • 2026-09-23 16:59Clarify initiative selection flowyessensiv
Все коммиты (22)
  • 2026-09-23 16:53Fix district map focus outlineyessensiv
  • 2026-09-23 16:51Refine simulator with editorial interfaceyessensiv
  • 2026-09-23 16:40Limit test discovery and guard AI quota after demo accessyessensiv
  • 2026-09-23 16:36Add city events, shared ranking, hosted entrypoint and demo materialsyessensiv
  • 2026-09-23 16:00Redesign simulator with interactive district map and persistent scenario planningyessensiv
  • 2026-09-23 15:59Redesign simulator with interactive district map and persistent scenario planningyessensiv
  • 2026-09-23 15:17Document reproducible demo and ground recommendation effects in the engineyessensiv
  • 2026-09-23 15:16Add interactive planning, verified alternatives and grounded AI analysisyessensiv
  • 2026-09-23 15:16Implement official dataset, scenario rules and deterministic scoringyessensiv
  • 2026-09-23 15:11Document reproducible demo and ground recommendation effects in the engineyessensiv
  • 2026-09-23 15:04Add interactive planning, verified alternatives and grounded AI analysisyessensiv
  • 2026-09-23 14:48Implement official dataset, scenario rules and deterministic scoringyessensiv
  • 2026-09-23 13:44Build Astana city management simulation MVPillidan111
  • 2026-09-23 14:28Исправить комментарий о сбросе предыдущего результата при изменении выбораAsylkhan
Структура репозитория (40 файлов)
.dockerignore
.env.example
.gitattributes
.github/workflows/check.yml
.gitignore
Dockerfile
README.md
THIRD_PARTY.md
backend/__init__.py
backend/advisor.py
backend/engine.py
backend/events.py
backend/hosted.py
backend/leaderboard.py
backend/main.py
compose.yaml
data/city_data.json
docs/Akim-Demo.pptx
docs/ai-usage.md
docs/demo.md
docs/deployment.md
docs/model.md
docs/rules-decision.md
docs/verification.md
frontend/server.py
frontend/web/app.js
frontend/web/editorial.css
frontend/web/favicon.svg
frontend/web/index.html
frontend/web/styles.css
pytest.ini
requirements-dev.txt
requirements.lock.txt
requirements.txt
run.py
serve.py
tests/test_api.py
tests/test_engine.py
tests/test_extensions.py
tests/test_frontend.py
Ветки (2)

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

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

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