О проекте
Команда: Kaztend
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Доведённый продукт
Задача кейса: «Аким на 5 часов»: городской симулятор, распределяющий бюджет по 5 направлениям и 5 районам
Суть
Симулятор бюджета Астаны на FastAPI: 5 решений в пределах 100 у.е., расчёт Astana Quality of Life Score по формуле ТЗ, AI-объяснение и AI-советник с инструментами, аналитика устойчивости и Парето-фронт.
Как устроено
Детерминированный engine.simulate считает 50 показателей с лагами, синергиями и штрафами; живой валидатор блокирует превышение бюджета и несовместимости. Оптимизатор перебирает все 694 395 допустимых наборов для Парето-фронта и «лучшего набора при бюджете ≤ X». LLM-агент (OpenAI Responses API, structured outputs, function tools) вызывает catalog → validate → simulate → improve → best_under_budget и возвращает набор с трассой; есть детерминированный fallback, 5 неожиданных событий-шоков, лидерборд команд и Markdown-брифинг.
Ключевые решения
- exhaustive search
- Pareto front
- OECD/JRC weight robustness
- Gini equity index
- function calling
- structured outputs
- event shocks
Особенности
Реализованы все пять опциональных пунктов ТЗ; анализ робастности Score к весам ±20% по методологии OECD/JRC и привязка показателей к ISO 37120. Код проверяет бюджет и приоритеты даже в финальном ответе LLM; работает полностью офлайн.
Стек
Python · FastAPI · Uvicorn · Pydantic · httpx · vanilla JS · SVG · Docker · pytest
Модели
OpenAI Responses API · gpt-6-sol
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-ad342fbd-kaztend.
README
README.mdАким на 5 часов — AI-симулятор бюджета Астаны
Репозиторий: https://github.com/BAITC-Hacks/hack-ad342fbd-kaztend · Развёрнутая версия: публичного сервера нет, проект запускается локально (см. «Быстрый старт»)
Быстрый старт для жюри
Что решает. Городской управленец распределяет ограниченный бюджет, а последствия решений разнесены по районам и во времени. Симулятор делает компромиссы видимыми: единый бюджет 100 у.е., ровно 5 решений по транспорту, экологии, соцсфере, безопасности и сервисам, итоговый Astana Quality of Life Score по формуле ТЗ. Числа считает детерминированная модель, AI объясняет решения и советует, как улучшить набор.
Технологии. Python 3.11+, FastAPI, Uvicorn, OpenAI Responses API (необязательно); интерфейс — один файл frontend/index.html (ванильный JS и SVG, работает без интернета).
Запуск — нужен только Python 3.11 или новее (Windows, macOS, Linux):
git clone https://github.com/BAITC-Hacks/hack-ad342fbd-kaztend.git
cd hack-ad342fbd-kaztend
pip install -r requirements.txt
python -m uvicorn backend.app:app --port 8000
Откройте в браузере http://localhost:8000. Ключ OpenAI не нужен: без него объяснения и AI-советник работают в детерминированном режиме. Для ответов живой модели скопируйте .env.example в .env и укажите OPENAI_API_KEY.
Проверка за 2 минуты:
- «Пример из ТЗ» → Score 56.54 (база 52.56, стоимость 95, критических значений 0 вместо 2).
- Поменяйте район в любом решении → Score меняется. Набор дороже 100 у.е. собрать нельзя: валидатор блокирует расчёт и называет причину.
- Вкладка «Аналитика» → «Проанализировать»: устойчивость к весам, равенство районов, Парето-фронт.
- Вкладка «AI-советник» → любой готовый запрос → допустимый набор и трасса вызовов инструментов.
- «Неожиданное событие» → «Аварийная зима» → база и Score пересчитываются.
- Вкладка «Сценарии команд» → сохранить результат; переключатель RU/KZ в верхней панели.
Автотесты: python -m pytest -q backend/tests → 52 passed.
HackAlem AI · 23.09.2026 · Спец-трек Astana Innovations · Задача «Аким на 5 часов» · Команда Kaztend Astana Quality of Life Score считает детерминированная модель по ТЗ; AI объясняет результат, советует и ведёт трассу решений.
1. Название проекта
Аким на 5 часов (каз. «5 сағаттық әкім») — симулятор управленческих решений: один виртуальный бюджет, пять решений по пяти направлениям, итоговый Astana Quality of Life Score с объяснением компромиссов.
2. Краткое описание — какую проблему решает и для кого
Городской управленец распределяет ограниченный бюджет между транспортом, экологией, соцсферой, безопасностью и сервисами; последствия решений разнесены во времени и по районам, а компромиссы не видны. Симулятор делает их видимыми: пользователь (аким, аналитик, участник обучающей сессии или партисипаторного бюджетирования) принимает ровно 5 решений, а система показывает, как изменятся показатели пяти районов, где остались критические провалы, насколько устойчив результат и что можно сделать лучше. Подход опирается на практику бюджетных симуляторов городов США (Balancing Act/Polco) и методологию композитных индикаторов OECD/JRC; показатели соотнесены с ISO 37120:2018.
3. Что реализовано
Must-have ТЗ
| Требование ТЗ | Реализация | Как проверить |
|---|---|---|
| Единый виртуальный бюджет | 100 у.е. для всех, индикатор остатка | верхняя панель слева |
| Решения по 5 направлениям | 5 слотов «мероприятие + район», ≤2 мер одного направления | слоты решений |
| Автоматический контроль превышения бюджета | живой валидатор (/api/validate): бюджет, повторы, направления, районы, несовместимости | выбрать M3+M13+M5+M7+M8 → «Превышен бюджет: 127 > 100» |
| AI-анализ принятых решений | /api/explain — сильные стороны, риски, последствия, компромиссы (LLM или детерминированный режим) | кнопка «Объяснить сценарий» |
| Расчёт итогового Score | engine.simulate по формуле ТЗ с лагами, синергиями, штрафами | «Пример из ТЗ» → 56.54 при стоимости 95 |
| Объяснение сильных сторон, рисков, последствий | панель объяснения + вкладка «Аналитика» + брифинг | «Объяснить сценарий», «Проанализировать» |
Критерии проверки ТЗ: все команды стартуют с одних данных (данные ТЗ зашиты в engine.py); превысить бюджет нельзя (валидатор блокирует расчёт); решения влияют на показатели (тест test_score_changes_with_decisions); AI формирует понятное объяснение; изменение набора меняет Score.
Опциональные пункты ТЗ — реализованы все пять
| Опция | Реализация |
|---|---|
| Сравнение результатов команд | вкладка «Сценарии команд»: сохранение, лидерборд, открытие чужого набора |
| Визуализация изменений показателей районов | схематическая картограмма районов до/после, карточки районов с барами 10 показателей |
| AI-рекомендации по улучшению | агент-советник на естественном языке (RU/KZ) с инструментами и трассой; детерминированный советник «одна замена»; Парето-фронт и «лучший набор при бюджете ≤ X» |
| Моделирование неожиданных событий | 5 событий (аварийная зима, смог, приток населения, паводок, жара) — шок по показателям до мер, пересчёт базы и Score |
| Автогенерация краткой презентации | Markdown-брифинг для акима (/api/report) и экспорт JSON |
Сверх ТЗ: анализ робастности Score к весам (OECD/JRC, ±20 %), индекс равенства районов (разрыв, Джини, критические значения), эффективность мер (вклад в Score и Score на у.е.), паспорта показателей с привязкой к ISO 37120:2018 и паспорта мер с международными аналогами, интерфейс RU/KZ, работа полностью офлайн без ключа.
4. Как работает решение (основной сценарий)
- Пользователь выбирает 5 решений (мероприятие + район для мер типа «Район»); валидатор в реальном времени показывает нарушения правил и остаток бюджета.
- «Рассчитать Score» →
engine.simulate: новые значения 50 показателей, оценки районов, D_avg, min D, критические значения, Score; картограмма и карточки районов до/после, таблица вклада каждой меры. - «Объяснить сценарий» → LLM получает результат расчёта (не считает числа) и формулирует сильные стороны, риски, последствия, компромиссы, рекомендацию; без ключа — детерминированное объяснение.
- «Аналитика» → робастность к весам, равенство районов, эффективность мер, Парето-фронт из полного перебора 694 395 допустимых наборов.
- «AI-советник» → запрос вида «помоги Нуре, не больше 80 у.е.» → агент вызывает инструменты (catalog → validate → simulate → improve → best_under_budget), возвращает допустимый набор, обоснование и трассу; кнопка «Применить набор агента».
- Условия советника отображаются отдельными полями и доступны для ручной корректировки. Приоритет района означает минимум две районные меры; каждое приоритетное направление должно быть представлено хотя бы одной мерой, при выбранном районе — в этом районе. Бюджет и приоритеты проверяет код, включая итоговый ответ LLM и поиск одной замены. При бюджете меньше 61 объясняется невозможность собрать пять решений.
- Событие (например, «Аварийная зима») меняет исходные показатели — база и Score пересчитываются, пользователь перераспределяет решения. Советник, лучшие наборы и Парето используют это же событие.
- При изменении решений, события или языка старые результаты и объяснение сбрасываются; запоздавшие ответы не применяются. Экспорт доступен после нового расчёта и содержит согласованный снимок сценария. Сервер отклоняет брифинг с объяснением от другого сценария.
- «Сохранить» → сценарий попадает в лидерборд команд; «Скачать брифинг» → Markdown-отчёт для акима.
5. Технологии
- Backend: Python 3.11+, FastAPI, Uvicorn, Pydantic, httpx, python-dotenv.
- AI: OpenAI API — модель
gpt-6-solчерез Responses API (structured outputs, function tools); детерминированный fallback без ключа. - Frontend: один файл
frontend/index.html— ванильный JS, SVG (картограмма, шкала Score, Парето-график), без сборки и внешних CDN. - Данные: датасет ТЗ (районы, показатели, 14 мер, синергии, несовместимости),
data/passports.json, предрассчитанныеdata/top_sets.jsonиdata/pareto.json,data/scenarios.json(лидерборд). - Тесты: pytest — движок на контрольных числах ТЗ, API и регрессионные проверки событий, ограничений и атрибуции; Node.js — 6 проверок состояния интерфейса.
- Инструменты разработки: Claude (Anthropic) как AI-агент разработки, OpenAI Codex (см.
docs/CODEX_LOG.md), Git.
6. Архитектура
frontend/index.html ──JSON──▶ backend/app.py (FastAPI)
├─ engine.py расчёт Score по ТЗ, валидатор, лаги, синергии, штрафы
├─ analytics.py робастность (OECD/JRC), равенство, эффективность мер, Парето
├─ events.py шоки показателей (5 событий)
├─ agent.py LLM-агент с инструментами + детерминированный fallback
├─ ai.py LLM-объяснение (structured outputs) + fallback
├─ optimizer.py перебор допустимых наборов
├─ search.py лучшие наборы/Парето с кэшем по событию и приоритетам
├─ constraints.py разбор и проверка пользовательских ограничений
├─ store.py сценарии команд → data/scenarios.json
└─ report.py Markdown-брифинг
Подробнее: docs/ARCHITECTURE.md (схема) и docs/METHODOLOGY.md (формула, методология, источники).
7. Установка и запуск
Требования: Python 3.11 или новее (проверено на 3.12 и 3.13), Windows / macOS / Linux. Docker — по желанию.
git clone https://github.com/BAITC-Hacks/hack-ad342fbd-kaztend.git
cd hack-ad342fbd-kaztend
python -m venv .venv
Windows PowerShell:
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\scripts\run.ps1
macOS / Linux:
.venv/bin/python -m pip install -r requirements.txt
bash scripts/run.sh
Откройте http://localhost:8000. Windows-скрипты: scripts\run.ps1, scripts\test.ps1 (при блокировке: Unblock-File .\scripts\*.ps1).
Минимальные версии зависимостей указаны в requirements.txt: pip сам подберёт готовые сборки для вашей версии Python, компилятор не нужен. Скрипты запуска и тестов автоматически используют .venv, если она существует. APP_PORT поддерживается обеими версиями скрипта запуска.
Проверки: scripts/test.ps1 или bash scripts/test.sh.
Первый полный подбор для нового события/приоритетов может занять до двух минут. Результаты сохраняются в data/search_cache/ (не включается в Git); повторный запрос использует кэш. Ключ кэша учитывает событие, приоритеты и версию расчётного кода. При недоступности записи поиск продолжает работать с кэшем в памяти.
С ключом OpenAI (необязательно): скопируйте .env.example в .env и заполните OPENAI_API_KEY. Без ключа приложение работает полностью в детерминированном режиме (объяснения и советник считаются кодом).
Docker: docker compose up --build → http://localhost:8000.
8. Как проверить решение (сценарий для жюри)
python -m pytest -q backend/tests→ все тесты пройдены (в т.ч. база 52.56, пример ТЗ ≈ 56.5, дешёвый набор 61, невозможность превысить бюджет, событие меняет Score, агент, сценарии, отчёт).- Откройте http://localhost:8000 → «Пример из ТЗ» → Score 56.54 (+3.98 к базе 52.56), стоимость 95, критических значений 0 (было 2), шкала и картограмма обновились.
- Замените в слоте 1 район «Нура» на «Есиль» → «Рассчитать» → Score изменился (влияние решений).
- Добавьте шестое решение невозможно; выберите M3 Нура + M13 Нура + M5 Есиль + M7 Нура + M8 Нура → валидатор: «Превышен бюджет: 127 > 100», расчёт заблокирован.
- «Объяснить сценарий» → структурированное объяснение (источник
gpt-6-solпри ключе,deterministicбез него). - Вкладка «Аналитика» → «Проанализировать»: устойчив к весам, Джини 0.0428 → 0.0308, эффективность мер; Парето-фронт с золотым кольцом вашего сценария.
- Вкладка «AI-советник» → чип «Максимум при ≤70» → набор со Score 56.67 за 68 у.е. без события и трасса инструментов → «Применить».
- Событие «Аварийная зима» (верхняя панель) → база 52.30, Score пересчитан; «🎲 Внезапное событие» — случайное.
- «Сохранить» → вкладка «Сценарии команд»; «Скачать брифинг» →
astana_scenario_brief.md.
9. Данные и интеграции
- Входные данные — синтетический датасет ТЗ Astana Innovations (5 условных районов, 10 показателей, 14 мер, синергии, несовместимости, формула Score); персональных данных нет.
- Внешние сервисы — только OpenAI API (опционально). Никаких других аккаунтов, ключей или интернет-ресурсов не требуется.
- Паспорта показателей соотнесены с темами ISO 37120:2018; аналоги мер — из открытых описаний городских практик (см.
docs/METHODOLOGY.md, источники).
10. Ограничения
- Карта районов — схематическая картограмма (границы условных районов ТЗ не заданы); при подключении реальных данных заменяется на GeoJSON.
- Эффекты мер линейные и без неопределённости (так задано ТЗ); робастность оценивается только по весам направлений.
- Вклад мер рассчитывается по Шепли на 32 подмножествах пяти решений: учитываются синергии, clipping, смена слабейшего района, снятые и новые штрафы. Это объяснение модели, а не оценка причинного эффекта в реальном городе.
- Лидерборд хранится в файле
data/scenarios.json(для пилота достаточно; для продакшена — БД и авторизация). - Ответы LLM зависят от доступности OpenAI API; при ошибке автоматически показывается детерминированный режим.
11. Ссылки и развёрнутая версия
- Репозиторий: https://github.com/BAITC-Hacks/hack-ad342fbd-kaztend
- Развёрнутая версия: публичного сервера нет. Проект запускается локально одной командой (см. «Быстрый старт» и п. 7), внешние ресурсы и ключи не нужны.
Команда
| Участник | GitHub | Вклад |
|---|---|---|
| Сарсенбай Мағжан (капитан, главный разработчик) | @magzhansaken | архитектура, движок, API, аналитика, интерфейс, документация |
| Ерденбаев Адильжан (бэкенд-разработчик) | @AdilMoon | Существенный вклад в AI-функциональность и надёжность проекта: разработка LLM-слоя (ai.py, OpenAI Responses API, structured outputs); доработка советника с учётом событий, бюджета и приоритетов пользователя; расчёт вкладов мер по Шепли; согласованность результатов, объяснений и экспорта; настройка зависимостей и CI, регрессионные тесты backend и интерфейса, обновление документации и проверка демо-сценариев. |
| Ергараева Салтанат (фронтенд-разработчик) | @saeruoni | фронтенд: пользовательский интерфейс |
Источники
- OECD/JRC (2008). Handbook on Constructing Composite Indicators: Methodology and User Guide.
- ISO 37120:2018. Sustainable cities and communities — Indicators for city services and quality of life.
- Polco / Balancing Act — бюджетные симуляции городов США (Денвер, Лоуренс, Сан-Маркос); Bipartisan Policy Center — федеральная бюджетная симуляция.
- Systems (MDPI), 2026 — Composite Sustainable Smart City Performance Assessment Index.
- Акимат г. Астаны (2025). План развития города Астаны на 2026–2030 годы.
Контакты команды
| Роль | Участник | Контакты |
|---|---|---|
| Главный разработчик | Сарсенбай Мағжан | [email скрыт] |
| Бэкенд-разработчик | Ерденбаев Адильжан | [email скрыт] |
| Фронтенд-разработчик | Ергараева Салтанат | [email скрыт] |
Авторы коммитов
История коммитов
- 2026-09-23 16:56Fixing ReadmeAdilMoon
- 2026-09-23 16:51fix: align recommendations, attribution and exports with scenario contextAdilMoon
- 2026-09-23 17:50docs: repository link and deployment status in READMEmagzhansaken
- 2026-09-23 17:46fix(deps): minimum versions instead of pins - Python 3.14 has no wheel for pydantic-core 2.33 (build needed Rust)magzhansaken
- 2026-09-23 17:40ci: remove GitHub Actions workflow (org runners unavailable, jobs fail before start); tests run locally: 52 passedmagzhansaken
- 2026-09-23 17:38fix: pass explanation scenario id to report (409 after explain); drop obsolete old-UI frontend test from CImagzhansaken
- 2026-09-23 17:37Update README.mdmagzhansaken
- 2026-09-23 17:32Add GitHub handle for front-end developersaeruoni
Все коммиты (21)
- 2026-09-23 17:31docs: team names and roles in READMEmagzhansaken
- 2026-09-23 17:29docs: quick start for jury and team contacts in READMEmagzhansaken
- 2026-09-23 17:20fix(ui): responsive and print polish, indicator code legend, Pareto marker with events, refreshed screenshotsmagzhansaken
- 2026-09-23 17:14feat: new UI design (Astana map, 5x10 indicator matrix, score scale, agent trace) + screenshotsmagzhansaken
- 2026-09-23 16:33Update project documentationsaeruoni
- 2026-09-23 15:55CheckpointSsaeruoni
- 2026-09-23 15:08feat: design system (score gauge, cartogram, RU/KZ), README per organizers prompt, methodology docs, Dockerfile, disclosure (h4)magzhansaken
- 2026-09-23 15:01feat: analytics (OECD robustness, equity, Pareto), events, tool-using AI advisor with trace, scenarios leaderboard, briefing report, ISO 37120 passports, cartogram UI RU/KZ (h4)magzhansaken
- 2026-09-23 13:53first commitAdilMoon
- 2026-09-23 14:19feat: FastAPI API (catalog/validate/simulate/explain/advise) + web UI + 6 API tests + precomputed top sets (h3)magzhansaken
- 2026-09-23 14:11fix: place new LLM explanation layer at backend/ai.pymagzhansaken
- 2026-09-23 14:10feat: engine+validator+optimizer+tests; ai.py -> backend/ai.py as LLM explanation layer with DEMO_MODE fallback (h2)magzhansaken
- 2026-09-23 14:00feat: scoring engine + validator + optimizer per TZ, 5 tests pass (checkpoint h1)magzhansaken
Структура репозитория (49 файлов)
.env.example .gitignore AGENTS.md DISCLOSURE.md Dockerfile README.md backend/__init__.py backend/agent.py backend/ai.py backend/analytics.py backend/app.py backend/constraints.py backend/engine.py backend/events.py backend/optimizer.py backend/report.py backend/search.py backend/store.py backend/tests/conftest.py backend/tests/test_api.py backend/tests/test_engine.py backend/tests/test_regressions.py checkpoint.ps1 checkpoint.sh data/.gitkeep data/pareto.json data/passports.json data/top_sets.json demo/recordings/.gitkeep docker-compose.yml docs/ARCHITECTURE.md docs/CODEX_LOG.md docs/METHODOLOGY.md docs/TZ_CRITERIA.md docs/codex/.gitkeep docs/screenshots/.gitkeep docs/screenshots/agent-1440.png docs/screenshots/agent-390.png docs/screenshots/analytics-1440.png docs/screenshots/method-1440.png docs/screenshots/result-1440.png docs/screenshots/result-390.png docs/screenshots/result-kz-event-1440.png frontend/index.html requirements.txt scripts/run.ps1 scripts/run.sh scripts/test.ps1 scripts/test.sh
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.