AAYMA
RU
Войти

AI Urban Strategy Copilot

Симулятор «Аким на 5 часов»: пользователь собирает портфель из пяти мер по 5 районам Астаны в пределах бюджета, получает Quality of Life Score…

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

О проекте

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

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

Суть

Симулятор «Аким на 5 часов»: пользователь собирает портфель из пяти мер по 5 районам Астаны в пределах бюджета, получает Quality of Life Score, сравнивает сценарии и спрашивает AI-советника (Supervisor-агента).

Как устроено

data/city_data.json содержит 5 районов, 10 показателей и 14 мер. Python-ядро (validator, simulator, scoring) проверяет бюджет и конфликты, применяет лаги, эффекты и синергии, затем считает районные баллы и общий Score. Оптимизатор перебирает допустимые планы с отсечениями по четырём целям: max_score, balanced, focus_district, budget_efficiency. Supervisor-агент через function calling выбирает один из пяти детерминированных инструментов (inspect/validate/simulate/compare/search) и объясняет результат. Grounding-модуль пропускает только числа, которые ссылаются на поля результата инструмента.

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

  • deterministic city simulator
  • exhaustive search with pruning
  • function calling / tool calling
  • numeric grounding check
  • Supervisor agent

Особенности

Защита от выдуманных чисел: LLM ставит ссылки на поля результата инструмента, сервер проверяет их и только потом подставляет значения. Помимо этого есть GIS-карта Астаны из офлайн-тайлов OSM (mbtiles), стресс-тест кризисов, рейтинг команд и генерация «Доклада Акиму».

Стек

Python 3.12 · FastAPI · Pydantic 2 · Uvicorn · React 19 · TypeScript · Vite 6 · Tailwind CSS 4 · Recharts · Playwright · pytest · MBTiles (OSM Astana)

Модели

gpt-5.6 (OpenAI-compatible Chat Completions)


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

README

README.md

Аким на 5 часов · AI Urban Strategy Copilot

Интерактивный симулятор городских управленческих решений для кейса HackAlem «Аким на 5 часов».

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

Важно: используемые в проекте показатели и сценарии являются синтетическими данными учебного кейса. Это не официальная статистика Астаны и не реальный прогноз развития города.


1. Что решает проект

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

Пользователю нужно одновременно учитывать:

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

AI Urban Strategy Copilot объединяет детерминированную модель города и AI-агента: Python выполняет все расчёты, а LLM понимает запрос пользователя, выбирает нужный инструмент и объясняет уже рассчитанный результат.

Целевая аудитория решения в рамках кейса:

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

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

Симуляция города

  • модель пяти районов Астаны;
  • десять показателей качества городской среды;
  • 14 доступных мероприятий;
  • единый бюджет;
  • выбор ровно пяти различных решений;
  • районные и общегородские меры;
  • лаги реализации;
  • положительные и отрицательные эффекты;
  • синергии между мероприятиями;
  • несовместимости мероприятий;
  • ограничение итоговых показателей диапазоном 0–100;
  • расчёт районных оценок и итогового Quality of Life Score;
  • учёт критических показателей ниже порога.

Конструктор решений

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

Backend автоматически проверяет:

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

Невалидный сценарий не получает итоговый Score.

Аналитика результатов

После расчёта интерфейс показывает:

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

Оптимизатор сценариев

Реализован детерминированный поиск допустимых планов по четырём целям:

ЦельЧто оптимизируется
max_scoreмаксимальный итоговый Score
balancedсостояние слабейшего района и баланс между районами
focus_districtрезультат выбранного района
budget_efficiencyприрост Score относительно затрат

Оптимизатор перебирает допустимые сочетания и размещения мероприятий, применяет отсечения и повторно проверяет найденные решения основным валидатором и симулятором.

Сравнение сценариев

Два рассчитанных плана можно сравнить по:

  • Score;
  • бюджету;
  • районам;
  • показателям;
  • критическим значениям.

AI-советник

В проекте используется один Supervisor Agent.

Пользователь может написать запрос естественным языком, например:

  • «Что сейчас самое слабое в городе?»;
  • «Проверь мой план»;
  • «Почему мой сценарий получил такой Score?»;
  • «Найди лучший сценарий до бюджета 90»;
  • «Как лучше улучшить Нуру?»;
  • «Предложи более сбалансированный вариант»;
  • «Найди более сбалансированный вариант и сравни его с моим текущим планом».

