О проекте
Команда: HealMind
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Рабочий MVP
Задача кейса: «Аким на 5 часов»: городской симулятор, распределяющий бюджет по 5 направлениям и 5 районам
Суть
Streamlit-симулятор городского бюджета: пользователь выбирает 5 мер из каталога из 14 (с привязкой к районам), видит Score города, таблицу «до/после» (5 районов × 10 показателей) и число критических значений, а OpenAI объясняет, что улучшилось и на какой компромисс пошёл пользователь.
Как устроено
Данные районов, веса, каталог мер и правила берутся из backend/data.json (перенесены из «Датасет районов.pdf»). calculator.py на Decimal проверяет правила (ровно 5 разных мер, не больше 2 из одного направления, бюджет 100, запрещённые сочетания) и считает эффекты: полный эффект умножается на (8 − лаг)/8, добавляются синергии, значения ограничиваются 0–100. Итог: Score = 0.7·D_avg + 0.3·min D − N_crit. ai_analyst.py передаёт в gpt-4.1-mini готовый расчёт для текстового разбора; числа модель не считает, а неизменённый набор не отправляется повторно.
Ключевые решения
- детерминированная формула Score с Decimal
- эффекты с лагом и синергиями
- проверка ограничений и несовместимостей
- AI-разбор готового расчёта
- кеширование ответа в session_state
Метрики
Контрольный пример: бюджет 95/100, Score 52.56 → 56.54 (+3.99), критических 2 → 0; 19 автотестов
Особенности
Для жюри описан воспроизводимый контрольный сценарий с точными ожидаемыми значениями (включая проверку несовместимости M4+M7). Расчёт полностью отделён от LLM (Decimal, AI не источник чисел), в тестах запросы к OpenAI подменяются, поэтому квота не расходуется.
Стек
Python · Streamlit · OpenAI Python SDK · python-dotenv · unittest
Модели
gpt-4.1-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-6fe8700a-healmind.
README
README.mdАким: пять решений для города
Учебный симулятор распределения городского бюджета с AI-разбором решений. Пользователь выбирает пять мероприятий и видит, как они изменяют показатели районов, общий балл города и положение самого слабого района.
1. Проблема и пользователь
Проект предназначен для учащихся, осваивающих основы городского управления. Он помогает разобраться, почему полезные по отдельности инициативы не всегда дают лучший общий результат: бюджет ограничен, эффекты появляются с задержкой, а слабые районы требуют внимания.
Симулятор позволяет проверить свой выбор на условных данных пяти районов Астаны. Это учебная модель, а не прогноз реальных последствий для города.
2. Что реализовано
- Один экран с выбором пяти разных мероприятий из каталога из 14 мер.
- Выбор района для локальных мер; городские меры применяются ко всем пяти районам.
- Отображение бюджета: всего 100 условных единиц, потраченная сумма и остаток.
- Проверка количества решений, повторов, бюджета, ограничений направлений и несовместимостей. При недопустимом наборе итоговый балл не рассчитывается, интерфейс показывает причину.
- Расчёт эффектов с учётом задержек, фиксированных синергий, весов показателей и долей населения.
- Итоговый Score, изменение относительно базы и таблица «до/после» из 50 строк: 5 районов × 10 показателей.
- Подсчёт критических значений: строго меньше 40.
- AI-разбор через OpenAI: что улучшилось, какие проблемы остались и какой компромисс сделал пользователь.
- Восстановление контрольного примера одной кнопкой.
- Сохранение текущего результата и AI-ответа в сеансе. Повторная оценка неизменённого набора не отправляет новый запрос к модели.
- Работа расчёта при отсутствии ключа или ошибке AI API; повторный запрос разбора по кнопке.
3. Как работает решение
- Приложение загружает районы, показатели и каталог из
backend/data.json. - Пользователь выбирает пять мероприятий и районы для локальных мер. Стоимость и остаток бюджета обновляются на экране.
- По кнопке «Оценить решения» Python проверяет правила и рассчитывает результат.
- На экране появляются Score, таблица изменений и количество критических показателей.
- OpenAI получает выбранные меры и готовый расчёт, затем возвращает текстовое объяснение.
- Пользователь меняет выбор и повторяет оценку. При изменении набора старые результаты скрываются.
Правила расчёта
Горизонт симуляции — 8 кварталов. Полный эффект каждой меры умножается на (8 − лаг) / 8. Синергии прибавляются отдельно и не уменьшаются из-за лага. После суммирования значения показателей ограничиваются диапазоном 0–100.
Балл района D = сумма(вес показателя × итоговое значение показателя)
Средний балл города D_avg = сумма(доля населения района × D)
Score = 0.7 × D_avg + 0.3 × минимальный D − N_crit
N_crit — число пар «район × показатель» со значением строго ниже 40. За каждую такую пару снимается один балл. Остаток бюджета не даёт бонуса.
Выбираются ровно пять разных мер, максимум две из одного направления. Дополнительно запрещены сочетания:
| Меры | Ограничение |
|---|---|
| M1 и M3 | Нельзя выбирать вместе, независимо от районов |
| M4 и M7 | Нельзя назначать в один район |
| M5 и M13 | Нельзя назначать в один район |
Математику выполняет программа с помощью Decimal. Для интерфейса Score округляется до сотых; калькулятор также возвращает точные десятичные значения. AI не является источником числового результата.
4. Технологии
| Компонент | Технология |
|---|---|
| Язык | Python 3.10+ |
| Интерфейс | Streamlit 1.63.0 |
| Расчёт и данные | Стандартные библиотеки Python: decimal, json, collections, pathlib; локальный JSON |
| AI-интеграция | OpenAI Python SDK 3.11.0, Responses API |
| Модель по умолчанию | gpt-4.1-mini; изменяется через OPENAI_MODEL |
| Локальные настройки | python-dotenv 1.2.3 и переменные окружения |
| Проверки | unittest, unittest.mock, streamlit.testing.v1.AppTest |
Версии внешних библиотек закреплены в requirements.txt.
5. Архитектура проекта
Выбор пользователя в Streamlit
│
▼
backend/calculator.py ◄── backend/data.json
│
├──► Score, бюджет, таблица и критические значения
│
▼
backend/ai_analyst.py ──► OpenAI Responses API
│
▼
Текст разбора в том же интерфейсе Streamlit
Основные файлы рабочей версии:
frontend/
app.py # Интерфейс и состояние текущего сеанса
backend/
data.json # Датасет, каталог, правила и контрольный пример
calculator.py # Валидация и calculate_plan()
ai_analyst.py # Формирование запроса и вызов OpenAI
tests/ # Автотесты расчёта, AI-интеграции и интерфейса
requirements.txt # Зависимости
.env.example # Шаблон настроек без ключа
.gitignore # Исключения для секретов и локальных файлов
README.md # Инструкция для запуска и проверки
Frontend вызывает функции backend напрямую в одном Python-приложении. Отдельный HTTP-сервер backend и база данных для запуска не нужны. Выбор и ответы хранятся в st.session_state.
6. Установка и запуск
Подготовка
Нужны Python 3.10 или новее, pip и доступ к интернету для установки зависимостей. Для настоящего AI-разбора дополнительно нужны API-ключ OpenAI, доступ к выбранной модели и доступная квота API.
Откройте терминал в корне полученной копии проекта — в папке с requirements.txt, backend/ и frontend/.
Windows / PowerShell
Создайте виртуальное окружение и установите зависимости:
python -m venv .venv
.\.venv\Scripts\python -m pip install -r requirements.txt
macOS / Linux
python3 -m venv .venv
./.venv/bin/python -m pip install -r requirements.txt
Настройка AI
Создайте в корне проекта файл .env по образцу .env.example. Если .env уже существует, добавьте или обновите только эти настройки:
OPENAI_API_KEY=вставьте_свой_API_ключ_только_в_локальном_файле
OPENAI_MODEL=gpt-4.1-mini
OPENAI_API_KEY обязателен только для AI-разбора. OPENAI_MODEL необязателен: без него используется модель по умолчанию. Можно указать другую модель, доступную вашему проекту и поддерживающую Responses API. Непустые переменные окружения имеют приоритет над .env.
Не публикуйте настоящий ключ. .env, локальные варианты .env.* и .streamlit/secrets.toml исключены из Git; .env.example содержит только шаблон. При демонстрации не открывайте файл с ключом на общем экране.
Для проверки только расчёта можно оставить ключ незаданным: Score и таблица продолжат работать, а приложение сообщит, что AI-разбор недоступен.
Запуск
Windows:
.\.venv\Scripts\python -m streamlit run frontend/app.py
macOS / Linux:
./.venv/bin/python -m streamlit run frontend/app.py
Откройте локальный адрес, который Streamlit напечатает в терминале. Для остановки приложения нажмите Ctrl+C в этом терминале.
7. Как проверить решение: сценарий для жюри
Контрольный пример
- Запустите приложение и нажмите «Восстановить демо-пример».
- Проверьте выбранные меры:
| Мера | Название | Территория | Стоимость |
|---|---|---|---|
| M7 | Школа + детсад | Нура | 24 |
| M8 | Центр семейного здоровья / поликлиника | Нура | 20 |
| M10 | Освещение и камеры | Нура | 12 |
| M12 | Единая цифровая платформа обращений | Весь город | 14 |
| M5 | Перевод частного сектора на чистое топливо | Сарыарка | 25 |
- Нажмите «Оценить решения».
- Сверьте результат:
| Показатель | Ожидаемое значение |
|---|---|
| Потраченный бюджет | 95 из 100 |
| Остаток | 5 |
| Базовый Score | 52.55768 → на экране 52.56 |
| Итоговый Score | 56.54307 → на экране 56.54 |
| Изменение Score на экране | +3.99 |
| Критические показатели | 2 до → 0 после |
| Строки таблицы «до/после» | 50 |
Синергия M10 + M12 добавляет к безопасности улиц Нуры фиксированные 2 пункта. С ключом и доступным API ниже таблицы появляется AI-разбор. Его формулировки могут отличаться между запросами; сравнивать нужно соответствие объяснения рассчитанным данным.
Изменение решения и проверка ограничений
- Замените M7 на M9 в Нуре, остальные меры оставьте прежними. После новой оценки бюджет должен составить 81, остаток — 19, Score — 56.43 (точное значение 56.425135).
- Восстановите пример, замените M5 на M4 и назначьте M4 в Нуру. Нажмите оценку: приложение должно сообщить о несовместимости M4 и M7 и не показать итоговый Score.
- Повторно выберите уже выбранную меру: интерфейс предупредит о повторе и отключит кнопку оценки.
- При недоступном AI API расчёт остаётся виден. Интерфейс показывает сообщение об ошибке и кнопку «Повторить AI-разбор».
Автоматические проверки
Windows:
.\.venv\Scripts\python -m unittest discover -s tests -v
macOS / Linux:
./.venv/bin/python -m unittest discover -s tests -v
В проекте 19 тестов. Они проверяют контрольные значения, бюджет, повторы, несовместимости, лаги, все синергии, городской эффект, порог критичности, ограничение показателей, независимость от порядка решений, вызов калькулятора из интерфейса, сохранение AI-ответа и обработку ошибок API.
Автотесты подменяют запросы к OpenAI и не расходуют квоту. Настоящий AI проверяется отдельно через пользовательский сценарий выше.
8. Данные и интеграции
Источник учебных данных указан в backend/data.json: «Датасет районов.pdf», разделы 1–4. В JSON перенесены показатели Есиля, Алматы, Сарыарки, Байконура и Нуры, доли населения, веса, каталог мероприятий и правила. PDF для запуска не нужен: приложение читает JSON и не распознаёт документы во время работы.
По каждому району учитываются десять показателей: два транспортных, два экологических, два социальных, два показателя безопасности и два показателя городских сервисов. Все имеют шкалу 0–100, где больше — лучше.
Единственная внешняя интеграция приложения — OpenAI Responses API по адресу https://api.openai.com/v1. В запрос включаются выбранные меры, их территории, цены и задержки, описание модели и готовый расчёт с таблицей, эффектами и синергиями. Произвольные файлы проекта в запрос не включаются.
Клиент настроен на тайм-аут 30 секунд, без автоматических повторов, с store=False и лимитом ответа 900 токенов. Инструкция модели просит краткий русский разбор на основе переданных данных. API-запрос использует квоту проекта владельца ключа.
9. Ограничения текущей версии
- Датасет условный и фиксированный: пять районов, 14 мер, горизонт восемь кварталов. Загрузки своих данных и настройки горизонта в интерфейсе нет.
- Нет авторизации, базы данных, истории сценариев, экспорта результатов и совместной работы. Состояние хранится только в текущем сеансе.
- Нет карты города, свободного чата, автоматического подбора оптимального набора или сравнения нескольких сценариев на одном экране.
- AI требует интернета, действующего ключа и доступной квоты. Ошибка AI не отменяет математический расчёт.
- Инструкция ограничивает AI переданными фактами, но автоматической проверки всех утверждений модели нет. Объяснение следует сверять с таблицей.
- Эффекты отдельных мер не являются независимыми вкладами в Score: итог зависит также от синергий, самого слабого района и штрафов.
10. Публичная версия и репозиторий
Ссылка на deployed-версию в текущем репозитории не указана. Подтверждённый способ запуска этой версии — локальное Streamlit-приложение по инструкции выше.
Репозиторий: BAITC-Hacks/hack-6fe8700a-healmind.
Авторы коммитов
История коммитов
- 2026-09-23 17:34feat: prepare complete hackathon submission with AI and documentationako-turman
- 2026-09-23 17:07feat: add AI analysis to simulator resultsИнжу
- 2026-09-23 16:43fix: integrate official dataset calculation with Streamlitako-turman
- 2026-09-23 16:22Merge pull request #3 from BAITC-Hacks/frontend-finalparuazinzhu04-sys
- 2026-09-23 16:22Merge pull request #2 from BAITC-Hacks/codex/backend-calculatorparuazinzhu04-sys
- 2026-09-23 15:59feat: add backend dataset and calculatorako-turman
- 2026-09-23 15:40feat: add AI analystИнжу
- 2026-09-23 15:39feat: add backend files to mainako-turman
Все коммиты (13)
- 2026-09-23 14:26Fix structure and remove submoduleako-turman
- 2026-09-23 14:23Initial project structureako-turman
- 2026-09-23 16:15Add frontend interfacemarket
- 2026-09-23 16:04Add frontend interfacemarket
- 2026-09-23 15:46описание изменений, сделанных кодексомmarket
Структура репозитория (11 файлов)
.env.example .gitignore README.md backend/ai_analyst.py backend/calculator.py backend/data.json frontend/app.py requirements.txt tests/test_ai_analyst.py tests/test_calculator.py tests/test_frontend.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.