О проекте
Команда: chrollo
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Доведённый продукт
Задача кейса: «Аким на 5 часов»: городской симулятор, распределяющий бюджет по 5 направлениям и 5 районам
Суть
Городской симулятор-планировщик для Астаны: AI-диалог переводит приоритеты в ограничения, движок перебирает все допустимые планы из 5 мер и показывает последствия на карте OSM, включая эксперименты с задержками.
Как устроено
OpenAI (gpt-4.1) превращает сообщение пользователя в структурированное намерение: закрепления, исключения, цель. Отдельный вызов проверяет, что перевод полный. Детерминированный движок перебирает 694 395 допустимых планов и считает Score = 0.7×средний районный балл + 0.3×балл слабейшего района − число показателей ниже 40, с лагами и синергиями на 8 кварталов. Для каждого кандидата проверяется задержка каждой меры, считается вклад Шепли и лучшая замена одной меры. LLM только объясняет уже посчитанные факты, а план применяется отдельной кнопкой.
Ключевые решения
- exhaustive search
- multi-objective (max Score vs max-min район)
- Shapley values
- delay/resilience analysis
- structured intent parsing
- OpenStreetMap geography
Метрики
Лучший план: Score 57,24, бюджет 98/100, 0 дефицитов; max-min: Score 55,43, мин. район 55,26; контрольный пример 56,54307; перебрано 694 395 планов
Особенности
Точный вклад каждой меры по Шепли и явно показанная цена выбранного приоритета (общий Score против слабейшего района). Отдельный вызов LLM проверяет, полностью ли запрос переведён в ограничения. В README приложено видео-демо и контрольные числа организаторов.
Стек
TypeScript · Next.js · React · Vitest · Node.js · GitHub Actions
Модели
OpenAI gpt-4.1
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-46aa131a-chrollo.
README
README.mdQALA — Аким на 5 часов
Обсудите приоритеты. Увидьте последствия. Примите решение.
QALA помогает выбрать пять городских инициатив в пределах бюджета и проверить последствия до принятия плана. Городской управленец, аналитик или участник учебной симуляции обсуждает приоритеты с AI, сравнивает варианты на карте Астаны и проверяет, что произойдёт при задержке работ.
Astana Innovations · HackAlem AI · команда chrollo
Смотреть демо — 51 сек. · Запустить · Проверить за 5 минут · Что делает AI · Архитектура
Смотреть запись со всеми шагами и русскими подписями — 51 сек., MP4. Для просмотра ключ и установка не нужны. Показаны реальные ответы OpenAI gpt-4.1: закрепление школы и поликлиники → исключение ЛРТ и смена цели → задержка → применение и отчёт. Ожидание ответов сокращено монтажом; GIF выше показывает фрагменты записи.
В демонстрации поиск ограничен условиями пользователя, поэтому результаты отличаются от глобального максимума ниже. Предложения AI меняют принятый план только после нажатия «Применить план».
[!TIP] Для первой проверки OpenAI-ключ не нужен. Запустите приложение, откройте «Условия поиска» под картой и нажмите «Подобрать планы». Получите воспроизводимый результат: 57,24 Score · бюджет 98/100 · 0 дефицитов. Свободный диалог подключается отдельно.
Задача и ценность
У города 100 единиц бюджета, 5 районов, 10 показателей и 14 мероприятий. Нужно выбрать ровно пять мер с учётом стоимости, задержек, несовместимостей и взаимного усиления. Максимальный общий балл и максимальная помощь слабейшему району могут приводить к разным решениям.
QALA переводит запрос в явные условия, перебирает допустимые планы, показывает последствия на карте и объясняет компромиссы. Полный поиск без дополнительных условий даёт:
| Цель | Общий Score | Балл слабейшего района | Показателей ниже 40 |
|---|---|---|---|
| Максимальный общий Score | 57,24 | 54,09 | 0 |
| Максимальный балл слабейшего района | 55,43 | 55,26 | 2 |
Во втором случае минимальный районный балл выше, но остаются дефициты школ и медицины в Нуре. Приложение показывает цену выбранного приоритета. Оба результата получены из 694 395 допустимых планов. Точные числа и воспроизводимый пример.
Это позволяет обсуждать конкретный выбор: кому достанутся улучшения, какие дефициты останутся и чем придётся пожертвовать. Например, в контрольном плане задержка поликлиники на три квартала снижает медицинский показатель Нуры до 38,5 и возвращает штраф за дефицит — даже при неизменном бюджете.
Что реализовано
- Город и чат рядом. Карта Астаны на реальных границах OpenStreetMap: масштабирование, выбор районов, переключение десяти показателей и изменения относительно базы сравнения. На телефоне — вкладки карты и диалога.
- Подбор через диалог. Закрепление решений, исключение мер, смена цели, сравнение и объяснение. Условия можно проверить и изменить вручную. Ответы поддерживают Markdown, списки и таблицы.
- Полный поиск. Перебор допустимых наборов и назначений районов; победители по нескольким целям. Неупомянутые условия сохраняются.
- Предпросмотр и отдельное применение. Найденный вариант появляется на карте. Переключение вариантов и эксперименты не заменяют принятый план; итог применяется кнопкой.
- Проверка задержек. Для каждого кандидата автоматически проверяется задержка каждой из пяти мер на два квартала. В отдельном эксперименте можно выбрать меру и задержку от 1 до 8 кварталов; карта показывает последствия.
- Конструктор и отчёт. Контроль бюджета и конфликтов, сравнение сценариев, точный вклад Шепли, лучшая замена одной меры, AI-анализ с раскрываемыми фактами, JSON-экспорт и ссылка на сценарий.
Статичные скриншоты: подбор, обзор города и эксперимент
Подбор: город и диалог рядом; найденный план ещё не применён.

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