Supervisor может последовательно использовать несколько инструментов и затем сформировать объяснение.

Доступные tools:

  • inspect_city_state — исходное состояние города и правила;
  • validate_scenario — проверка плана;
  • simulate_scenario — расчёт сценария;
  • compare_scenarios — сравнение двух сценариев;
  • search_scenarios — поиск допустимых стратегий.

Защита от выдуманных чисел

LLM не используется для вычисления Score, бюджета или эффектов.

Все точные числовые значения берутся из deterministic tools. Внутри ответа модель ссылается на поля результата инструмента, а сервер проверяет эти ссылки и только после этого подставляет значения.

Если модель пытается вернуть неподтверждённое число, ответ не проходит grounding-проверку.

Дополнительные интерфейсные модули

В текущем frontend также реализованы:

  • обзор города и интерактивная карта-схема;
  • радарная визуализация направлений;
  • экран стресс-теста кризисных сценариев;
  • локальный рейтинг стратегий команд;
  • генерация презентационного «Доклада Акиму» из рассчитанного сценария.

Рейтинг сохраняется в localStorage браузера. Стресс-тест кризисов реализован как отдельная клиентская демонстрационная модель и не является частью основного детерминированного городского симулятора.


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

Основной пользовательский сценарий:

1. Frontend получает исходное состояние города
                ↓
2. Пользователь выбирает 5 мероприятий
                ↓
3. FastAPI передаёт план валидатору
                ↓
4. Validator проверяет бюджет и ограничения
                ↓
5. Simulator применяет лаги, эффекты и синергии
                ↓
6. Scoring рассчитывает показатели районов и общий Score
                ↓
7. Frontend показывает результат и визуализации
                ↓
8. При необходимости пользователь:
   • сравнивает сценарии
   • запускает поиск оптимального сценария
   • задаёт вопрос AI-советнику
                ↓
9. Supervisor выбирает нужный deterministic tool
                ↓
10. Tool возвращает проверенный JSON
                ↓
11. LLM объясняет результат
                ↓
12. Grounding проверяет происхождение числовых утверждений

Таким образом, архитектура разделяет две ответственности:

  • Python-код отвечает за факты и вычисления;
  • LLM отвечает за понимание намерения пользователя, выбор tools и объяснение результата.

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

Backend и расчётное ядро

  • Python 3.12;
  • FastAPI;
  • Pydantic 2;
  • Uvicorn;
  • HTTPX;
  • python-dotenv;
  • pytest.

Frontend

  • React 19;
  • TypeScript;
  • Vite 6;
  • Tailwind CSS 4;
  • Recharts;
  • Lucide React;
  • Playwright для end-to-end тестов.

AI

Проект использует Chat Completions-совместимый LLM API с:

  • function calling;
  • JSON output;
  • tool calling.

В .env.example в качестве модели указан:

gpt-5.6

По умолчанию используется OpenAI-compatible endpoint:

https://api.openai.com/v1

Провайдер задаётся через переменные окружения, поэтому расчётная часть проекта не зависит от наличия LLM и продолжает работать без API-ключа.


5. Архитектура проекта

