О проекте
Команда: Infinity AI
Кейс HackAlem.ai: Энергетика — Самрук-Казына
Стадия: Доведённый продукт
Задача кейса: AI-агент, прогнозирующий выработку ветровой электростанции по погодным данным
Суть
Агентная система почасового прогноза выработки ВЭС «Нурлы» на 24–48 часов. Агент проходит цикл «погода → признаки → обучение → прогноз → анализ → перепланирование» и воспроизводит выпуски февраля 2026 «как в прошлом». Есть чат-агент с function calling и 3D-дашборд.
Как устроено
Погода берётся только из Open-Meteo Previous Model Runs (переменные *_previous_day1/2), так что будущие данные в модель не попадают; проверка all_runs_before_issue встроена. Модель строит эмпирическую кривую мощности по v_eq с поправкой на плотность воздуха, монотонность обеспечивает изотоническая регрессия. Поверх неё HistGradientBoosting обучается на остатках, отдельно для T1 и T2; квантильный бустинг даёт диапазон Q10–Q90. Перепланирование идёт по правилам: новый прогон погоды, рост MAE вдвое, 7 суток новых фактов. Чат-агент сам вызывает инструменты (get_forecast, find_analogs, search_knowledge и др.) через vLLM с Qwen или через OpenAI. База знаний построена на TF-IDF с SVD и хранится в ClickHouse.
Ключевые решения
- эмпирическая кривая мощности
- изотоническая регрессия
- HistGradientBoostingRegressor на остатках
- квантильный бустинг Q10–Q90
- Analog Ensemble
- TF-IDF char n-grams + SVD (LSA)
- function calling
- SSE
- Open-Meteo Previous Model Runs
- rule-based replanning
Метрики
Покрытие диапазона Q10–Q90 на январе 78% / 75% при цели 80%; 20 тестов (утечка будущего, данные, модель, API)
Особенности
Утечку будущего закрывают строго, через архивные прогоны метеомодели. Паспорт турбин переводится в МВт·ч, есть уведомления о резких изменениях мощности и режим «машины времени» с паспортом выпуска. Все шаги агента с причинами пишутся в журнал и видны в UI.
Стек
Python · FastAPI · pandas · scikit-learn · ClickHouse · SQLite · React 19 · TypeScript · Vite · Tailwind · Recharts · Leaflet · three.js · Docker Compose · pytest
Модели
Qwen3.8-27B (vLLM, NVIDIA H200/L40S) · OpenAI
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-9a8fb661-infinity-ai.
README
README.mdInfinity AI — Agentic AI для прогноза выработки ВЭС
HackAlem AI 2026, трек «Энергетика». Команда Infinity AI.
Система сама выполняет полный цикл прогноза почасовой выработки ветроэлектростанции на 24–48 часов: получает архивный прогноз погоды на момент выпуска → готовит признаки → (пере)обучает модель → строит почасовой прогноз → анализирует результат → пересчитывает при обновлении входных данных. Процесс воспроизводится «как в прошлом»: выпуски 31.01, 01.02, … 27.02.2026.
Вход в систему (для проверки)
Логин: expert · Пароль: infinity-demo — задаётся в .env (APP_LOGIN, APP_PASSWORD, см. .env.example),
одинаково для локального запуска (http://localhost:5180) и Docker (http://localhost:3000).
Главное правило: никакой утечки будущего
Погода берётся из Open-Meteo Previous Model Runs API — только переменные *_previous_day1/2,
то есть значения из прогонов метеомодели, сделанных за 1–2 суток до целевого часа.
Для выпуска D (00:00 UTC) час +h ≤ 24 берётся из прогона за сутки, +h ≤ 48 — за двое суток:
оба прогона выпущены не позже D. «Текущие» (близкие к факту) переменные не запрашиваются вообще.
Обучение идёт на том же типе данных (архивные прогнозы за прошлое), модель обучается только на
фактах строго раньше момента выпуска. Проверка вшита в агент (all_runs_before_issue).
Объект: ВЭС «Нурлы» (паспорт)
Источник: Samruk-Green Energy, проект ВЭС 5 МВт;
в системе — таблица wind_objects.
| Параметр | Значение |
|---|---|
| Станция | ВЭС 5 МВт, п. Нурлы, Енбекшиказахский район, Алматинская область |
| Оператор | ТОО «Samruk-Green Energy» |
| Ввод в эксплуатацию | 20 июля 2020 (строительство март–ноябрь 2018) |
| Плановая годовая выработка | около 16 млн кВт·ч |
| Турбины | 2 × Goldwind GW109/2500 (XINJIANG GOLDWIND Science & Technology), класс IEC IIA/IIIA |
| Мощность одной турбины | 2,5 МВт |
| Ротор | 3 лопасти, диаметр 109 м; лопасти — стеклопластик (Sinoma) |
| Башня | трубчатая коническая стальная, 80 м |
| Стартовая / номинальная / максимальная скорость ветра | 3 / 10,3 / 25 м/с |
| Координаты | T1: 43.645139, 78.535611 · T2: 43.643194, 78.538833 |
Как паспорт используется в системе: номинал 2,5 МВт переводит нормализованную мощность в МВт·ч;
высота ступицы 80 м обосновывает ветер на 100 м из метеомодели (ближайший уровень к ступице);
диапазон 3–25 м/с — ориентир для кривой мощности (нижняя граница в модели 1,5 м/с, потому что
прогнозный ветер занижен относительно измеренного на гондоле; отсечка 25 м/с совпадает с паспортом);
данные о пропусках (wind_actuals_gaps) — 245 пропусков, самый длинный 999 ч у T1 (май–июнь 2024).
Архитектура
React UI (Vite, TS) ──/api──► FastAPI ──► ForecastAgent (цикл + политика пересчёта)
│ ├─ fetch_forecast Open-Meteo previous runs (+кеш data/cache)
│ ├─ prepare_features плотность воздуха, v_eq, направление, порывы
│ ├─ train_model кривая мощности + бустинг остатков
│ ├─ predict 48 ч × {T1, T2, станция}
│ ├─ analyze sanity-check, сравнение с прошлым выпуском
│ ├─ evaluate MAE/RMSE/skill к персистентности
│ ├─ replan пересчёт / переобучение по правилам
│ └─ report сводка LLM (OpenAI / vLLM на NVIDIA / mock)
├─ Chat-агент: LLM сам вызывает инструменты (function calling), SSE-поток
└─ Store: ClickHouse (основное) | SQLite (запасное)
Политика перепланирования: новый прогон погоды (изменилась сигнатура) → пересчёт; разница ветра с прошлым выпуском > 1.5 м/с → пометка ревизии; пропуск факта > 3 ч → пониженная достоверность; MAE выпуска > 2× среднего → переобучение; ≥ 7 суток новых фактов → переобучение. Каждое действие и его причина пишутся в журнал агента и видны в UI.
Модель: эмпирическая кривая мощности (медианы по бинам 0.25 м/с от прогнозного v_eq с поправкой
на плотность воздуха, монотонность через изотоническую регрессию) + HistGradientBoostingRegressor
на остатках (направление, порывы, сезон, час суток, горизонт). Отдельно для T1 и T2, станция = среднее.
Агент: цикл, уведомления, диалог, база знаний
- Цикл агента (страница «Агент»): для каждого выпуска — получение погоды → подготовка данных
(с учётом пропусков
wind_actuals_gaps) → обучение по политике → прогноз → анализ → оценка → перепланирование → отчёт. Каждый шаг с причиной пишется вagent_logи показывается в UI. - Уведомления (
/api/alerts): резкие изменения выработки по ΔP̂ₕ = P̂ₕ₊₁ − P̂ₕ (порог 15 % Pном за час, 30 % за 3 ч, задаётся под оператора), штиль, риск остановки по ветру (> 22 м/с), обледенение (< −10 °C), пониженная достоверность. Для окна события проверяется расхождение с прошлым выпуском («сценарии заметно расходятся»). Пример: «Днём ожидается снижение мощности на 1,9 МВт (38 % Pном). Наиболее вероятное окно — 17:00–20:00. В этом интервале сценарии заметно расходятся с прошлым выпуском». - Диалог (
/api/agent, SSE): LLM сама выбирает инструменты —get_forecast,get_alerts,get_period_summary,get_metrics,get_agent_log,find_analogs,search_knowledge,run_forecast. Режимы Быстрый/Средний/Думающий, память диалога, понимание опечаток, вложения (docx, doc, pdf, xlsx, csv, изображения), выгрузка ответа в Word/Excel. Ответ на языке вопроса. Провайдеры: vLLM (Qwen3.8-27B на NVIDIA H200) → OpenAI → правила с автоматическим переходом. - База знаний (
python -m app.cli train-embeddings): эмбеддинги обучаются на корпусе проекта (паспорт станции, методика, данные, метрики, README): TF-IDF по символьным n-граммам + SVD (LSA), индекс в ClickHouse (knowledge_chunks,cosineDistance) и в памяти. Никаких внешних сервисов. - Машина времени: режим «Доступно тогда / Факт для оценки» и паспорт выпуска (
/api/passport): момент выпуска, до какого часа был факт, окно публикации прогонов погоды, контрольная сумма входа, версия модели, отличие от прошлого выпуска.
Интерфейс
Вход по логину/паролю (для проверки: expert / infinity-demo). Страницы в сайдбаре:
- Прогноз — фильтры (объект, горизонт 24/48 ч, дата выпуска, «Доступно тогда / Факт для оценки», график/таблица),
полоса ключевых чисел (формулы — во всплывающей подсказке), график прогноз/факт/прошлый выпуск, погода на горизонте,
автоматический ИИ-анализ выпуска (
/api/insight), уведомления агента, почасовая таблица, экспорт CSV. - Исторический прогон — воспроизведение февраля по дням «как в прошлом»: шкала выпусков 31.01–27.02, «Продолжить» / «Следующий день», цепочка шагов цикла, текущий выпуск против предыдущего, решения системы, таблица запусков.
- Карта и 3D — спутниковая карта с турбинами; клик — паспорт объекта с живыми данными и мини-3D; 3D-сцена площадки: рельеф, подстанция, лопасти вращаются по прогнозному ветру, поток частиц по направлению ветра.
- Данные и источники — параметры турбин, реестр источников (история, архив прогнозов Open-Meteo, справочник,
пропуски, отсутствующий факт февраля), аномалии, найденные системой в истории (простои, залипание датчика,
мощность без ветра, пропуски
wind_actuals_gaps), сверка таблиц ClickHouse, пропуски по месяцам. - Агент — чаты как в ChatGPT (история, режимы Быстрый/Средний/Думающий), вложения документов, ответы с таблицами, выгрузка в Word/Excel, живая лента «Как агент построил этот прогноз», похожие дни. Русский/казахский, светлая/тёмная тема.
Технологии
Бэкенд: Python 3.12, FastAPI, pandas, numpy, scikit-learn (HistGradientBoosting, квантильная регрессия, TF-IDF + SVD), ClickHouse (clickhouse-connect) / SQLite, OpenAI SDK (совместим с vLLM), python-docx, openpyxl, pypdf, matplotlib, pytest. Фронтенд: React 19 + TypeScript + Vite, Tailwind CSS 4, Recharts, react-markdown + remark-gfm, Leaflet, three.js, lucide-react. Инфраструктура: Docker Compose; опционально vLLM на NVIDIA H200 (Brev).
Структура
backend/app/
core/ конфиг, логирование
api/ роутеры FastAPI (health, forecasts, metrics, agent), зависимости
schemas/ pydantic-схемы ответов
db/ Store: clickhouse.py, sqlite.py, factory.py
ml/ data, weather, features, model, metrics, pipeline
services/ agent (цикл), chat (function calling), llm, export
cli.py fetch-weather | backtest | forecast | ensure | export
frontend/ React + TS (Vite), nginx.conf для docker
data/raw/ исходные CSV организаторов (10 мин) + wind_actuals.csv (выгрузка дата-инженера)
data/cache/ ответы Open-Meteo — проверка работает без сети
outputs/ forecasts.csv, forecasts_test_period.csv, metrics.json
Быстрая проверка для жюри (Windows / Linux / macOS)
Нужен только Docker Desktop (Windows, macOS) или Docker Engine + Compose (Linux). Ключи, GPU и интернет-API не нужны.
git clone https://github.com/BAITC-Hacks/hack-9a8fb661-infinity-ai.git
cd hack-9a8fb661-infinity-ai
docker compose up --build
Через 2–4 минуты (первый старт сам прогоняет бэктест и обучает базу знаний) открыть http://localhost:3000,
войти expert / infinity-demo. Остановить: Ctrl+C, затем docker compose down.
Что проверить — раздел «Проверка основного сценария». Свободными должны быть порты 3000, 8010, 8123, 9000.
Без Docker — вариант 1 ниже. Отличия для Windows (PowerShell): py -3.12 -m venv .venv,
.venv\Scripts\activate, copy .env.example .env.
Запуск
Нужно: Python 3.12, Node.js 20+, git. ClickHouse, GPU и ключи не нужны: по умолчанию — SQLite,
погода из кеша data/cache, агент отвечает по правилам на реальных данных. Проверено на чистой копии.
Вариант 1 — локально (≈ 3 минуты)
git clone https://github.com/BAITC-Hacks/hack-9a8fb661-infinity-ai.git # или: git pull origin main
cd hack-9a8fb661-infinity-ai
python3.12 -m venv .venv && source .venv/bin/activate
pip install -r backend/requirements.txt
cp .env.example .env # SQLite, офлайн-погода, вход expert / infinity-demo
cd backend
python -m app.cli backtest # ~1 мин: 58 выпусков (январь — бэктест, 31.01–27.02 — тест)
python -m app.cli train-embeddings # база знаний агента (эмбеддинги)
uvicorn app.main:app --port 8010 # API; оставить запущенным
Во втором терминале:
cd hack-9a8fb661-infinity-ai/frontend
npm ci
npm run dev # http://localhost:5180 (вход: expert / infinity-demo)
Проверка: cd backend && pytest -q — 31 тест; cd frontend && npm test — 3 теста.
Вариант 2 — Docker (одна команда, с ClickHouse)
docker compose up --build # UI: http://localhost:3000 (expert / infinity-demo)
При первом старте бэкенд сам прогоняет бэктест и обучает базу знаний.
По желанию
- Живая LLM: в
.env—USE_MOCK_LLM=falseиOPENAI_API_KEY=sk-…(илиLLM_BASE_URLдля своей модели на vLLM, см.gpu/README.md). Без этого агент работает по правилам. - ClickHouse вместо SQLite:
docker compose up -d clickhouse, в.env—DB_BACKEND=clickhouseи парольCLICKHOUSE_PASSWORD. Таблицыwind_objects,wind_actuals,wind_actuals_gapsсоздаются и заполняются при старте. - Свежая погода из сети:
WEATHER_OFFLINE=false(иначе только кеш из репозитория). - Показ команде в локальной сети:
cd frontend && npm run serve:lan→http://<IP>:5180(в Wi-Fi хакатона может мешать изоляция клиентов).
LLM агента: правила, OpenAI API, NVIDIA H200
Прогноз от LLM не зависит; LLM нужна только для диалога, ИИ-анализа выпуска и сводок. Три режима, переключение через .env:
| Режим | Что нужно | Настройка |
|---|---|---|
| Правила (по умолчанию, для проверки) | ничего | USE_MOCK_LLM=true — агент отвечает по тем же инструментам на реальных данных |
| OpenAI API | свой ключ | USE_MOCK_LLM=false, OPENAI_API_KEY=sk-… (модели: gpt-4o-mini / gpt-4o / o4-mini для режима «Думающий») |
| Своя модель на NVIDIA H200 | GPU в NVIDIA Brev | USE_MOCK_LLM=false, LLM_BASE_URL=http://localhost:8001/v1, VLLM_MODEL=qwen |
Во время хакатона агент работал на Qwen3.8-27B (bf16) на NVIDIA H200 141 GB в NVIDIA Brev: vLLM в Docker
(gpu/serve_vllm.sh), OpenAI-совместимый API, вызов инструментов qwen3_xml, режимы размышления через
reasoning_effort, туннель brev port-forward / ssh -L 8001:localhost:8000. Скрипт сам выбирает полную или FP8-версию
по объёму видеопамяти (L40S 48 GB — FP8). При недоступности модели цепочка переходит vLLM → OpenAI → правила
автоматически, без ошибки для пользователя. Подробно — gpu/README.md.
Вход и безопасность
Интерфейс и API закрыты входом: логин/пароль из .env (APP_LOGIN, APP_PASSWORD), сессия —
подписанная HMAC-SHA256 cookie (HttpOnly, SameSite=Strict, 12 ч). Защита от перебора: 5 попыток
в минуту с IP. Заголовки X-Frame-Options: DENY, nosniff. Документация API скрыта при включённом входе.
Доступ для команды в локальной сети: cd frontend && npm run serve:lan — наружу открыт только порт 5180
(собранная минифицированная версия без исходников и source maps); API на 127.0.0.1:8010 доступен только через прокси и только после входа.
Для проверки экспертами: в .env.example и docker-compose.yml — expert / infinity-demo.
Пустой APP_PASSWORD отключает вход (локальная разработка, тесты). Пароль ClickHouse — только в .env.
Параметры окружения (.env)
| Переменная | По умолчанию | Смысл |
|---|---|---|
USE_MOCK_LLM | true | сохранённые/шаблонные ответы LLM, ключ не нужен |
OPENAI_API_KEY | пусто | ключ OpenAI (только для живого LLM) |
LLM_BASE_URL | пусто | OpenAI-совместимый endpoint (vLLM на NVIDIA Brev), напр. http://localhost:8001/v1 |
LLM_PROVIDER | auto | vllm / openai / mock; auto = vLLM → OpenAI → mock, при сбое переход к следующему |
VLLM_MODEL | qwen | имя модели на vLLM (Qwen3.8-27B) |
OPENAI_MODEL_FAST / _STRONG | gpt-4o-mini / gpt-4o | маршрутизация: сводки / диалог |
LLM_MAX_TOKENS | 600 | лимит вывода |
DB_BACKEND | sqlite | clickhouse или sqlite; если ClickHouse недоступен — автоматически SQLite |
CLICKHOUSE_* | см. .env.example | подключение к ClickHouse |
WEATHER_OFFLINE | true | true = только кеш data/cache, без сети |
APP_LOGIN / APP_PASSWORD | expert / infinity-demo (пример) | вход в интерфейс; пустой пароль — без входа |
APP_SECRET | случайный | ключ подписи сессий |
SOURCE_UTC_OFFSET | 5 | часовой пояс исходных CSV (проверено корреляцией с Open-Meteo) |
Проверка основного сценария
После запуска открыть http://localhost:5180 (или :3000 в Docker), войти expert / infinity-demo.
- Прогноз: выпуск
31.01→ почасовой прогноз на 48 ч, факт (январь), ключевые числа, погода, уведомления агента. Переключить «Доступно тогда» — факт скрывается: видно только то, что было известно на момент выпуска. - Исторический прогон: «Продолжить» — система последовательно воспроизводит выпуски 31.01 → 27.02, для каждого показаны шаги цикла, отличие от прошлого выпуска и решения агента (например, 25.02: пересчёт, ветер изменился на 2,4 м/с при пороге 1,5 м/с).
- Данные и источники: что загружено и откуда, аномалии в истории, сверка данных.
Точность на январе — в разделе «Результаты» ниже и в
outputs/metrics.json(лучше «как вчера» на 62 % / 51 %). - Агент: «Прогноз на 12.02», «прогназ на завтро скок будет» (опечатки), «какой день в феврале лучший для ремонта»;
прикрепить
examples/agent_docs/01_reglament_dispetchera.docxи спросить про пороги регламента; выгрузить ответ в Word/Excel. Список проверочных вопросов —examples/agent_questions.md. - Пересчёт: кнопка «Пересчитать выпуск» в сайдбаре или
python -m app.cli forecast 2026-02-10 --force.
Готовые результаты: outputs/forecasts.csv, outputs/forecasts_test_period.csv (выпуски 31.01–27.02), outputs/metrics.json,
outputs/experiments.json.
Тесты
После обновления правил агрегации факта нужно пересчитать сохранённые выпуски:
cd backend && python -m app.cli backtest --force, затем перезапустить API.
Команда переобучает модели и обновляет выгрузки; старые запуски в БД сохраняются.
Обычный ensure не пересчитывает уже заполненное хранилище.
Факт часа использует только шесть уникальных валидных 10-минутных точек
центрированного окна [H−30 мин, H+30 мин). Факт станции требует обе турбины.
Неполные часы не подменяются нулями и не участвуют в оценке.
cd backend && pytest -q # 20 тестов, без сети и ключей (SQLite + кеш погоды)
Проверяют: отсутствие утечки будущего (все прогоны погоды выпущены до момента прогноза, модель не обучена на данных позже выпуска), UTC-конвертацию и флаг простоя, монотонность кривой мощности, метрики, API (валидация входа, агентный цикл, пропуск пересчёта без изменений, SSE-диалог в mock-режиме), справочник объектов.
Проверка без API-ключей
USE_MOCK_LLM=true (по умолчанию). Прогноз от LLM не зависит; сводки и ответы чата строятся
правилами по тем же инструментам агента на реальных данных (понимает опечатки, «завтра/вчера», казахский). Погода берётся из data/cache (в Docker
WEATHER_OFFLINE=true), поэтому сеть тоже не нужна.
Результаты (январский бэктест, выпуски 01.01–30.01.2026)
| Объект | Горизонт | MAE | RMSE | MAE персистентности | Skill |
|---|---|---|---|---|---|
| Станция | 1–24 ч | 0.145 | 0.194 | 0.385 | +62% |
| Станция | 25–48 ч | 0.170 | 0.228 | 0.343 | +51% |
| T1 | 1–24 ч / 25–48 ч | 0.152 / 0.174 | +61% / +50% | ||
| T2 | 1–24 ч / 25–48 ч | 0.144 / 0.171 | +63% / +49% |
MAE — в долях номинальной мощности. Факт по февралю организаторы не предоставили (данные до 31.01.2026 23:50), поэтому февральские выпуски — прогноз без оценки.
Таблица доказательств (что улучшает прогноз, а что нет)
python -m app.cli experiments → outputs/experiments.json, страница «Аналитика». Январь 2026, одинаковые
условия: обучение только до выпуска, переобучение раз в 7 суток, архивные прогнозы погоды. MAE станции (доля Pном):
| Вариант | 1–24 ч | 25–48 ч | Решение |
|---|---|---|---|
| Кривая мощности по прогнозному ветру 100 м | 0,149 | 0,170 | база модели |
| + бустинг остатков | 0,145 | 0,170 | в работе |
| + погодный контекст ±1–3 ч (Landry et al., 2016, GEFCom2014) | 0,155 | 0,183 | отклонено: хуже |
| Analog Ensemble — среднее факта 8 похожих дней (Alessandrini et al., 2015) | 0,210 | 0,224 | как прогноз — отклонено |
| Смесь 0,7 × бустинг + 0,3 × аналоги | 0,166 | 0,189 | отклонено: хуже |
Персистентность «как вчера»: 0,385 / 0,343. Гипотезы из литературы проверены, а не перенесены на веру.
Диапазон прогноза Q10–Q90 — квантильный бустинг остатков (Landry et al., 2016). На январе в диапазон
попало 78 % фактов на горизонте 1–24 ч и 74 % на 25–48 ч при цели 80 % (станция; ширина ≈ 2,2–2,5 МВт).
Диапазон станции — среднее квантилей турбин: ошибки турбин почти полностью коррелированы общей погодой.
Аналоги оставлены там, где они полезны: память агента (/api/analogs, инструмент find_analogs) —
похожие прошлые дни по 48-часовому прогнозу погоды (только до даты выпуска), их фактическая выработка
и разброс Q10–Q90, чтобы объяснить, насколько можно доверять текущему прогнозу.
Вклад команды: модель дата-инженера (contrib/wind_hackathon_handoff/)
Отдельный пакет коллеги по команде: прогноз с 10-минутной детализацией (288 точек на 48 ч) и
часовыми агрегатами, физическая кривая по паспорту + residual HistGradientBoostingRegressor,
обучение только по полным часам (6 валидных 10-минуток), CLI train / predict / replay, DDL таблиц
wind_objects, wind_actuals, wind_actuals_gaps, wind_weather_forecasts, wind_power_forecasts.
Вторая версия пакета добавляет загрузчик архивных прогнозов погоды (Open-Meteo, опционально NOAA GFS через eccodes),
агентный workflow, миграцию схемы wind_hackathon_upgrade.sql.
Тесты: cd contrib/wind_hackathon_handoff && python -m unittest discover -s backend/tests -t . (18 тестов).
Основной сервис (backend/) использует те же таблицы данных; модель пакета — альтернативный
вариант с 10-минутной детализацией. backend/app/config.py пакета взят из инфраструктуры проекта
KEGOC (переиспользование конфигурации, не решения задачи). Пароли — только в [скрыто] (не в git).
Использованные внешние материалы
- Данные: исторические CSV организаторов HackAlem AI (две турбины, 10-минутный шаг); выгрузки
wind_actuals,wind_actuals_gapsи справочникwind_objectsподготовлены дата-инженером команды; паспорт станции — Samruk-Green Energy, ВЭС «Нурлы». - Погода: Open-Meteo Previous Model Runs API (CC BY 4.0), без ключа; ответы закешированы в
data/cache. - Карта: спутниковые тайлы Esri World Imagery, схема CARTO Voyager / © OpenStreetMap (ODbL); Leaflet (BSD-2), three.js (MIT).
- LLM (опционально): Qwen/Qwen3.8-27B (Apache 2.0) через vLLM на NVIDIA H200 (Brev) —
gpu/README.md; OpenAI API как резерв. Без ключей агент работает по правилам. - Методы из литературы (проверены на наших данных, см. таблицу доказательств): Landry et al., 2016 (GEFCom2014, квантильный бустинг и погодный контекст), Alessandrini et al., 2015 (Analog Ensemble).
- Переиспользование:
contrib/wind_hackathon_handoff/backend/app/config.py— конфигурация из инфраструктуры проекта KEGOC (не решение задачи). Остальной код написан в рамках соревновательной части. - Библиотеки: полный список с версиями —
backend/requirements.txt,frontend/package.json. - AI-инструменты разработки: Claude Code, Codex.
- Учебные документы в
examples/agent_docs/созданы командой для проверки агента и не являются документами организаций.
Известные ограничения
- Архив Open-Meteo previous runs доступен с 16.02.2024 — обучение на 2024-02…2026-01.
- Обе турбины попадают в одну ячейку сетки метеомодели — погодный ряд общий.
- Время в CSV интерпретируется как UTC+5 (подтверждено корреляцией с погодой; скачка в марте 2024 нет).
- Час факта — среднее 10-минутных значений в окне [H−30, H+30) мин; учитываются только полные часы из 6 валидных точек (неполные часы не заменяются нулём); факт станции — только при валидном факте обеих турбин.
- Факта за февраль нет: точность оценивается на январе, февраль — прогноз без оценки.
- Без LLM ответы агента строятся правилами (шаблонный текст); тексты уведомлений — на русском.
Потенциал развития
Кластер ClickHouse для сотен станций; ансамбль метеомоделей (ICON/GFS/ECMWF) и совместные сценарии для диапазона станции; модели по ветровым режимам; нейросетевой соперник (N-HiTS/TFT); self-hosted LLM на NVIDIA GPU как стандартный режим.
Почасовой прогресс
- 13–14: разбор ТЗ; данные (часовой пояс UTC+5 проверен корреляцией с погодой); архив прогнозов погоды без утечки будущего; модель «кривая мощности + бустинг остатков»; агент прогноза с политикой пересчёта; FastAPI, ClickHouse/SQLite; первый UI; Docker.
- 14–15: тесты (утечка будущего, данные, модель, API); LLM Qwen3.8 на NVIDIA H200; таблицы дата-инженера
wind_objects,wind_actuals; страница прогноза (ключевые числа, график/таблица); карта и 3D; машина времени; паспорт станции в README. - 15–16: отдельные страницы; уведомления агента по ΔP; база знаний на эмбеддингах; вход в систему; сверка данных дата-инженера;
пакет дата-инженера в
contrib/; агент: три режима, память диалога, опечатки, вложения документов, выгрузка в Word/Excel. - 16–17: страница агента как ChatGPT; проверка запуска с нуля по README; память агента (Analog Ensemble); таблица доказательств (погодный контекст и аналоги проверены и отклонены как прогноз); диапазон 80 % с проверкой покрытия; сводка за период; страница «Исторический прогон»; упрощение интерфейса; русский/казахский.
- 17–18: финальная проверка запуска с нуля на чистой копии, актуализация README.
Авторы коммитов
История коммитов
- 2026-09-23 17:41Исторический прогон с 01.01.2026: шкала выпусков охватывает январь (с фактом) и февральNurlan Dyussembekov
- 2026-09-23 17:41Исправлен запуск в Docker на пустой базе ClickHouse: миграции колонок диапазона после создания таблиц; при ошибке ClickHouse — переход на SQLite вместо паденияNurlan Dyussembekov
- 2026-09-23 17:38README: режимы LLM агента — правила по умолчанию, OpenAI API, Qwen3.8 на NVIDIA H200 (Brev) и автоматический переход между нимиNurlan Dyussembekov
- 2026-09-23 17:37Итог: бэктест пересчитан по правилу полных часов, метрики в README обновлены; вход и быстрая проверка для жюри (Windows/Linux/macOS) в README; убраны дубли на странице прогноза и лишнее на странице даNurlan Dyussembekov
- 2026-09-23 17:35Fix incomplete hourly actuals and forecast completion checksNurlan Dyussembekov
- 2026-09-23 17:26«Данные и источники» короче и понятнее: простые названия проверок и источников, производитель турбин вместо кода моделиNurlan Dyussembekov
- 2026-09-23 17:23Автоматический ИИ-анализ выпуска на странице прогноза (/api/insight, кеш LLM, запасной вариант по правилам); README: страница «Данные и источники»Nurlan Dyussembekov
- 2026-09-23 17:22Страница «Данные и источники» вместо «Аналитики»: параметры турбин, реестр источников (история, архив Open-Meteo, справочник, пропуски, февраль), аномалии в истории, таблицы ClickHouse, пропуски по меNurlan Dyussembekov
Все коммиты (45)
- 2026-09-23 17:21Ключевые числа без подписей, формулы во всплывающей подсказке, время пика; ветер и температура на графике по умолчанию; API источников данных и аномалий в историиNurlan Dyussembekov
- 2026-09-23 17:06README под итоговую версию: страницы интерфейса, проверка основного сценария по шагам, технологии, внешние материалы, ограничения, почасовой прогресс по истории коммитовNurlan Dyussembekov
- 2026-09-23 16:57Прогноз: убрана строка статуса (проверки, покрытие погоды, изменение к прошлому выпуску)Nurlan Dyussembekov
- 2026-09-23 16:56Агент: убрана пояснительная строка у похожих дней; «Q10–Q90» в интерфейсе заменено на понятное «диапазон»Nurlan Dyussembekov
- 2026-09-23 16:56Интерфейс полностью на русском и казахском; подписи температуры видны и в февралеNurlan Dyussembekov
- 2026-09-23 16:52Аналитика: компактная раскладка в две колонки без пустых зон, короткие подписи вместо абзацевNurlan Dyussembekov
- 2026-09-23 16:51Прогноз без лишнего: справа только уведомления и строка статуса, таблица по часам свёрнута; агент: автоповтор при обрыве и кнопка «Повторить»Nurlan Dyussembekov
- 2026-09-23 16:48Страница прогноза по второму макету и разгрузка графика; агент: связь не рвётся на долгих ответахNurlan Dyussembekov
- 2026-09-23 16:34Страница «Исторический прогон»: воспроизведение февраля по дням на реальных данных; логотип-турбина в сайдбареNurlan Dyussembekov
- 2026-09-23 16:31Агент: сводка за период одним вызовом вместо перебора дат, итоговый ответ при исчерпании шагов; длинные списки шагов свёрнутыNurlan Dyussembekov
- 2026-09-23 16:29Диапазон прогноза Q10–Q90 (квантильный бустинг) с проверкой покрытия на январе: 78 % / 75 % при цели 80 %Nurlan Dyussembekov
- 2026-09-23 16:23Таблица доказательств и память агента в интерфейсе; погодный контекст ±1–3 ч проверен и отклонёнNurlan Dyussembekov
- 2026-09-23 16:20Память агента: поиск похожих ситуаций (Analog Ensemble) — /api/analogs и инструмент find_analogsNurlan Dyussembekov
- 2026-09-23 16:16README: запуск у себя за 3 минуты (проверено на чистой копии), живая лента агента на странице «Агент»Nurlan Dyussembekov
- 2026-09-23 16:07Доступ команде по локальной сети: собранная версия на 0.0.0.0:5180, API только через прокси со входом; агент: названная дата — дата выпуска, ответ на языке вопросаNurlan Dyussembekov
- 2026-09-23 16:02contrib: вторая версия пакета дата-инженера — загрузчик погодного архива, агентный workflow, миграция схемы (18 тестов)Nurlan Dyussembekov
- 2026-09-23 16:00Страница агента как ChatGPT, ответы с разметкой, компактный цикл агента; таблицы и жирный в Word/ExcelNurlan Dyussembekov
- 2026-09-23 15:54Набор проверки агента: 22 вопроса от простых к сложным и 5 учебных документов (docx, xlsx, csv, pdf, png)Nurlan Dyussembekov
- 2026-09-23 15:53Чат: вложения документов (docx, doc, pdf, xlsx, csv, jpg, png) и выгрузка ответа агента в Word и Excel с графиками; уведомления без служебных записейNurlan Dyussembekov
- 2026-09-23 15:50Агент: три режима (быстрый/средний/думающий), память диалога, контекст экрана, понимание опечаток; без mock-меток и демо-объектовNurlan Dyussembekov
- 2026-09-23 15:41График прогноза: убран коридор ±MAE (непонятная заливка)Nurlan Dyussembekov
- 2026-09-23 15:39Модель дата-инженера в contrib/wind_hackathon_handoff: 10-минутный прогноз, DDL таблиц, CLI, 10 тестовNurlan Dyussembekov
- 2026-09-23 15:35Вход в систему, сверка данных дата-инженера, реалистичные турбины, паспорт объекта на картеNurlan Dyussembekov
- 2026-09-23 15:21База знаний агента с эмбеддингами, настройка агента, ветер в 3DNurlan Dyussembekov
- 2026-09-23 15:18Уведомления агента вместо событий и выводов, карта со спутником, небо и подстанция в 3DNurlan Dyussembekov
- 2026-09-23 15:06Отдельные страницы: Прогноз, Карта и 3D, Аналитика, Агент; график по образцу; ландшафт в 3DNurlan Dyussembekov
- 2026-09-23 14:54README: паспорт ВЭС «Нурлы» и турбин Goldwind GW109/2500Nurlan Dyussembekov
- 2026-09-23 14:53Машина времени: паспорт выпуска, режим «Доступно тогда / Факт для оценки», сравнение с прошлым выпускомNurlan Dyussembekov
- 2026-09-23 14:51Карта и 3D-сцена турбин, новый график, погода цифрами под графикомNurlan Dyussembekov
- 2026-09-23 14:42Страница «AI Прогноз»: ключевые числа, дерево, график/таблица, погода Open-Meteo, качество данных, два языка и темыNurlan Dyussembekov
- 2026-09-23 14:18Факт из таблицы wind_actuals в ClickHouse, паспорт турбин, выработка в МВт·чNurlan Dyussembekov
- 2026-09-23 14:15Тесты: утечка будущего, данные, модель, API и агент (20 тестов)Nurlan Dyussembekov
- 2026-09-23 14:08Скрипт LLM сам выбирает полную или FP8-версию модели по объёму видеопамятиNurlan Dyussembekov
- 2026-09-23 14:02LLM агента на GPU: Qwen3.8-27B в FP8 через vLLM на L40SNurlan Dyussembekov
- 2026-09-23 14:00Живой интерфейс и понятный чат с агентомNurlan Dyussembekov
- 2026-09-23 13:57Новый интерфейс пульта диспетчера и справочник объектовNurlan Dyussembekov
- 2026-09-23 13:46Рабочий прототип: прогноз выработки ВЭС на 48 часов с агентомNurlan Dyussembekov
Структура репозитория (199 файлов)
.dockerignore .env.example .gitignore README.md backend/Dockerfile backend/app/__init__.py backend/app/api/__init__.py backend/app/api/deps.py backend/app/api/router.py backend/app/api/routes/__init__.py backend/app/api/routes/agent.py backend/app/api/routes/auth.py backend/app/api/routes/forecasts.py backend/app/api/routes/health.py backend/app/api/routes/metrics.py backend/app/cli.py backend/app/core/__init__.py backend/app/core/auth.py backend/app/core/config.py backend/app/core/logging.py backend/app/db/__init__.py backend/app/db/base.py backend/app/db/clickhouse.py backend/app/db/factory.py backend/app/db/sqlite.py backend/app/main.py backend/app/ml/__init__.py backend/app/ml/data.py backend/app/ml/experiments.py backend/app/ml/features.py backend/app/ml/metrics.py backend/app/ml/model.py backend/app/ml/pipeline.py backend/app/ml/weather.py backend/app/schemas/__init__.py backend/app/schemas/agent.py backend/app/schemas/forecast.py backend/app/schemas/metrics.py backend/app/services/__init__.py backend/app/services/agent.py backend/app/services/alerts.py backend/app/services/analogs.py backend/app/services/anomalies.py backend/app/services/chat.py backend/app/services/export.py backend/app/services/files.py backend/app/services/knowledge.py backend/app/services/llm.py backend/app/services/quality.py backend/app/services/reports.py backend/pytest.ini backend/requirements.txt backend/tests/conftest.py backend/tests/test_api.py backend/tests/test_auth.py backend/tests/test_data.py backend/tests/test_model.py backend/tests/test_no_leakage.py contrib/wind_hackathon_handoff/.env.wind.example contrib/wind_hackathon_handoff/.gitignore contrib/wind_hackathon_handoff/MANIFEST.json contrib/wind_hackathon_handoff/PROMPT_FOR_CODEX.md contrib/wind_hackathon_handoff/README.md contrib/wind_hackathon_handoff/backend/__init__.py contrib/wind_hackathon_handoff/backend/app/__init__.py contrib/wind_hackathon_handoff/backend/app/clickhouse.py contrib/wind_hackathon_handoff/backend/app/config.py contrib/wind_hackathon_handoff/backend/app/forecasting/__init__.py contrib/wind_hackathon_handoff/backend/app/forecasting/wind_hackathon.py contrib/wind_hackathon_handoff/backend/app/forecasting/wind_hackathon_agent.py contrib/wind_hackathon_handoff/backend/app/forecasting/wind_hackathon_io.py contrib/wind_hackathon_handoff/backend/app/forecasting/wind_hackathon_workflow.py contrib/wind_hackathon_handoff/backend/app/forecasting/wind_noaa_archive.py contrib/wind_hackathon_handoff/backend/app/forecasting/wind_weather_archive.py contrib/wind_hackathon_handoff/backend/requirements-wind-noaa.txt contrib/wind_hackathon_handoff/backend/requirements-wind.txt contrib/wind_hackathon_handoff/backend/scripts/__init__.py contrib/wind_hackathon_handoff/backend/scripts/run_wind_hackathon.py contrib/wind_hackathon_handoff/backend/tests/__init__.py contrib/wind_hackathon_handoff/backend/tests/test_wind_hackathon.py contrib/wind_hackathon_handoff/backend/tests/test_wind_hackathon_agent.py contrib/wind_hackathon_handoff/data/wind_objects.csv contrib/wind_hackathon_handoff/db/clickhouse/wind_hackathon.sql contrib/wind_hackathon_handoff/db/clickhouse/wind_hackathon_upgrade.sql contrib/wind_hackathon_handoff/db/clickhouse/wind_objects_seed.sql contrib/wind_hackathon_handoff/docs/WIND_HACKATHON.md contrib/wind_hackathon_handoff/requirements.txt data/cache/prevruns_43.6442_78.5372_2023-03-01_2023-03-31.json data/cache/prevruns_43.6442_78.5372_2023-04-01_2023-04-30.json data/cache/prevruns_43.6442_78.5372_2023-05-01_2023-05-31.json data/cache/prevruns_43.6442_78.5372_2023-06-01_2023-06-30.json data/cache/prevruns_43.6442_78.5372_2023-07-01_2023-07-31.json data/cache/prevruns_43.6442_78.5372_2023-08-01_2023-08-31.json data/cache/prevruns_43.6442_78.5372_2023-09-01_2023-09-30.json data/cache/prevruns_43.6442_78.5372_2023-10-01_2023-10-31.json data/cache/prevruns_43.6442_78.5372_2023-11-01_2023-11-30.json data/cache/prevruns_43.6442_78.5372_2023-12-01_2023-12-31.json data/cache/prevruns_43.6442_78.5372_2024-01-01_2024-01-31.json data/cache/prevruns_43.6442_78.5372_2024-02-01_2024-02-29.json data/cache/prevruns_43.6442_78.5372_2024-03-01_2024-03-31.json data/cache/prevruns_43.6442_78.5372_2024-04-01_2024-04-30.json data/cache/prevruns_43.6442_78.5372_2024-05-01_2024-05-31.json data/cache/prevruns_43.6442_78.5372_2024-06-01_2024-06-30.json data/cache/prevruns_43.6442_78.5372_2024-07-01_2024-07-31.json data/cache/prevruns_43.6442_78.5372_2024-08-01_2024-08-31.json data/cache/prevruns_43.6442_78.5372_2024-09-01_2024-09-30.json data/cache/prevruns_43.6442_78.5372_2024-10-01_2024-10-31.json data/cache/prevruns_43.6442_78.5372_2024-11-01_2024-11-30.json data/cache/prevruns_43.6442_78.5372_2024-12-01_2024-12-31.json data/cache/prevruns_43.6442_78.5372_2025-01-01_2025-01-31.json data/cache/prevruns_43.6442_78.5372_2025-02-01_2025-02-28.json data/cache/prevruns_43.6442_78.5372_2025-03-01_2025-03-31.json data/cache/prevruns_43.6442_78.5372_2025-04-01_2025-04-30.json data/cache/prevruns_43.6442_78.5372_2025-05-01_2025-05-31.json data/cache/prevruns_43.6442_78.5372_2025-06-01_2025-06-30.json data/cache/prevruns_43.6442_78.5372_2025-07-01_2025-07-31.json data/cache/prevruns_43.6442_78.5372_2025-08-01_2025-08-31.json data/cache/prevruns_43.6442_78.5372_2025-09-01_2025-09-30.json data/cache/prevruns_43.6442_78.5372_2025-10-01_2025-10-31.json data/cache/prevruns_43.6442_78.5372_2025-11-01_2025-11-30.json data/cache/prevruns_43.6442_78.5372_2025-12-01_2025-12-31.json data/cache/prevruns_43.6442_78.5372_2026-01-01_2026-01-31.json data/cache/prevruns_43.6442_78.5372_2026-02-01_2026-02-28.json data/cache/prevruns_43.6442_78.5372_2026-03-01_2026-03-31.json data/raw/turbine1.csv data/raw/turbine2.csv data/raw/wind_actuals.csv data/raw/wind_actuals_gaps.csv docker-compose.yml examples/agent_docs/01_reglament_dispetchera.docx examples/agent_docs/02_grafik_remontov_fevral.xlsx examples/agent_docs/03_zayavka_plan_06_02.csv examples/agent_docs/04_akt_osmotra_T2.pdf examples/agent_docs/05_grafik_20_02.png examples/agent_questions.md frontend/.dockerignore frontend/.gitignore frontend/.oxlintrc.json frontend/Dockerfile frontend/index.html frontend/nginx.conf frontend/package-lock.json frontend/package.json frontend/public/favicon.svg frontend/src/App.tsx frontend/src/api/client.ts frontend/src/api/types.ts frontend/src/components/layout/FilterBar.tsx frontend/src/components/layout/Sidebar.tsx frontend/src/components/layout/TopBar.tsx frontend/src/components/ui/Panel.tsx frontend/src/components/ui/Segmented.tsx frontend/src/features/AgentWidget.tsx frontend/src/features/AlertsPanel.tsx frontend/src/features/AnalogsPanel.tsx frontend/src/features/ChartPanel.tsx frontend/src/features/ChatView.tsx frontend/src/features/DailyErrorPanel.tsx frontend/src/features/DataReconcile.tsx frontend/src/features/ForecastSide.tsx frontend/src/features/KpiStrip.tsx frontend/src/features/Markdown.tsx frontend/src/features/MiniTurbine.tsx frontend/src/features/PassportCard.tsx frontend/src/features/PipelineRail.tsx frontend/src/features/PowerCurvePanel.tsx frontend/src/features/QualityPanel.tsx frontend/src/features/SiteMap.tsx frontend/src/features/TestPeriodPanel.tsx frontend/src/hooks/useAgentStream.ts frontend/src/hooks/useAsync.ts frontend/src/hooks/useCountUp.ts frontend/src/index.css frontend/src/lib/calc.ts frontend/src/lib/ctx.ts frontend/src/lib/format.ts frontend/src/lib/i18n.ts frontend/src/lib/prefs.ts frontend/src/lib/router.ts frontend/src/lib/theme.ts frontend/src/lib/turbine3d.ts frontend/src/main.tsx frontend/src/pages/AgentPage.tsx frontend/src/pages/DataPage.tsx frontend/src/pages/ForecastPage.tsx frontend/src/pages/LoginPage.tsx frontend/src/pages/MapPage.tsx frontend/src/pages/ReplayPage.tsx frontend/tests/calc.test.mjs frontend/tsconfig.app.json frontend/tsconfig.json frontend/tsconfig.node.json frontend/vite.config.ts gpu/README.md gpu/serve_vllm.sh outputs/experiments.json outputs/forecasts.csv outputs/forecasts_test_period.csv outputs/metrics.json
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.