Эксперимент: задержка дворовых спорт-хабов в найденном плане на два квартала снижает Score с 57,24 до 56,14. Принятый план остаётся прежним.

Как работает решение
- Задать приоритет: например, «Сохрани школу и поликлинику, улучши остальное». Можно задать условия вручную или собрать план в конструкторе.
- Проверить условия: OpenAI преобразует сообщение в структурированное намерение. Сервер проверяет изменения и сохраняет остальные ограничения. Перед поиском или экспериментом отдельный вызов модели проверяет полноту перевода: неподдерживаемое требование должно привести к уточнению, без изменения плана.
- Исследовать варианты: код рассчитывает планы; карта показывает предпросмотр, бюджет, дефициты и районные изменения. Можно сравнить другую цель и проверить задержку, продолжая диалог.
- Применить предложение: найденный вариант заменяет текущий сценарий после нажатия «Применить план». В ручном конструкторе пользователь редактирует сценарий напрямую. Раздел «Результат» содержит подробный разбор и экспорт.
Формула из датасета:
Score = 0.7 × средний районный балл с учётом населения
+ 0.3 × балл слабейшего района
− количество показателей строго ниже 40
Горизонт — восемь кварталов; прямые эффекты учитывают лаг, бонусы сочетаний фиксированы. LLM не вычисляет официальный Score. Числовые ответы о найденных планах и задержках формируются программно. Правила и контрольные расчёты.
| Кто отвечает | За что |
|---|---|
| AI | Понимание запроса, проверка его перевода и объяснение рассчитанных фактов |
| Расчётный движок | Допустимость плана, полный поиск, Score, районные эффекты, задержки и вклад Шепли |
| Пользователь | Проверка видимых условий и применение выбранного плана отдельной кнопкой |
Быстрый запуск
Нужны Git, Node.js 22.12+ и npm; рекомендуется Node.js 24. База данных, аккаунт в приложении и отдельный backend не требуются.
git clone https://github.com/BAITC-Hacks/hack-46aa131a-chrollo.git
cd hack-46aa131a-chrollo
npm ci
npm run dev
Откройте http://127.0.0.1:3000. Начальный экран — «Город и AI».
Подключение OpenAI — необязательно
Создайте .env.local из примера:
# Windows PowerShell
Copy-Item .env.example .env.local
# macOS / Linux
cp .env.example .env.local
Укажите в .env.local и перезапустите сервер:
OPENAI_API_KEY=your_api_key_here
OPENAI_MODEL=gpt-4.1
«OpenAI подключён» в шапке означает наличие ключа; его работоспособность проверяется первым сообщением. Ключ используется сервером, файл исключён из Git. Запросы оплачиваются в аккаунте владельца ключа.
Production и опубликованная версия
npm run build
npm run start
Приложение открывается на 127.0.0.1:3000; dev-сервер на этом порту нужно предварительно остановить. Публичная демоверсия не опубликована. Решение запускается локально из этого репозитория.
Как проверить решение
Основной маршрут занимает около пяти минут после установки зависимостей. Он работает без ключа, регистрации и базы данных.
Основной путь без API-ключа
- «Город и AI» → «Новый диалог» → «Условия поиска» под картой → «Подобрать планы». Сброс диалога убирает прежние условия и сохраняет принятый план. Цель — «Общий Score», без закреплений и исключений.
- Проверено 694 395 допустимых планов. На карте появится предпросмотр: Score 57,24, бюджет 98/100, дефицитов 0. План ещё не применён.
- Переключите вариант «Самый слабый район» над картой: Score 55,43, дефицитов 2, минимальный районный балл 55,26.
- Верните первый вариант, нажмите «Применить план», затем «Результат». Изучите вклад решений и скачайте JSON с точными значениями.
Контрольный пример организаторов
«Обзор города» → «Посмотреть пример» → «Рассчитать сценарий».
| Проверка | Ожидаемый результат |
|---|---|
| Набор | M7, M8, M10 в Нуре; M12 по городу; M5 в Сарыарке |
| Бюджет / Score / дефициты | 95 / 56,54307 / 0 |
| Замена M5 в Сарыарке на M3 в Нуре | 100 / 57,20556 / 0; у Сарыарки меньше улучшений |
| В исходном примере: задержка поликлиники на 3 квартала | Score 55,30514; медицина Нуры 38,5; один дефицит |
Для последней проверки не применяйте замену: в отчёте исходного примера откройте «Если сроки сдвинутся», выберите три квартала и семейную поликлинику. Эксперимент не меняет официальный результат.
С OpenAI
Загрузите контрольный пример, откройте «Город и AI» и нажмите «Новый диалог». Напишите «Сохрани школу и поликлинику, улучши остальное», затем «Теперь помоги самому слабому району». Проверьте сохранение обоих закреплений в «Условиях поиска». Сравните варианты кнопкой в чате. Строка «Обсуждаем» показывает, к какому предпросмотру или эксперименту относятся вопросы. Применение остаётся за пользователем.
Числа проверяются без API и платных вызовов:
npm run demo:verify # контрольный пример, полный поиск и задержка
npm run check # TypeScript, все тесты, production-сборка
npm run format:check
Что проверено
| Проверка на 23 сентября 2026 | Результат и подтверждение |
|---|---|
| Расчёты, ограничения, API и геоданные | 66 тестов прошли; npm test |
| Типы, production-сборка и форматирование | npm run check и npm run format:check прошли локально |
| Живой AI-диалог | 30 из 30 запросов прошли проверку ожидаемого действия с gpt-4.1; сохранённые результаты |
| Интерфейс | Проверены 1440 × 1100 и 390 × 844, предпросмотр, задержки, сохранение плана и отказ фоновой карты; протокол |
30 запросов — небольшой регрессионный набор, а не гарантия точности на произвольной формулировке. Полный маршрут демонстрации · Сверка исходных PDF.
[!NOTE] GitHub Actions настроен, но на момент проверки задания не стартуют из-за биллинга аккаунта владельца. Приведённые результаты получены локально; подробности и диагностическое сообщение — в статусе CI.
Технологии
| Слой | Используется |
|---|---|
| Приложение и API | Next.js 16, React 19, TypeScript, Node.js |
| AI | OpenAI JavaScript SDK, Responses API, Structured Outputs; gpt-4.1 по умолчанию |
| Проверка структур | Zod |
| Интерфейс | CSS, SVG, Phosphor, Leaflet / OpenStreetMap; локальные шрифты Manrope и IBM Plex Mono |
| Markdown | react-markdown, remark-gfm; сырой HTML отключён |
| Проверки | Vitest, TypeScript, Prettier; браузерные проверки через agent-browser и axe-core |
| Хранение | localStorage для сценария и одного набора сравнения; без базы данных |
Архитектура
Основной путь подбора плана:
flowchart LR
UI["Карта и чат"] --> API["Next.js /api/planner"]
API -->|"Свободный запрос"| AI["OpenAI: намерение и проверка полноты"]
AI --> P["Валидация условий"]
API -->|"Ручные условия, без AI"| P
P --> E["Полный поиск и расчёт"]
E --> V["Предпросмотр и эксперимент"]
V -->|"Кнопка Применить"| R["Принятый план и отчёт"]
R --> A["/api/analyze: факты и AI-разбор"]
| Компонент | Ответственность |
|---|---|
data.ts, engine.ts | Датасет, правила, Score, Шепли и проверенная замена |
planner.ts, planning-intent.ts | Полный перебор и сохранение ограничений |
resilience.ts | Задержка одной меры и пересчёт последствий |
geographic-map.tsx, astana-districts.json | Интерактивная карта и сохранённые границы районов |
planner-chat.tsx, city-map.tsx | Диалог, предпросмотр, карта и отдельное применение |
/api/planner, /api/analyze | Серверная валидация, повторный расчёт, обращения к OpenAI |
Клиент и сервер используют общий расчётный модуль. Сервер заново считает результат и не доверяет присланным баллам. Свободное объяснение LLM может ошибаться; вычисленные факты доступны для проверки. Архитектура и границы AI.
Данные и интеграции
Источник — синтетический датасет организаторов Astana Innovations: районы, доли населения, веса, меры, стоимость, лаги, конфликты и синергии. Исходные материалы включают скачанные PDF. Сверка с оригиналами подтверждает перенос данных и правил в код.
QALA следует подробным правилам датасета: ровно пять разных мер, максимум две из одного направления; охват всех пяти направлений не обязателен. Неоднозначность общего описания задания разобрана в методике.
OpenAI получает последние восемь сообщений, условия и обсуждаемые сценарии; ключ остаётся на сервере. Карта использует Leaflet, сохранённые границы OpenStreetMap и уличную подложку OSM, для которой нужен интернет. Для соответствия пяти районам датасета Сарайшык объединён с Алматы: это учебное представление, а не актуальное административное деление. Без подложки границы и расчёты остаются доступны. Источники и лицензия геоданных. Подключений к городским системам и персональным данным нет.
Ограничения текущей версии
- Учебные данные и фиксированные правила. Результаты относятся к датасету организаторов, бюджету 100 и заданному каталогу мер. Они не являются прогнозом для реальной Астаны. Эксперимент задержки меняет прямой эффект одной меры, сохраняя синергии и бюджет; вероятности и перерасход не моделируются.
- Индивидуальный режим. План хранится в браузере, диалог и предпросмотр — до перезагрузки. Команды, роли (RBAC) и совместное редактирование не реализованы. Ссылка на сценарий требует доступа к тому же экземпляру приложения.
- Границы AI. Модель может ошибиться в интерпретации; условия видны пользователю и требуют проверки. Произвольные требования вне поддерживаемых целей и ограничений не оптимизируются.
- Локальный запуск. Для публичного многопользовательского сервиса нужны аутентификация, серверное хранилище и общий контроль расходов API. Текущие лимиты запросов и кэш действуют в пределах процесса.
Авторы коммитов
История коммитов
- 2026-09-23 17:45docs: add recorded AI walkthrough and animated README previewDias Meiram
- 2026-09-23 17:16docs: tighten jury guide and clarify model boundariesDias Meiram
- 2026-09-23 17:05docs: present QALA value and reproducible jury walkthroughDias Meiram
- 2026-09-23 17:01feat: replace schematic map with interactive Astana geographyDias Meiram
- 2026-09-23 16:42fix: verify AI planning requests against supported capabilitiesDias Meiram
- 2026-09-23 15:56feat: connect city previews with AI planning and document jury workflowDias Meiram
- 2026-09-23 15:21feat: add conversational planning and delay experimentsDias Meiram
- 2026-09-23 14:39feat: polish simulator UX and document verified modelDias Meiram
Все коммиты (9)
- 2026-09-23 14:24feat: implement QALA city simulator with verified scoring and AI analysisDias Meiram
Структура репозитория (73 файлов)
.env.example .github/workflows/ci.yml .gitignore .prettierignore .prettierrc.json AGENTS.md CLAUDE.md README.md docs/ARCHITECTURE.md docs/DEMO.md docs/DESIGN.md docs/MAP-DATA.md docs/MODEL.md docs/SOURCE-AUDIT.md docs/TESTING.md docs/media/qala-demo.mp4 docs/media/qala-preview.gif docs/planner-evaluation.json docs/screenshots/delay.png docs/screenshots/overview.png docs/screenshots/planner.png docs/screenshots/results.png next-env.d.ts next.config.ts package-lock.json package.json scripts/eval-planner.mjs scripts/prepare-map.py src/app/api/analyze/route.test.ts src/app/api/analyze/route.ts src/app/api/planner/route.test.ts src/app/api/planner/route.ts src/app/api/status/route.ts src/app/globals.css src/app/icon.svg src/app/layout.tsx src/app/map.css src/app/page.tsx src/app/studio.css src/components/builder.tsx src/components/city-map.tsx src/components/geographic-map.tsx src/components/markdown-message.test.ts src/components/markdown-message.tsx src/components/overview.tsx src/components/planner-chat.tsx src/components/resilience-panel.tsx src/components/results.tsx src/components/shared.tsx src/components/simulator.tsx src/data/astana-districts.json src/lib/data.ts src/lib/demo.test.ts src/lib/engine.test.ts src/lib/engine.ts src/lib/geography.test.ts src/lib/planner-contract.ts src/lib/planner.test.ts src/lib/planner.ts src/lib/planning-capabilities.ts src/lib/planning-intent.test.ts src/lib/planning-intent.ts src/lib/report.test.ts src/lib/report.ts src/lib/request-json.ts src/lib/resilience.test.ts src/lib/resilience.ts tracks/astana innovations/HackAlem AI_ «Аким на 5 часов» - AI-симулятор управления городом.pdf tracks/astana innovations/dataset.txt tracks/astana innovations/tz.md.txt tracks/astana innovations/Датасет районов.pdf tsconfig.json vitest.config.ts
Ветки (2)
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.