frontend/
    React + TypeScript UI
          │
          │ HTTP /api/*
          ▼
backend/
    FastAPI
          │
          ├──────────────► validator
          │
          ├──────────────► simulator
          │
          ├──────────────► optimizer
          │
          ├──────────────► comparison
          │
          │
          └──────────────► AI Supervisor
                              │
                              ▼
                     deterministic tools
                              │
                              ▼
                          grounding

Основные директории:

ai/
  agent.py            # Supervisor и LLM transport
  system_prompt.md    # правила поведения агента
  tools.py            # пять инструментов агента
  grounding.py        # проверка ссылок на tool evidence
  validator.py        # проверка сценария
  simulator.py        # эффекты, лаги и синергии
  scoring.py          # расчёт районов и общего Score
  optimizer.py        # полный поиск допустимых сценариев
  comparison.py       # сравнение двух сценариев
  data.py             # загрузка данных

backend/
  main.py             # FastAPI endpoints и раздача frontend
  schemas.py          # Pydantic-модели расчётного ядра
  agent_schemas.py    # схемы AI-запросов и ответов

frontend/
  src/                # React-интерфейс
  e2e/                # Playwright сценарии

data/
  city_data.json      # структурированные данные учебного кейса

rules/
  ...                 # исходные правила кейса

scripts/
  demo.py             # воспроизводимые примеры без LLM
  eval_agent.py       # opt-in проверка реального AI Supervisor

tests/
  ...                 # unit/integration тесты

6. API

FastAPI предоставляет следующие основные endpoints:

МетодEndpointНазначение
GET/api/healthсостояние backend и наличие AI-конфигурации
GET/api/contextданные города, меры, ограничения, baseline
POST/api/validateпроверка выбранного плана
POST/api/simulateполный расчёт сценария
POST/api/searchпоиск оптимальных сценариев
POST/api/compareсравнение двух планов
POST/api/chatзапрос к AI Supervisor
POST/api/analyzeAI-объяснение уже проверенного расчёта

Swagger/OpenAPI после запуска:

http://127.0.0.1:8000/docs

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

Требования

  • Python 3.12;
  • Node.js 22.13+;
  • npm.

Windows PowerShell

Из корня репозитория:

py -3.12 -m venv .venv
.venv/Scripts/python.exe -m pip install -r requirements.lock.txt

npm.cmd --prefix frontend ci
npm.cmd --prefix frontend run build

.venv/Scripts/python.exe -m uvicorn backend.main:app --host 127.0.0.1 --port 8000

После запуска откройте:

http://127.0.0.1:8000

FastAPI раздаёт собранный frontend/dist.

Linux / macOS

Эквивалентный запуск:

python3.12 -m venv .venv
.venv/bin/python -m pip install -r requirements.lock.txt

npm --prefix frontend ci
npm --prefix frontend run build

.venv/bin/python -m uvicorn backend.main:app --host 127.0.0.1 --port 8000

Режим frontend-разработки

Backend должен быть запущен на порту 8000.

Во втором терминале:

npm.cmd --prefix frontend run dev

Frontend будет доступен по адресу:

http://127.0.0.1:5173

Vite проксирует запросы /api на backend.


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

Детерминированная симуляция, поиск и сравнение работают без LLM.

Для AI-советника создайте корневой файл .env на основе .env.example:

LLM_API_KEY=<your-api-key>
LLM_MODEL=gpt-5.6
LLM_BASE_URL=https://api.openai.com/v1

После изменения .env полностью перезапустите backend.

Проверка конфигурации:

Invoke-RestMethod http://127.0.0.1:8000/api/health

Ожидаемый формат:

{
  "status": "ok",
  "ai_configured": true
}

ai_configured: true означает, что backend видит необходимые переменные окружения. Реальный вызов модели проверяется через /api/chat или через scripts/eval_agent.py.

API-ключ не должен добавляться в Git. Файл .env исключён через .gitignore.


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

Вариант A — через интерфейс

  1. Запустите приложение.
  2. Откройте «Конструктор решений».
  3. Используйте демонстрационный портфель или выберите пять мероприятий самостоятельно.
  4. Запустите расчёт.
  5. Проверьте:
    • соблюдение бюджета;
    • итоговый Score;
    • изменения районов;
    • критические показатели;
    • синергии.
  6. Измените одно из решений и рассчитайте новый сценарий.
  7. Используйте сравнение результатов.
  8. Откройте AI-советник и выполните, например:
Найди лучший сценарий до бюджета 90

или:

Как лучше улучшить Нуру?

При настроенном LLM Supervisor должен вызвать search_scenarios, а найденные значения должны поступить из deterministic optimizer.

Для проверки multi-tool сценария:

Найди более сбалансированный вариант и сравни его с моим текущим планом

Supervisor может последовательно выполнить поиск и сравнение.

Вариант B — воспроизводимый demo без LLM

.venv/Scripts/python.exe -m scripts.demo

Скрипт воспроизводит:

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

Вариант C — тесты

Backend:

.venv/Scripts/python.exe -m pytest -q

Frontend build:

npm.cmd --prefix frontend run build

Browser E2E:

cd frontend
npx.cmd playwright install chromium
npm.cmd run test:e2e

Проверка реального AI routing

При настроенных LLM_API_KEY и LLM_MODEL:

.venv/Scripts/python.exe -m scripts.eval_agent

Live evaluator проверяет наблюдаемые свойства агента:

  • доступность ответа;
  • выбранные tools;
  • аргументы tool calls;
  • наличие evidence;
  • прохождение grounding.

Он не оценивает качество текста субъективной метрикой.


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

Данные

Основной набор данных находится в:

data/city_data.json

Он содержит:

  • пять районов;
  • доли населения;
  • десять индикаторов;
  • веса индикаторов;
  • 14 мероприятий;
  • стоимость и лаг каждого мероприятия;
  • эффекты;
  • синергии;
  • несовместимости;
  • демонстрационный план.

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

Внешние интеграции

Основной runtime не использует:

  • базу данных;
  • внешнюю GIS-платформу;
  • официальные городские API;
  • внешние сервисы статистики.

Единственная необязательная внешняя интеграция расчётного приложения — Chat Completions-совместимый LLM API для AI-советника.

Если LLM недоступна, остаются работоспособными:

  • валидация;
  • симуляция;
  • поиск;
  • сравнение;
  • визуализация результатов.

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

Основные ограничения модели:

  • бюджет — 100 единиц;
  • пользовательский сценарий содержит ровно пять различных мероприятий;
  • ровно по одному мероприятию каждого из пяти направлений;
  • районная мера требует назначения района;
  • общегородская мера не требует района;
  • часть комбинаций мероприятий несовместима;
  • эффект меры учитывает лаг на горизонте восьми кварталов;
  • синергии применяются отдельно;
  • показатели после всех изменений ограничиваются диапазоном 0–100.

Реализованный эффект мероприятия:

effect_share = (8 - lag) / 8
realized_effect = effect × effect_share

Районная оценка:

D_d = Σ(weight × indicator)

Средняя городская оценка:

D_avg = Σ(population_share × D_d)

Итоговый Score:

Score = 0.7 × D_avg + 0.3 × min(D_d) - N_crit

N_crit — количество пар «район × показатель» со значением строго ниже 40.


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

Подтверждённые ограничения проекта:

  • данные синтетические и не являются реальной статистикой Астаны;
  • результат модели нельзя трактовать как реальный прогноз городской политики;
  • AI-зависимая часть требует отдельного LLM API key;
  • LLM не выполняет расчёты и не является источником числовых значений;
  • оптимизатор работает на фиксированном наборе данных и правил;
  • сервер не хранит пользовательские сессии;
  • отдельной базы данных нет;
  • рейтинг команд хранится только локально в браузере через localStorage;
  • встроенные кризисные сценарии являются демонстрационной frontend-моделью и не изменяют состояние основного optimizer/simulator;
  • полноценная оптимизация нового городского состояния после кризиса в расчётном ядре не реализована;
  • внешние реальные городские данные и GIS API не подключены.

13. Deployed-версия

В текущем репозитории не обнаружена подтверждённая ссылка или конфигурация публичного deployment.

Проект воспроизводимо запускается локально:

http://127.0.0.1:8000

Если появится публичная deployed-версия, ссылку можно добавить в этот раздел.


Ключевая идея проекта

LLM не должна придумывать городские показатели.

В AI Urban Strategy Copilot:

LLM понимает задачу
        ↓
выбирает tool
        ↓
Python рассчитывает результат
        ↓
LLM объясняет только проверенные данные
        ↓
grounding контролирует числовые утверждения

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

Звёзды
⭐ 1
Форки
0
Язык
TypeScript
Последний push
в прошлом месяце
Коммиты
26
Авторы
4
Файлы
86
Ветки
5

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

Salamat 14Sladok 9Akhmedyanov Salamat 2Corv23 1

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

  • 2026-09-23 17:58Merge pull request #5 from BAITC-Hacks/frontendAkhmedyanov Salamat
  • 2026-09-23 17:56fix: require one decision per city directionSalamat
  • 2026-09-23 17:40feat: add mobile header styles, test script, and visual assetsSalamat
  • 2026-09-23 17:26feat: add frontend styles, components, and interactive header test suiteSalamat
  • 2026-09-23 17:15fix(map): expand map to 100% width with horizontal district stripSalamat
  • 2026-09-23 17:13feat: add map-wide.png image to frontendSalamat
  • 2026-09-23 17:13chore: remove fileSalamat
  • 2026-09-23 17:11chore: remove temporary debug test scriptsSalamat
Все коммиты (26)
  • 2026-09-23 17:08feat: add frontend UI styles, environment types, and overview componentSalamat
  • 2026-09-23 16:58feat: initialize full-stack application with backend, frontend UI, and map tilesSalamat
  • 2026-09-23 16:38fix(vite): allow port fallback when 5173 is occupiedSalamat
  • 2026-09-23 16:35docs: rewrite README for hackathon jurySladok
  • 2026-09-23 16:28Merge pull request #4 from BAITC-Hacks/ai-agentSladok
  • 2026-09-23 16:25feat: improve AI supervisor orchestrationАлександр Юрышев
  • 2026-09-23 16:21feat(map): ultra-detailed GIS map of Astana with zoom/pan, waterways, bridges, landmarks, and fullscreen viewSalamat
  • 2026-09-23 16:19feat(frontend): Situational Center 2.0 with GIS heatmaps, 5-axis Radar, Crisis stress-test, Team Leaderboard, Pitch Deck and Control Plan integrationSalamat
  • 2026-09-23 16:12chore: add .env to gitignoreSalamat
  • 2026-09-23 15:29Merge pull request #3 from BAITC-Hacks/salamat-treeSladok
  • 2026-09-23 15:28feat: finalize AI supervisor integrationАлександр Юрышев
  • 2026-09-23 14:45Merge pull request #2 from BAITC-Hacks/salamat-treeSladok
  • 2026-09-23 14:44feat: polish frontend and update READMEАлександр Юрышев
  • 2026-09-23 14:38Add canonical district dataset rules sourceCorv23
  • 2026-09-23 14:34feat: complete working urban strategy copilot MVPАлександр Юрышев
  • 2026-09-23 14:19Merge pull request #1 from BAITC-Hacks/salamat-treeAkhmedyanov Salamat
  • 2026-09-23 14:17feat: add city simulator architectureАлександр Юрышев
  • 2026-09-23 14:10FIRST commitSalamat
Структура репозитория (86 файлов)
.env.example
.gitignore
README.md
ai/__init__.py
ai/agent.py
ai/comparison.py
ai/data.py
ai/grounding.py
ai/optimizer.py
ai/scoring.py
ai/simulator.py
ai/system_prompt.md
ai/tools.py
ai/validator.py
backend/__init__.py
backend/agent_schemas.py
backend/main.py
backend/schemas.py
backend/tiles.py
data/city_data.json
examples/requests.http
frontend/.gitkeep
frontend/arcgis-jsapi-view.png
frontend/arcgis-webscene-view.png
frontend/e2e/strategy.spec.ts
frontend/header-fixed-1440.png
frontend/header-mobile-375.png
frontend/header-mobile-menu-open.png
frontend/header-mobile-profile-open.png
frontend/header-nav-dropdown.png
frontend/header-profile-open.png
frontend/header-sidebar-collapsed.png
frontend/index.html
frontend/map-panel-view.png
frontend/new-map-boundaries.png
frontend/new-map-nura-selected.png
frontend/new-map-saryarka-selected.png
frontend/package-lock.json
frontend/package.json
frontend/playwright.config.ts
frontend/public/favicon.svg
frontend/public/test-arcgis.html
frontend/src/Advisor.tsx
frontend/src/App.tsx
frontend/src/Builder.tsx
frontend/src/Crisis.tsx
frontend/src/Leaderboard.tsx
frontend/src/Overview.tsx
frontend/src/PitchDeck.tsx
frontend/src/Results.tsx
frontend/src/api.ts
frontend/src/components.tsx
frontend/src/main.tsx
frontend/src/mapData.ts
frontend/src/styles.css
frontend/src/types.ts
frontend/src/vite-env.d.ts
frontend/test-arcgis.mjs
frontend/test-header-1440.png
frontend/test-header-768.png
frontend/test-header-interactions.mjs
frontend/test-map-boundaries.mjs
frontend/test-mobile-header.mjs
frontend/test-pitemx.mjs
frontend/tsconfig.json
frontend/vite.config.ts
idea.md
instruct.md
item.pitemx
osm-2020-02-10-v3.11_kazakhstan_astana.mbtiles
pyproject.toml
requirements.lock.txt
requirements.txt
rules/Аким на 5 часов датасет.md
scripts/demo.py
scripts/eval_agent.py
slides.txt
tests/test_agent.py
tests/test_api.py
tests/test_eval_agent.py
tests/test_llm_config.py
tests/test_optimizer.py
tests/test_simulator.py
tests/test_tiles.py
tests/test_tools.py
tests/test_validator.py
Ветки (5)

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

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

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