О проекте
Команда: Terricon
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Доведённый продукт
Задача кейса: «Аким на 5 часов»: городской симулятор, распределяющий бюджет по 5 направлениям и 5 районам
Суть
Симулятор городского бюджета: пользователь выбирает 5 из 14 мер по 5 районам, видит Astana Quality of Life Score и изменения по районам. ИИ-агент выполняет поручения вроде «улучши, но не ухудшай воздух в Сарыарке» и называет цену такого условия.
Как устроено
Движок считает Score по формуле организаторов: эффект×(8−лаг)/8, синергии, 70% среднего по городу + 30% слабейшего района − 1 за каждый показатель ниже 40. Проверяются 7 правил, полным перебором всех 694 395 допустимых наборов ищется лучший вариант и лучший под ограничения. Агентная система из 4 ролей (координатор, Проверяющий и др.) с 12 инструментами работает циклом «поиск → проверка → повторный поиск». LLM только объясняет, каждое число в тексте сверяется с расчётом. Риск-менеджер пересчитывает сценарии при городских событиях (зимний смог) и ищет самый устойчивый набор. Утверждает только человек.
Ключевые решения
- полный перебор
- оптимизация с ограничениями
- мультиагентная система с ролями
- tool calling
- стресс-тест событий
- сверка чисел в ответе LLM
- голосовой ввод
Метрики
Score 52,56 → 56,54 (пример организаторов); лучший из 694 395 — 57,24; с условием по воздуху — 56,78 (цена 0,46); check_scenario 11/11
Особенности
Агент называет «цену условия» в баллах индекса (например, сохранение воздуха в Сарыарке стоит 0,46) и «цену устойчивости» при событиях. Проверка всего сценария одной командой без браузера и ключа. Работа в команде распределялась через TASKS.md и AGENTS.md с Codex.
Стек
Python · Streamlit · pytest · Docker · GeoJSON
Модели
OpenAI
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-5c60a040-terricon.
README
README.mdАким на 5 часов — симулятор городского бюджета и принятия решений
Русский · English
Команда Terricon · HackAlem AI, 23.09.2026 · трек «03 · Управление» · задача Astana Innovations
Бывало ли у вас такое: каждое предложение кажется нужным, но денег на всё не хватает — и выбирать приходится вам?
Представьте рабочее совещание в акимате. Родители просят школу ближе к дому. Жители другого района жалуются на воздух. Транспортникам нужны деньги на новую линию, коммунальным службам — на изношенные сети. У каждого есть причины считать свою задачу первой. Бюджет один. Решение нужно принять сегодня, а последствия жители будут ощущать ещё несколько лет.
Для руководителя и аналитика здесь начинается самая трудная часть: сопоставить разные потребности и объяснить выбор. Кому станет лучше? Какой район снова подождёт? Когда появится эффект? Что произойдёт, если зимой придёт смог? И можно ли получить почти такой же общий результат, сохранив важное для жителей условие? Таблица расходов показывает, куда ушли деньги. Для такого разговора нужно ещё увидеть, что изменится в жизни районов.
«Аким на 5 часов» — место, где такой выбор можно проверить до утверждения. В учебном городе пять районов, 100 условных единиц бюджета и 14 доступных мер. Вам нужно выбрать ровно пять решений. Можно начать со знакомой логики: помочь самому отстающему району, улучшить транспорт, сохранить качество воздуха. Программа проверит, хватает ли бюджета, покажет изменения по районам и рассчитает общий индекс качества жизни — Astana Quality of Life Score. Рядом будут видны сильные стороны набора, оставшиеся риски и возможная замена.
Например, набор организаторов поднимает индекс с 52,56 до 56,54. Замена одной меры позволяет получить 57,21. Но затем звучит важное уточнение: «Улучши, только не ухудшай воздух в Сарыарке». Система ищет вариант с этим условием и предлагает 56,78. Лучший набор без ограничения дал бы 57,24: сохранение качества воздуха стоит 0,46 балла общего индекса. Теперь можно обсуждать конкретный компромисс: готовы ли мы отказаться от части общего прироста, чтобы сохранить этот показатель в районе?
Такой сценарий полезен руководителю, которому нужно обосновать решение, аналитику, который сравнивает варианты, и участникам обучения, которым важно увидеть последствия собственного выбора. ИИ помогает задать условия обычными словами и объясняет результаты. Формулы, проверку бюджета и поиск выполняет программный движок; применяет предложение и утверждает сценарий человек.
Попробуйте сами: какие пять решений вы выберете — и как объясните их жителям района, которому досталось меньше?
Данные и эффекты мер в прототипе условные, из задания организаторов. Все приведённые числа — результаты этой учебной модели. Для использования в реальном городе понадобятся проверенные местные данные и оценка эффектов мер.
Быстрый запуск и проверка
git clone https://github.com/BAITC-Hacks/hack-5c60a040-terricon.git
cd hack-5c60a040-terricon
pip install -r requirements.txt
python scripts/check_scenario.py
python -m pytest -q
python web/server.py
Ключ OpenAI для проверки не нужен. Что должно получиться:
check_scenario.py— главный сценарий и все пять критериев ТЗ одной командой, без браузера: 11 строк «✓» и «Итог: 11/11 проверок» за 2–10 секунд (замер 23.09: 2 с на ноутбуке команды и в Docker, 8 с на второй машине);pytest— все проверки зелёные, пропущенных нет: формула, 7 правил, эталонные числа организаторов, агент, экран;- экран открывается на http://localhost:8501;
- без решений Score города 52,56; пример организаторов (M7, M8, M10 в Нуре, M12, M5 в Сарыарке) — 56,54;
- набор дороже 100 не принимается — система называет причину: «Бюджет превышен: 101 из 100»;
- лучший из всех 694 395 допустимых наборов — 57,24.
Показ за 3 минуты — порядок кликов
Экран открывается с примером организаторов. Все числа ниже сверяют тесты (tests/test_web.py, tests/test_events.py, tests/test_tools.py) и
scripts/check_scenario.py.
- Главный вывод вверху: индекс Астаны 52,56 → 56,54, потрачено 95 из 100; обе острые проблемы Нуры (школы 38, поликлиники 35) решены — это видно в блоке «Результат по модели».
- Правила: в четвёртом решении («Решение 4») выбрать «Модернизация тепло- и водосетей» (цена 28) — «Сценарий пока нельзя принять: Бюджет превышен: 109 из 100». Затем кнопка «Вернуть пример».
- Поручение агенту (блок «Совет ИИ-агента», текст уже вписан: «Улучши, но не ухудшай качество воздуха в Сарыарке») → «Выполнить поручение»: агент перебирает все 694 395 наборов, Проверяющий отклоняет лучший (57,24 — он ухудшает воздух в Сарыарке) и после повторного поиска рекомендует 56,78; цена условия — 0,46 балла.
- «Найти улучшение»: заменить чистое топливо в Сарыарке на линию ЛРТ в Нуре — 57,21 (+0,67) → «Применить улучшение».
- Проверка на прочность (блок «Проверка на прочность» → «Проверить сценарий»): при зимнем смоге 57,21 → 55,6 и совет, какую меру заменить. Ниже — «Найти самый устойчивый» (около 6 секунд): лучший по индексу набор (57,24) при росте числа школьников падает до 55,80, самый устойчивый (57,07) держит худший исход 55,82; цена устойчивости — 0,17 балла.
- Утвердить (блок «Утвердить и рейтинг»): только человек и только кнопкой — «Утверждено …: индекс 57,21».
Проблема и для кого
Денег в городском бюджете всегда меньше, чем нужд: транспорт, зелень, школы и поликлиники, безопасность, ЖКХ спорят за одни и те же деньги. Решение в одном районе меняет картину всего города, эффект приходит через месяцы, а отстающий район тянет вниз общую оценку. Такие решения часто принимают по таблицам и интуиции — последствия видны только через год. Кто пользуется: руководители и аналитики акимата, депутаты маслихата, программы обучения управленцев; команды на обучающей игре — бюджет и данные у всех одинаковые, поэтому видно, чьё решение лучше.
Ценность
- Можно быстро сравнить десятки вариантов: видно, какой район получит улучшения, какие острые проблемы уйдут и какие компромиссы останутся.
- ИИ-агент объясняет компромиссы простыми словами и сам ищет лучший вариант среди всех 694 395 — в том числе под условия («не ухудшай воздух в Сарыарке») — и честно называет цену условия в баллах.
- Формула учитывает отстающие районы: 30% индекса зависит от балла самого слабого района.
- Расчёт можно проверить по формуле и тестам; утверждает сценарий только человек.
Потенциал развития
- Заменить условные данные открытыми: data.egov.kz (школы, поликлиники, ДТП, камеры «Сергек»), stat.gov.kz (население районов), open.egov.kz (бюджет), Казгидромет и IQAir (воздух).
- Настоящая карта районов и цифровой двойник города; учёт климатических рисков и перемещений жителей.
- Режим для жителей в Smart Astana: каждый собирает свой сценарий, акимат видит, чего хотят люди в каждом районе.
- Учёт налогов и рабочих мест, которые дают меры.
- У каждой меры — источник, дата и версия оценки эффекта; паспорт сценария показывает, на каких данных он посчитан.
- Не одно число, а диапазон: как меняется индекс, если эффекты мер окажутся слабее или сильнее, и какие наборы устойчивы к городским событиям и смене приоритетов.
- Сверка с фактом: после утверждения — «план / факт» по показателям районов и уточнение эффектов мер по открытым данным.
- Подробнее — исследование команды: аналоги, приоритеты и проверка следующей версии.
Аналоги и чем мы отличаемся
Похожие инструменты есть в трёх направлениях:
- симуляторы городского бюджета для жителей — Balancing Act (США), Citizen Budget (Канада), Delib Budget Simulator (Великобритания): бюджет раздают по статьям и сразу видят остаток;
- партисипаторное бюджетирование — OmaStadi (Хельсинки), Decidim (Барселона), CONSUL (Мадрид): жители предлагают проекты и голосуют за них по районам;
- городские панели и цифровые двойники — Dublin Dashboard, Virtual Singapore, MIT CityScope: состояние города слоями данных и шкалами. В Казахстане — открытые бюджеты budget.egov.kz и openbudget.kz.
Чем отличаемся: один управленец решает за весь город, а программа считает последствия по каждому району; ИИ-агент объясняет риски простыми словами, выполняет поручения («улучши, но не ухудшай воздух в Сарыарке») и называет цену условий; утверждает только человек. На этом сочетании построен наш прототип. В обзоре аналогов нам был полезен приём наглядности: цвет района и сравнение «было → стало».
Что реализовано
| Возможность | Что делает |
|---|---|
| Проверка правил | ровно 5 решений, бюджет ≤ 100, без повторов, район у районных мер, не больше 2 мер на направление, несовместимые пары — на каждое нарушение понятная причина |
| Расчёт Score | формула организаторов: эффект × (8 − лаг) / 8, синергии, ограничение 0–100, балл района, средний по населению, 70% город + 30% самый слабый район − 1 за каждый показатель ниже 40 |
| Вклад каждой меры | насколько Score упадёт, если убрать меру |
| Разбор компромиссов | сильные стороны, риски, последствия; без ключа — по шаблону из чисел расчёта, с ключом — текст модели, в котором каждое число сверено с расчётом |
| «Улучшить сценарий» | лучшая замена одной меры и прирост Score |
| Подбор под цель | поиск по всем 694 395 допустимым наборам с условиями: бюджет не больше, обязательно / исключить меры, ни один район не ниже заданного балла |
| Место сценария | «Ваш сценарий — 566-й из 694 395 допустимых; лучший даёт 57,24» — под индексом, в ответе агента и в рейтинге команд |
| Паспорт района | клик по району на карте или выбор в списке: балл, место с конца, слабые показатели и решения, которые поднимут район сильнее всего; на карте — показатели района до и после и решения набора, которые на него влияют |
| Сравнение и «что если» | «Сохранить текущий как вариант A» — и сравнение с любым новым набором: индекс, баллы районов, чем наборы различаются; в чате — «что если убрать чистое топливо?» |
| Паспорт сценария | отчёт для акима в Markdown — скачать одной кнопкой |
| Поручение агенту | «Улучши, но не ухудшай воздух в Сарыарке»: агент разбирает условия, ищет по всем 694 395 наборам, Проверяющий сверяет результат с условиями и при нарушении запускает повторный поиск; на экране — журнал шагов, рекомендация, альтернатива и «цена условий» — сколько баллов стоит ограничение |
| Чат с агентом | вопросы словами («почему такой результат?», «что с Нурой?», «сколько осталось?»); под ответом — какие инструменты агент использовал |
| Городские события | зимний смог, авария на теплосети, рост числа школьников, весенний паводок: Score до и после события, новые проблемные показатели и совет, какую меру заменить |
| Устойчивость к приоритетам | что будет, если вес одного направления вырастет на 20%: Score сценария и лучший набор при новых весах |
| Сколько индекса можно купить за бюджет | график «затраты → лучший индекс» по всем наборам, точка — ваш сценарий |
| Самый устойчивый набор | стресс-тест условных сценариев: для всех 694 395 наборов — худший индекс на четырёх городских событиях; ваш сценарий, лучший по индексу и самый устойчивый рядом, цена устойчивости в баллах и кнопка «Взять» |
| Карта районов | контуры районов по OpenStreetMap; цвет — изменение балла района; «до / после»; выбор района показывает его показатели и связанные решения |
| Рейтинг команд | команда отправляет свой сценарий под своим названием; рейтинг показывает место, индекс, прирост и место среди всех 694 395 вариантов |
| Голосовое поручение | кнопка «Сказать голосом»: запись в браузере, распознавание речи с подсказкой районов (с ключом OpenAI), вопрос уходит агенту |
| «Утвердить сценарий» | только человек и только допустимый набор; движок хранит историю утверждённых |
| Проверка одной командой | python scripts/check_scenario.py проходит главный сценарий и сверяет 11 эталонных чисел |
Как работает
- Экран показывает город сейчас: Score 52,56, у Нуры школы (38) и поликлиники (35) ниже 40 — штраф −2.
- Пользователь выбирает 5 мер и районы. Движок проверяет правила и сразу называет нарушения.
- Для допустимого набора движок считает Score, баллы районов до и после, вклад каждой меры, синергии, снятые и новые критические значения.
- Агент объясняет результат и предлагает улучшение. Например, для примера организаторов: заменить «Чистое топливо» в Сарыарке на ЛРТ в Нуре — 57,21 (+0,67), это третий лучший из 694 395 наборов.
- Пользователь сам решает: «Применить» предложение, сравнить варианты, «Утвердить сценарий».
Архитектура
flowchart LR
U["Управленец"] -->|"5 решений, вопрос, поручение, голос"| S["Экран web/index.html · сервер web/server.py"]
S --> G{"Проверка на входе"}
G -->|"«поставь Score 100», политика — отказ"| S
G --> K["Координатор"]
K --> A["Аналитик: правила, расчёт, разбор, паспорт района"]
K --> ST["Стратег: улучшить, подбор по 694 395 наборам"]
ST --> P{"Проверяющий: условия соблюдены?"}
P -->|"нет — повторный поиск"| ST
P -->|"да"| R["Докладчик: рекомендация, цена условий, журнал шагов"]
K --> RM["Риск-менеджер: что если, события, приоритеты"]
D[("data/akim.json — данные организаторов")] --> A
A --> N{"Проверка чисел"}
R --> N
RM --> N
L["OpenAI — по желанию"] -.->|"текст"| N
N --> S
S -->|"Применить / Утвердить — только кнопкой"| U
web/index.html— экран на HTML и JavaScript без внешних библиотек: ничего не считает, показывает ответы движка. Сверху — главный вывод и индекс, слева пять решений, справа карта районов (контуры OpenStreetMap), ниже совет ИИ-агента, проверка на прочность, утверждение и рейтинг.web/server.py— сервер на стандартной библиотеке Python: каждая ручка/api/…вызывает функцию движка и переводит тексты в простые слова (контракт —web/API.md).akim/— движок:rules.py(правила),scoring.py(формула),optimizer.py(вклад мер, «Улучшить»),search.py(индекс всех 694 395 наборов: строится за ~2 с, запрос — доли миллисекунды),explainer.py(разбор и проверка чисел),agent.py(проверка на входе и координатор: с ключом модель выбирает инструменты, без ключа — правила),nlu.py(поручение текстом → условия),mission.py(поиск → Проверяющий → повторный поиск → цена условий),tools.py(паспорт района, сравнение, «что если»),events.py(городские события, устойчивость к приоритетам),brief.py(паспорт сценария),approvals.py(утверждённые сценарии),teams.py(рейтинг команд),voice.py(голос),llm.py(подключение модели).scripts/check_scenario.py— главный сценарий одной командой;web/MAP_SOURCES.md— источники карты и достопримечательностей.data/akim.json— районы, показатели, веса, 14 мер, синергии, несовместимости — перенесены из ТЗ один в один;data/top_plans.json— заранее посчитанные лучшие наборы (python scripts/precompute.py, ~30 с).
Где что находится
Для запуска нужен один список зависимостей — requirements.txt: python -m pip install -r requirements.txt.
| Файл или папка | Назначение |
|---|---|
web/ | Экран: index.html (карта районов, решения, агент), server.py (ручки /api/… к движку), API.md, источники карты |
requirements.txt, Dockerfile | Зависимости приложения и альтернативный запуск в контейнере |
.env.example | Образец необязательных настроек модели |
akim/, data/ | Расчёты, AI-агент и входные данные |
scripts/, tests/, pytest.ini | Проверки, подготовка данных и настройки тестов |
docs/task/ | Исходное задание и датасет организаторов |
docs/ | Исследование, инструкция проверки и сохранённые отчёты |
docs/environments/ | Снимки окружений для повторения проверок; обычному запуску не нужны |
README.md, README.en.md | Инструкции на русском и английском |
AGENTS.md, CASE.md, TASKS.md | Правила работы команды, описание кейса и задания; приложение их не использует |
.gitignore, .dockerignore | Исключение локальных файлов, окружений и секретов из Git и контейнера |
Локальные .venv/, .venv-judge/, .env, __pycache__/ и .pytest_cache/ в GitHub не публикуются.
Сохранённые отчёты отражают структуру и версии на момент проверки; старые пути в них — история этого запуска.
Что агент делает сам и что только после человека
- Сам: проверяет правила, считает Score, ищет лучшие наборы, объясняет компромиссы, предлагает замену. Всё это обратимо — черновик сценария.
- Только человек: применить предложенную замену и утвердить сценарий — кнопками на экране. У агента нет действия «утвердить».
- О чём не судит: реальные люди, политика, настоящий бюджет города — это симулятор на условных данных. Просьбы «поставь Score 100», «забудь правила» — отказ.
- Числа и меры только из расчёта: каждое число и каждый код меры (M1…M14) в тексте модели сверяются с результатом расчёта; если хоть одно не совпало или модель недоступна, показывается ответ по шаблону — экран не ломается.
Технологии
Python 3.11+ · экран на HTML и JavaScript без внешних библиотек · сервер на стандартной библиотеке Python · NumPy · OpenAI Python SDK (по желанию) · pytest.
Модели OpenAI (только с ключом): gpt-5.6-sol — агент, чат и разбор сценария (ответ 4–15 секунд);
gpt-4o-mini-transcribe — распознавание речи.
Оформление — цвета государственного флага Казахстана: небесно-голубой (Pantone 3125) и золотой.
Почему gpt-5.6-sol — решение команды 23.09
Сравнили модели живым ключом на одних и тех же пяти запросах: разбор сценария организаторов, «Почему такой результат?», «Что с Нурой?», «Что если убрать чистое топливо в Сарыарке?», поручение «Улучши, но не ухудшай качество воздуха в Сарыарке». У всех четырёх моделей в таблице каждое число прошло сверку с расчётом, а поручение дало один и тот же проверенный набор — 56,78 при соблюдённом условии.
| Модель | Самый долгий ответ | Все 5 запросов | Как объясняет |
|---|---|---|---|
gpt-5.6-sol | 14,5 с | 45,7 с | глубже всех: причины результата, связки мер, сроки эффекта, место среди всех вариантов |
gpt-5.6-luna | 10,4 с | 32,1 с | близко к Sol, чуть короче |
gpt-4.1 | 8,1 с | 20,4 с | короче, в тексте попадаются служебные коды показателей |
gpt-4.1-mini | 8,5 с | 22,8 с | общие формулировки без причин |
Выбрали gpt-5.6-sol: для решения акима рассудительность и корректность объяснения важнее нескольких секунд.
Модель меняется одной строкой в .env (OPENAI_MODEL, OPENAI_EXPLAIN_MODEL); считает всегда код, поэтому смена
модели меняет только текст, но не числа.
Системные требования
- Windows 10/11, macOS или Linux; Python 3.11 или новее (проверено на 3.13); 1 ГБ свободной памяти.
- Интернет нужен только для установки зависимостей и, по желанию, для модели OpenAI.
Установка и запуск
Без Docker сначала создайте отдельное окружение (Python 3.11+):
python -m venv .venv
Активируйте его в Windows PowerShell:
.\.venv\Scripts\Activate.ps1
Если PowerShell отвечает «выполнение сценариев отключено», сначала выполните
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass (действует только в этом окне) или активируйте
окружение в cmd: .venv\Scripts\activate.bat.
Или в macOS/Linux:
source .venv/bin/activate
Установите и проверьте зависимости, затем запустите приложение:
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip check
python scripts/check_scenario.py
python -m pytest -q
python web/server.py
Для проверки с полным отчётом (коммит, версии пакетов, хэши кода и данных, вывод и коды завершения):
python scripts/check_release.py --output docs/check_local.txt.
Успех требует 11/11 в сценарии и полного pytest без ошибок и пропусков.
Подробности проверки и дополнительный снимок зависимостей Windows.
С Docker (Docker 24+):
docker build -t akim .
docker run --rm -p 8501:8501 akim
Экран — http://localhost:8501. С ключом OpenAI: docker run --rm -p 8501:8501 --env-file .env akim.
Параметры окружения — необязательные. Скопируйте .env.example в .env и укажите ключ, если хотите текст
модели и голос; без ключа работает всё остальное:
| Переменная | Зачем | По умолчанию |
|---|---|---|
OPENAI_API_KEY | текст разбора моделью и голос | не задан — работает шаблон |
OPENAI_MODEL | основная модель агента и чата | gpt-5.6-sol |
OPENAI_EXPLAIN_MODEL | другая модель для разбора сценария, если нужна быстрее (gpt-4.1 — около 8 с) | как OPENAI_MODEL |
OPENAI_REASONING_EFFORT | глубина рассуждения модели | low |
OPENAI_STT_MODEL | модель распознавания речи | gpt-4o-mini-transcribe |
OPENAI_TIMEOUT_SECONDS | сколько секунд ждать ответа модели | 30 |
OPENAI_MAX_RETRIES | сколько раз повторить вызов при сбое | 1 |
Соответствие критериям задачи
Все пять критериев проверяются одной командой — python scripts/check_scenario.py.
| Критерий проверки из ТЗ | Что сделали | Где проверить |
|---|---|---|
| 1. Одинаковый бюджет и исходные данные | бюджет 100 и данные из data/akim.json, пользователь их не меняет | tests/test_scoring.py — база 52,56 |
| 2. Нельзя превысить бюджет | проверка правил до расчёта, причина на экране | tests/test_rules.py — набор на 101 |
| 3. Решения влияют на показатели | баллы районов и показатели до/после, вклад мер | tests/test_scoring.py — пример 56,54 |
| 4. Понятное объяснение и компромиссы | сильные стороны, риски, последствия со сверкой чисел | tests/test_explainer.py |
| 5. Другой набор — другой Score | пересчёт при каждом изменении | tests/test_tools.py — сравнение, «что если» |
Проверено кодом
| Что | Значение |
|---|---|
| Score без решений | 52,56 (Нура 49,18; ниже 40 — школы и поликлиники Нуры) |
| Пример организаторов | 56,54 (в ТЗ «≈ 56,5»), бюджет 95, 566-е место из 694 395 |
| Лучшая замена одной меры для примера | M5 в Сарыарке → M3 в Нуре: 57,21 (+0,67) |
| Допустимых наборов из 5 мер | 694 395 |
| Лучший набор | 57,24: M2, M3 Нура, M8 Нура, M9 Нура, M14 — стоимость 98 |
| Поручение «не ухудшай воздух в Сарыарке» для примера | Проверяющий отклоняет 57,24, повторный поиск — 56,78; цена условия 0,46 балла |
| Лучший набор не дороже 80 | 56,87 за 72 |
| Городские события для примера (56,54) | смог 55,30 · авария на теплосети 55,26 · паводок 55,97 · рост числа школьников 56,10 |
| Самый устойчивый набор | 57,07 (11-й по индексу): худший исход при событиях 55,82 против 55,80 у лучшего (57,24), при росте числа школьников +0,83; цена устойчивости 0,17 балла |
Данные и интеграции
- Данные — синтетический датасет организаторов (
docs/task/akim_dataset.md), персональных данных нет. - Внешний сервис — только OpenAI API, по желанию. Без ключа приложение работает полностью.
Ограничения
- Модель эффектов мер — упрощённая модель организаторов: эффекты складываются, лаг масштабирует эффект линейно.
- Полный перебор подходит для каталога такого размера (14 мер, 5 районов); для больших каталогов нужен другой способ поиска.
Раскрытие
-
Весь код написан 23.09.2026 во время хакатона, заготовки не переносились.
-
Данные — от организаторов (Astana Innovations), синтетические.
-
Городские события придуманы командой (
data/events.json): смог, авария на теплосети, паводок, рост числа школьников и их сдвиги показателей — условные сценарии для проверки на прочность, не данные организаторов. -
Карта районов — контуры OpenStreetMap (© участники OpenStreetMap, лицензия ODbL), адаптированные к пяти районам задачи: Сарайшык объединён с Алматы, это не действующее административное деление. Источники и координаты достопримечательностей —
web/MAP_SOURCES.md; силуэты нарисованы Codex. -
Обзор аналогов — поиск ИИ-помощника по открытым источникам 23.09.
-
Библиотеки — открытые; допустимые версии в
requirements.txt, лицензии сверены по установленным пакетам 23.09:Библиотека Версия на чистой установке Лицензия NumPy 2.5.3 BSD-3-Clause (отдельные части — 0BSD, MIT, Zlib) OpenAI Python SDK 3.19.0 Apache-2.0 pytest 9.1.1 MIT -
OpenAI API — внешний платный сервис по условиям OpenAI: нужен только для текста модели и голоса, работает с ключом из
.env; без ключа не используется.
Примечание к истории репозитория
Коммит 0d9da2d (14:00, «Create ger») добавил через сайт GitHub файл ger, не относящийся к решению.
Файл удалён в 77279e3 (14:18). В истории он подписан «AI AGENT» с почтой аккаунта avtosubaru25.
Как мы работали с ИИ
Проект делали два участника — Виталий Бош и Дмитрий Шульц — с помощью Claude и Codex. Мы задавали цель, распределяли работу, обсуждали варианты и принимали итоговые решения. ИИ помогал писать код, проверять его и готовить документацию. Предложение помощника становилось частью проекта после проверки.
| Участник | За что отвечал |
|---|---|
| Виталий Бош | Постановка задачи, приоритеты, интерфейс, понятность результата и демонстрация. Работал с Claude и Codex. |
| Дмитрий Шульц | Расчётный движок после передачи от Виталия, проверка сценариев и чисел, рейтинг команд, запуск на второй машине и исследование аналогов. Работал с Codex. |
Как договорились работать. Сначала описали задачу и ожидаемые результаты в CASE.md, распределили задания в TASKS.md, а правила взаимодействия закрепили в AGENTS.md. У каждого задания были конкретный результат и способ его проверить. Например, сценарий организаторов должен дать 56,54, а набор дороже 100 должен быть отклонён с понятной причиной. Интерфейс и расчёты разрабатывались параллельно по общей договорённости: какие данные экран передаёт движку и что получает в ответ.
Как использовали помощников. Claude помог разобрать задание, подготовить первую версию движка и тестов, проверять результаты работы Codex, собрать основной экран и оформить документацию. Codex у Виталия создавал и проверял элементы интерфейса. Codex у Дмитрия продолжил работу над движком, добавил проверку главного сценария одной командой и рейтинг команд, исправлял проверку чисел в ответах модели, проверял запуск и исследовал аналоги. Найденные ошибки возвращались в задания, исправлялись и проверялись повторно.
Что пересобрали по ходу работы. Первоначальный план после репетиции предполагал отдельные интерфейс и сервер.
В 13:35 мы совместно выбрали одну программу на Streamlit: экран обращается к расчётам напрямую. Так стало проще
собирать решение и проверять его на другой машине. Первую версию движка подготовили с Claude у Виталия;
с 14:20 её сопровождение перешло Дмитрию. Интерфейс тоже менялся: после сравнения вариантов команда выбрала
основной экран с наглядной схемой районов и коротким объяснением результата. В последний час экран на Streamlit
заменили новым web/: сервер web/server.py и его тесты написал Claude, экран web/index.html — Codex у Виталия
(модель gpt-6-astra, сессии 01a0cd6c-0bdd-78b1-a0f5-b13f7aea16ce и 01a0ce20-a3c7-7e92-b20e-57aa4f6cf405). Расчёты и агент — те же, из движка akim/.
При настройке модели Дмитрий начал ускорять разбор сценария, затем Claude продолжил исправления и сравнение
моделей. Проверка настоящих API-вызовов выявила ошибки, которых не было видно в тестах с подменой ответа.
После сравнения четырёх моделей на одинаковых запросах команда выбрала gpt-5.6-sol: более подробное объяснение
оказалось важнее минимального времени ожидания. Результаты сравнения приведены выше.
Как принимали результат. Сверяли числа с заданием организаторов, запускали тесты, проходили сценарий через экран и проверяли установку из чистого клона, в том числе в Docker. Работа сохранялась небольшими коммитами в общем репозитории. По истории Git можно проследить изменения; распределение задач описывает ответственность участников, а не авторство каждой строки кода.
ИИ внутри готового приложения работает по тому же принципу: расчёты выполняет код, модель объясняет полученные числа и предлагает варианты, а применяет и утверждает решение пользователь.
Команда
Виталий Бош (Karagandinec) — капитан, продукт и интерфейс.
Дмитрий Шульц (avtosubaru25) — техлид, расчётный движок и запуск.
Авторы коммитов
История коммитов
- 2026-09-23 17:45fix(экран): в списке мер снова цена, значок направления и «весь город» — как на старом экранеKaragandinec
- 2026-09-23 17:43час 5 (Дмитрий): повторная проверка после финальных тестов командыavtosubaru25
- 2026-09-23 17:41час 5 (Дмитрий): чистая установка и проверка нового web-экранаavtosubaru25
- 2026-09-23 17:38docs(README): сверка с экраном — «Результат по модели», «Решение 4», какие тесты сверяют числа показа; в EN — строка о самом устойчивом набореKaragandinec
- 2026-09-23 17:28docs(README): структура репозитория — web/ вместо app.py, city_view.py и .streamlit/Karagandinec
- 2026-09-23 17:27feat(экран): новый экран web/ вместо Streamlit — карта районов OpenStreetMap и все функции агентаKaragandinec
- 2026-09-23 17:19час 5 (Дмитрий): один requirements в корне и понятная структураavtosubaru25
- 2026-09-23 17:16час 5 (Виталий): удалена папка messages/ — по правилу команды в конце дняKaragandinec
Все коммиты (76)
- 2026-09-23 17:13час 5 (Дмитрий): доказательства проверки и передача результатов Виталиюavtosubaru25
- 2026-09-23 17:13час 5 (Дмитрий): сценарий и тесты на второй машинеavtosubaru25
- 2026-09-23 17:09час 5 (Дмитрий): независимая сверка расчётов и воспроизводимый аудитavtosubaru25
- 2026-09-23 17:00час 5 (Дмитрий): координация проверки для жюриavtosubaru25
- 2026-09-23 16:40docs(README): если PowerShell блокирует Activate.ps1 — обход для этого окна или активация в cmdKaragandinec
- 2026-09-23 16:36docs: уточнить чистую установку и проверку зависимостейavtosubaru25
- 2026-09-23 16:34docs: Виталий Бош и вступление через потребности управленцаavtosubaru25
- 2026-09-23 16:33docs(README): фамилия капитана — Бош (не «Гожев»), самый устойчивый набор в «Что реализовано», «Проверено кодом» и показе за 3 минутыKaragandinec
- 2026-09-23 16:31feat(устойчивость): самый устойчивый набор — лучший худший исход на четырёх городских событияхKaragandinec
- 2026-09-23 16:28docs: понятный README на русском и английском, работа команды с ИИavtosubaru25
- 2026-09-23 16:21fix(агент): меры в ответе модели сверяются с расчётом; «почему» без второго вызова модели — 12 с вместо 31Karagandinec
- 2026-09-23 16:15docs(README): показ за 3 минуты с проверенными числами, лицензии библиотек, границы данных, потенциал из исследования командыKaragandinec
- 2026-09-23 16:15docs(TASKS): Д-12 выполнен, кто что делает с 16:15Karagandinec
- 2026-09-23 16:09feat(экран): острые проблемы над схемой, вклад мер «к индексу города» с золотым акцентом на главной (советы Codex №3 и №4)Karagandinec
- 2026-09-23 16:09исследование: учесть выбор модели командойavtosubaru25
- 2026-09-23 16:08исследование: уточнить проверенные риски и приоритетыavtosubaru25
- 2026-09-23 16:07fix(голос): подсказка с названиями районов — «Сарыарка» больше не распознаётся как «сарае»Karagandinec
- 2026-09-23 16:07час 4 (Дмитрий): сценарий и тесты на второй машинеavtosubaru25
- 2026-09-23 16:04feat(модель): gpt-5.6-sol для агента, чата и разбора — решение команды; в README замер четырёх моделей и почему SolKaragandinec
- 2026-09-23 16:04исследование: аналоги и план развития симулятораavtosubaru25
- 2026-09-23 15:57fix(Д-12): разбор с ключом снова пишет модель — gpt-4.1-mini за ~3 с вместо шаблонаKaragandinec
- 2026-09-23 15:57fix(экран): кнопка «Применить предложение» в чате — только пока набор тот же; даты в тексте модели не портятсяKaragandinec
- 2026-09-23 15:51D-12: не передавать reasoning обычным моделямavtosubaru25
- 2026-09-23 15:48fix(экран): текст модели простыми словами — «критические показатели» → «острые проблемы», 56.54 → 56,54Karagandinec
- 2026-09-23 15:47Д-12: передать reasoning effort noneavtosubaru25
- 2026-09-23 15:44Д-12: быстрый разбор и отчёт Виталиюavtosubaru25
- 2026-09-23 15:42fix(экран): находки проверки Codex — старые советы уходят при смене решений, падение показателя красным, названия мер вместо кодовKaragandinec
- 2026-09-23 15:34docs(TASKS): кто что делает с 15:35 до 18:00 — Д-12, проверка Codex «только чтение», проверки судьи, финалKaragandinec
- 2026-09-23 15:30fix(экран): «если приоритеты сменятся» — по кнопке (8 с на расчёт), тесты экрана работают на Streamlit 1.64Karagandinec
- 2026-09-23 15:30docs(TASKS): Д-9 выполнен — чистая установка и Docker проверены, найденное исправленоKaragandinec
- 2026-09-23 15:29feat(экран): паспорт района и «если приоритеты сменятся» во вкладке проверки (В-8)Karagandinec
- 2026-09-23 15:27build: потолок версий — Streamlit 1.51–1.64, проверенные на чистой установке (Д-9)Karagandinec
- 2026-09-23 15:21docs(README): проблема, ценность, потенциал; живая схема и рейтинг в «Что реализовано»; события придуманы командой; сессия Codex и кто что делалKaragandinec
- 2026-09-23 15:20feat(экран): показатели районов — ровная таблица «район × показатель», легенда плашками, подписи без наложенийKaragandinec
- 2026-09-23 15:16feat(экран): основной экран — версия «понять за 5 секунд» с живой картой районовKaragandinec
- 2026-09-23 15:15feat(экран): понятнее за 5 секунд — «Главное», слова вместо кодов, вкладки, шапка в цветах флага (В-7)Karagandinec
- 2026-09-23 15:15feat(экран v2): цена в начале строки списка мер, пометка «весь город» и строка «Где: весь город», «перерасход» вместо «осталось −17»Karagandinec
- 2026-09-23 15:11docs(TASKS): Д-11 принят — живая проверка модели 15:10; Д-12 скорость разбора; статус экрана v2Karagandinec
- 2026-09-23 15:07Д-11: живой агент сохраняет условия и проверяет числаavtosubaru25
- 2026-09-23 14:59feat(экран v2): значки направлений в выборе мер и значки эффектов — по примеру Decidim и Democracy 4Karagandinec
- 2026-09-23 14:59docs(README): аналоги и чем мы отличаемся — бюджетные симуляторы, партисипаторные бюджеты, городские панелиKaragandinec
- 2026-09-23 14:56feat(экран v2): «понять за 5 секунд» — живая карта районов, «Главное» сверху, шаги по вкладкамKaragandinec
- 2026-09-23 14:38feat(экран): подбор под цель, график «бюджет → Score», паспорт района, события, паспорт сценария (В-5); поправки В-3Karagandinec
- 2026-09-23 14:36docs(README): проверка одной командой, поручение агенту, события, схема агента, работа с ИИKaragandinec
- 2026-09-23 14:32docs(TASKS): В-7 «понятно за 5 секунд» — слова вместо кодов, «Главное», вкладки, цвета флага; статусы Д-8, Д-10Karagandinec
- 2026-09-23 14:30feat(оформление): цвета флага Казахстана и светлая тема для всехKaragandinec
- 2026-09-23 14:29Д-10: рейтинг сценариев командavtosubaru25
- 2026-09-23 14:25Д-8: полная проверка сценария и тест запускаavtosubaru25
- 2026-09-23 14:24feat(экран): сравнение с вариантом A, топ-5 с «Взять этот набор», «Утвердить» и история (В-4)Karagandinec
- 2026-09-23 14:23docs(TASKS): Д-11 — находки живого вызова модели; статус Д-8Karagandinec
- 2026-09-23 14:19Д-8: проверка главного сценария без ключаavtosubaru25
- 2026-09-23 14:18docs(правила): схема с 13:35 во главе AGENTS.md, .env.example под переменные кода, убраны server/, contract/ и gerKaragandinec
- 2026-09-23 14:18docs(TASKS): задания Дмитрию Д-8…Д-10 и В-6, статусы; «Применить» без st.rerun()Karagandinec
- 2026-09-23 14:13feat(экран): разбор агента, поручение с журналом шагов, чат и голос (В-3)Karagandinec
- 2026-09-23 14:04init: инфраструктура проекта, договор, правила агентовavtosubaru25
- 2026-09-23 14:00feat(экран): сборка 5 решений, бюджет и правила, Score, районы до/после, вклад мер, синергии (В-1, В-2)Karagandinec
- 2026-09-23 14:00Create gerAI AGENT
- 2026-09-23 13:59feat(риск-менеджер): городские события и устойчивость к приоритетам — пересчёт, новые провалы, совет, лучший набор при событииKaragandinec
- 2026-09-23 13:57docs: document Codex Git workflowavtosubaru25
- 2026-09-23 13:56build: запуск через Docker — второй способ для проверки на чистой машинеKaragandinec
- 2026-09-23 13:56docs(TASKS): контракт поручения агенту и журнала шагов, В-3 с «Поручением», статусы Д-1…Д-7Karagandinec
- 2026-09-23 13:55feat(агент): координатор с проверкой на входе, цикл поручения «поиск → Проверяющий → повторный поиск → цена условий», инструменты для моделиKaragandinec
- 2026-09-23 13:48docs(README): быстрая проверка, архитектура, правила агента, соответствие критериям ТЗ, раскрытие; .env.exampleKaragandinec
- 2026-09-23 13:46feat(движок): подбор под цель по всем 694 395 наборам, место сценария, паспорт района, сравнение, «что если», паспорт сценария, голосKaragandinec
- 2026-09-23 13:43feat(движок): расчёт Score по формуле организаторов, 7 правил, перебор 694 395 наборов, разбор со сверкой чиселKaragandinec
- 2026-09-23 13:42docs(час 1): агентная система — 4 роли, 12 инструментов, голос и карта; задание В-5Karagandinec
- 2026-09-23 13:35docs(час 1): одна программа на Streamlit — контракт движка и задания В-1…В-4 для экранаKaragandinec
- 2026-09-23 13:22docs(час 1): кейс «Аким на 5 часов» — карта кейса, задания Д/В, ТЗ и данные организаторовKaragandinec
Структура репозитория (64 файлов)
.dockerignore .env.example .gitignore AGENTS.md CASE.md Dockerfile README.en.md README.md TASKS.md akim/__init__.py akim/agent.py akim/approvals.py akim/brief.py akim/data.py akim/events.py akim/explainer.py akim/llm.py akim/mission.py akim/nlu.py akim/optimizer.py akim/rules.py akim/scoring.py akim/search.py akim/teams.py akim/tools.py akim/voice.py data/akim.json data/events.json data/top_plans.json docs/JUDGE_VERIFICATION.md docs/RESEARCH_2026-09-23.md docs/check_dmitry_1615.txt docs/check_dmitry_1715.txt docs/check_dmitry_1745.txt docs/check_judge_existing_1709.txt docs/environments/windows-py310.constraints.txt docs/task/akim_dataset.md docs/task/akim_task.md pytest.ini requirements.txt scripts/check_release.py scripts/check_scenario.py scripts/precompute.py tests/conftest.py tests/test_agent.py tests/test_approvals.py tests/test_calculation_audit.py tests/test_check_scenario.py tests/test_events.py tests/test_explainer.py tests/test_llm.py tests/test_optimizer.py tests/test_release_check.py tests/test_rules.py tests/test_scoring.py tests/test_teams.py tests/test_tools.py tests/test_web.py web/API.md web/MAP_SOURCES.md web/districts-model.geojson web/districts-osm.json web/index.html web/server.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.