О проекте
Команда: Во имя Омниссии!
Кейс HackAlem.ai: Энергетика — Самрук-Казына
Стадия: Доведённый продукт
Задача кейса: AI-агент, прогнозирующий выработку ветровой электростанции по погодным данным
Суть
Агентная система почасового прогноза выработки двух ветротурбин на D+1/D+2 с интервалом P10–P90, предупреждениями (обледенение, резкий спад), журналом шагов агента, отчётом для диспетчера и чатом. Честный backtest февраля 2026: 54 цикла агента.
Как устроено
ML-сервис на FastAPI берёт архивные прогнозы ECMWF/GFS/ICON (Open-Meteo Previous/Single Runs), опубликованные до момента выпуска, строит признаки и прогоняет LightGBM (среднее и квантили P10/P50/P90) плюс изотоническую кривую мощности. Бэкенд на Kotlin/Spring Boot выполняет 6-шаговый цикл агента: погода → ML с ретраями → валидация (48 ч, 0..1, внутри P10–P90, погода не из будущего) → сравнение с выпуском D−1 → отчёт LLM с самопроверкой чисел (иначе шаблон) → сохранение. Чат через Spring AI tool calling к локальной qwen3:8b в Ollama; LLM только пересказывает готовые данные.
Ключевые решения
- LightGBM quantile regression P10/P50/P90
- isotonic power curve (scikit-learn)
- Spring AI tool calling
- LLM self-check отчёта
- leakage-safe backtest по времени выпуска погоды
- ансамбль NWP ECMWF+GFS+ICON
Метрики
Holdout январь 2026, D+1: MAE 17.3% (t1) / 18.2% (t2) номинала, RMSE 23.6/24.8%, покрытие P10–P90 83.9/82.5%; бейзлайны 35.9% и 24.2–24.9%; D+2 MAE 17.8/18.5%; 54/54 успешных цикла backtest
Особенности
Строгая защита от утечки: время выпуска погоды (weatherIssuedAt) в каждом ответе и проверка, что оно раньше прогноза; LLM-отчёт проходит программную самопроверку всех чисел и времён, при провале заменяется шаблоном. Полностью локальный LLM без API-ключей, режим запуска без LLM.
Стек
Kotlin · Spring Boot · Spring AI · Python · FastAPI · LightGBM · React · TypeScript · Vite · Recharts · Leaflet · Docker Compose · nginx · Ollama
Модели
qwen3:8b (Ollama)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-cb6a2678-team.
README
README.mdAgentic AI для прогноза выработки ВЭС
Команда «Во имя Омниссии!», HackAlem AI, кейс «Agentic AI для прогнозирования выработки ВЭС».
Система сама строит почасовой прогноз выработки ветроэлектростанции из двух турбин на следующие 24–48 часов: берёт архивный прогноз погоды, известный на момент прогноза, прогоняет ML-модель, проверяет результат, сравнивает с предыдущим прогнозом и пишет отчёт для диспетчера. Каждый шаг агента виден в журнале.
Какую проблему решает и для кого
Ветроэлектростанция заранее сообщает энергосистеме, сколько электроэнергии выдаст по часам, и платит за отклонения от заявленного. Ветер изменчив, поэтому нужен точный прогноз с оценкой неопределённости и предупреждениями о рисках. Пользователь — диспетчер станции: утром он видит прогноз на завтра и послезавтра, интервал уверенности, риски (обледенение, резкий спад) и может спросить агента на естественном языке.
Что реализовано
- Прогноз выработки на сутки D+1 и D+2 от выпуска в день D в 12:00 местного времени: 48 часов, основной прогноз и интервал P10–P90, мощность в долях номинала. Обе турбины.
- Честный backtest по ТЗ: выпуски 31.01–26.02.2026 покрывают весь февраль. Каждый прогноз использует только
прогнозы погоды, опубликованные до момента выпуска; время выпуска погоды (
weatherIssuedAt) есть в каждом ответе и всегда не позже момента прогноза. Модель обучена только на данных по 31.01.2026. - Цикл агента (
POST /api/forecast/run), 6 шагов:- погода у турбины — прогон Open-Meteo, опубликованный до момента прогноза; недоступен → берётся более старый;
- прогноз ML — при сбое повтор, каждая попытка в журнале;
- проверка — 48 часов подряд, значения 0..1, прогноз внутри P10–P90, погода не из будущего; иначе прогноз отклоняется;
- сравнение с предыдущим выпуском — насколько изменился прогноз тех же суток после обновления погоды;
- отчёт для диспетчера от LLM с самопроверкой: каждое время и процент из текста должны быть в данных, иначе отчёт отклоняется и собирается по шаблону;
- сохранение — прогноз и журнал шагов в
data/cycles/.
- Журнал агента (
GET /api/agent-log): шаги, статусы, время выпуска использованных данных. - Чат с агентом (
POST /api/agent/chat): LLM сама вызывает инструменты — прогноз, версии прогноза, погода, метрики — и отвечает только по их данным. - Предупреждения: риск обледенения, штормовое отключение, резкий рост/спад выработки, расхождение погодных моделей.
- Метрики качества на отложенном тесте (январь 2026) с двумя бейзлайнами.
- Веб-интерфейс: карта турбин, график прогноза с интервалом, сводка и предупреждения, версии прогноза, журнал агента, метрики, чат.
- Результаты backtest в репозитории:
data/cycles/— циклы агента за все даты выпуска для обеих турбин, с отчётами LLM.
Результаты
Факта за февраль 2026 в выданных данных нет (датасет заканчивается 31.01.2026), поэтому точность измерена на отложенном тесте — январе 2026: отдельная модель, обученная по 31.12.2025, прогнозирует январь тем же способом (выпуск в 12:00, сутки D+1 и D+2). Ошибки — в процентах номинальной мощности, сутки D+1:
| Турбина | MAE | RMSE | Смещение | Покрытие P10–P90 | Бейзлайн «мощность как в момент прогноза» | Бейзлайн «кривая мощности без ML» |
|---|---|---|---|---|---|---|
| t1 | 17.3 % | 23.6 % | +6.0 п.п. | 83.9 % | 35.9 % | 24.2 % |
| t2 | 18.2 % | 24.8 % | +7.6 п.п. | 82.5 % | 35.9 % | 24.9 % |
На сутках D+2 MAE — 17.8 % и 18.5 %. Модель точнее бейзлайна «как в момент прогноза» примерно в 2 раза и бейзлайна «кривая мощности без ML» на 7 п.п. Подробности обучения — ML/TRAINING.md.
Backtest февраля (data/cycles/): 27 выпусков (31.01–26.02) × 2 турбины = 54 цикла агента, все успешны.
Все 54 отчёта написала LLM и прошли самопроверку; ни один прогноз не использует погоду, опубликованную позже
момента прогноза; в 26 циклах агент зафиксировал существенное изменение прогноза после обновления погоды.
Как работает решение
выпуск в день D, 12:00 местного
│
├─ ML-сервис: архивные прогнозы ECMWF + GFS + ICON (опубликованы ≤ D 12:00)
│ → признаки → LightGBM → 48 ч, P10/P50/P90 + автоматический анализ
│
├─ бэкенд-агент: погода у турбины (ECMWF IFS) → проверка → сравнение с выпуском D−1
│ → отчёт LLM с самопроверкой → сохранение
│
└─ интерфейс: график, интервал, предупреждения, журнал шагов агента, метрики, чат
Пользовательский сценарий: диспетчер выбирает дату (например, 10.02) и турбину → видит прогноз на 11 и 12 февраля с интервалом и предупреждениями → открывает журнал и видит, какие данные взял агент и когда они были опубликованы → нажимает «Пересчитать» и наблюдает шаги агента вживую → спрашивает в чате «будет ли 11 февраля риск обледенения?».
Технологии
| Часть | Технологии |
|---|---|
| Бэкенд и агент | Kotlin 2.3, Spring Boot 4.1, Spring AI 2.0 (tool calling), Jackson 3, springdoc (Swagger), Java 17 |
| LLM | Ollama, qwen3:8b — локально, без внешних API-ключей |
| ML | Python 3.12, FastAPI, LightGBM (среднее и квантили P10/P50/P90), scikit-learn (изотоническая кривая мощности), pandas |
| Фронтенд | React 19, TypeScript, Vite, Recharts, Leaflet |
| Запуск | Docker, Docker Compose, nginx |
| Разработка | AI-агенты Claude Code и Codex; контекст проекта для них — AGENTS.md |
Архитектура
Браузер ──► frontend (React, nginx :3000) ──/api──► backend (Spring Boot :8080)
├─ REST API, Swagger
├─ цикл агента и чат (Spring AI) ──► ollama :11434 (qwen3:8b)
├─ клиент погоды ──► Open-Meteo Single Runs API (+ кэш data/weather-cache)
├─ метрики (отложенный тест ML + SCADA)
└─ хранилище циклов data/cycles/
│
▼ POST /v1/forecast, GET /v1/evaluation
ML (FastAPI :8000): модели, кэш погоды Previous Runs, SCADA
- Контракт фронт ↔ бэкенд: backend/src/main/resources/static/openapi.yaml.
- Контракт бэкенд ↔ ML: contracts/ml-service.openapi.yaml.
- LLM никогда не считает числа сама: ML-модель считает прогноз, код — сводки и выводы, LLM только выбирает инструменты и пересказывает готовые данные.
- Подробно: docs/architecture.md.
Установка и запуск
Нужен Docker с Docker Compose. Docker должно быть выделено не меньше 8 ГБ памяти (Docker Desktop → Settings →
Resources): LLM qwen3:8b с контекстом занимает около 6.5 ГБ. Если памяти меньше — возьмите модель поменьше:
OLLAMA_MODEL=qwen3:4b docker compose up --build (около 3 ГБ, ответы проще).
git clone https://github.com/BAITC-Hacks/hack-cb6a2678-team.git
cd hack-cb6a2678-team
docker compose up --build
Первый запуск: сборка образов — несколько минут, загрузка LLM qwen3:8b — около 5 ГБ.
Когда сервисы поднимутся:
- интерфейс — http://localhost:3000
- API и Swagger — http://localhost:8080/swagger-ui.html
- ML-сервис — http://localhost:8000/docs
Без LLM (быстрее и без 5 ГБ): docker compose up --build ml backend frontend. Прогнозы, журналы
и отчёты из сохранённого backtest работают; чат с агентом недоступен, новые циклы пишут отчёт по шаблону.
Ollama в Docker на macOS работает только на CPU и отвечает медленно. Быстрее — нативный Ollama на хосте:
ollama serve & ollama pull qwen3:8b
OLLAMA_BASE_URL=http://host.docker.internal:11434 docker compose up --build ml backend frontend
Запуск без Docker (для разработки)
# 1. LLM
ollama serve & ollama pull qwen3:8b
# 2. ML (Python 3.12+; на macOS: brew install libomp)
cd ML && python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt && uvicorn windml.api:app --port 8000
# 3. Бэкенд (JDK 17+)
cd backend && ./gradlew bootRun
# 4. Фронтенд (Node 22+)
cd frontend && npm ci && npm run dev # http://localhost:5173
Как проверить решение
-
Прогноз и честность данных. Откройте http://localhost:3000, выберите дату 10.02 и турбину t1, или:
curl 'http://localhost:8080/api/forecast?turbineId=t1&date=2026-02-10'forecastIssuedAt=2026-02-10T07:00:00Z(12:00 местного), точки — сутки 11 и 12 февраля,weatherIssuedAtраньшеforecastIssuedAt. -
Журнал агента за этот выпуск (из сохранённого backtest):
curl 'http://localhost:8080/api/agent-log?date=2026-02-10&turbineId=t1' -
Цикл агента вживую: кнопка «Пересчитать» в интерфейсе или
curl -X POST http://localhost:8080/api/forecast/run -H 'Content-Type: application/json' \ -d '{"turbineId":"t2","date":"2026-02-14"}' # повторять, пока status = running: curl 'http://localhost:8080/api/agent-log?date=2026-02-14&turbineId=t2' -
Метрики:
curl http://localhost:8080/api/metrics— таблица из раздела «Результаты». -
Чат с агентом (нужна LLM):
curl -X POST http://localhost:8080/api/agent/chat -H 'Content-Type: application/json' \ -d '{"message":"Какая ожидается выработка t1 на 11 февраля 2026? Есть ли риск обледенения?"}'В ответе — текст и
toolCalls: какие инструменты вызвал агент. -
Повторить весь backtest (нужны запущенные сервисы; ~10 минут с LLM):
python3 scripts/backtest.py -
Тесты:
cd backend && ./gradlew test(без сети, ML и LLM);cd ML && python -m pytest tests.
Данные и интеграции
| Источник | Для чего |
|---|---|
Датасет организаторов: SCADA двух турбин, 10-минутные данные 11.03.2023–31.01.2026 (ML/data/raw/) | Обучение модели, факт для метрик и бейзлайна |
| Координаты турбин из ТЗ: t1 43.645150, 78.535604; t2 43.643198, 78.538828 | Погода, карта |
Open-Meteo Previous Runs API: архивные прогнозы ECMWF IFS 0.25°, GFS, ICON (кэш в ML/data/cache/) | Вход ML-модели. Режим strict: для суток D+k берётся прогноз, сделанный не менее чем за k+1 суток |
Open-Meteo Single Runs API: конкретные прогоны ECMWF IFS HRES 9 км (кэш в data/weather-cache/) | Погода у турбины для агента: предупреждения, чат. Берётся последний прогон, опубликованный до момента прогноза (задержка публикации — 7 ч с запасом) |
Ollama, qwen3:8b | LLM агента (локально) |
Всё, что нужно для воспроизведения, лежит в репозитории: модели, кэши погоды, датасет, результаты backtest. API-ключи не нужны.
Ограничения
- Факта за февраль 2026 нет в данных, поэтому точность февральских прогнозов мы проверить не можем — она оценена на отложенном январе.
- Модель в среднем завышает выработку на 6–8 п.п. номинала; калибровка на декабре уменьшила смещение, но не убрала.
- Версии прогноза — раз в сутки. Архив Previous Runs хранит прогнозы с шагом в сутки заблаговременности, поэтому внутридневные пересчёты по каждому прогону погоды не сделаны; «повторный расчёт при обновлении данных» — это прогноз тех же суток из следующего выпуска.
- Два источника погоды: ML обучена на ансамбле Previous Runs, агент для предупреждений использует прогоны ECMWF HRES — ветер и температура в них могут немного отличаться.
- Часовой пояс SCADA организаторы не указали; ML выбрала UTC+5 по ошибке на валидации (ноябрь–декабрь 2025).
- Турбины в 300 м друг от друга попадают в одну ячейку погодных моделей — погода для них одинаковая.
- LLM в Docker требует ~6.5 ГБ памяти; при нехватке процесс модели убивается — чат отвечает 503, а циклы агента пишут отчёт по шаблону (прогнозы, журналы и сохранённый backtest работают без LLM).
- LLM локальная и небольшая (8B): отчёты фактически точные (самопроверка), но стилистически простые; ответы в чате — 5–60 секунд, в Docker на macOS дольше.
- Предупреждение об обледенении — эвристика по температуре и влажности, без данных о подогреве лопастей.
- Установленная мощность турбин неизвестна, поэтому прогноз — в долях номинала, а не в МВт·ч.
Развёрнутая версия
Нет — проект запускается локально одной командой docker compose up --build.
Документация
- docs/overview.md — продукт простыми словами
- docs/architecture.md — архитектура, цикл агента, защита от утечки данных
- docs/task.md — ТЗ и критерии
- docs/ — остальное: бэкенд, ML, фронтенд, план
Авторы коммитов
История коммитов
- 2026-09-23 17:59FIX: LLM fits into 8 GB Docker memory; LLM failures return 503Kuanysh Yabekov
- 2026-09-23 17:47UPD: archive finished plans, refresh AGENTS/docs, label template reports in UIKuanysh Yabekov
- 2026-09-23 17:42UPD: docs match the final system: issue/versions, January holdout, demo daysKuanysh Yabekov
- 2026-09-23 17:42ADD: jury-ready release: Docker, README, February backtest on the new modelKuanysh Yabekov
- 2026-09-23 17:42ADD: real agent cycle and agent log; remove mocksKuanysh Yabekov
- 2026-09-23 17:39ADD: guided dashboard tour and agent log contextBekzhan
- 2026-09-23 17:30FIX: Make ML packaging tests portable across platformsleonmen34
- 2026-09-23 17:15ADD: ML contract v2, offline Docker and calibrated turbine modelsleonmen34
Все коммиты (22)
- 2026-09-23 17:08FIX: Frontend for backend v1.2 contract (real ML forecast + metrics)Bekzhan
- 2026-09-23 17:03ADD: real metrics on the January holdoutKuanysh Yabekov
- 2026-09-23 16:57UPD: Frontend — v1.1 contract rework, BMW design, bento layoutBekzhan
- 2026-09-23 16:52ADD: backend <-> ML integration: real forecasts in API and agentKuanysh Yabekov
- 2026-09-23 16:36UPD: ML contract v2, ML task brief and integration plan; remove ML/spring-agentKuanysh Yabekov
- 2026-09-23 16:20ADD: ML forecasting prototype with trained models and offline dataleonmen34
- 2026-09-23 15:49ADD: getWeather agent tool with per-day conclusionsKuanysh Yabekov
- 2026-09-23 15:39ADD: Frontend, Интерактивная карта, линейный график, таймлайн, шаги, метрикиBekzhan
- 2026-09-23 15:30ADD: Weather clientKuanysh Yabekov
- 2026-09-23 15:12ADD: docs for agentsKuanysh Yabekov
- 2026-09-23 15:03ADD: overview docKuanysh Yabekov
- 2026-09-23 14:54ADD: LLM agent (Spring AI + Ollama) and API contract v1.1Kuanysh Yabekov
- 2026-09-23 14:12ADD: mock API for WES forecast (turbines, forecast, metrics, agent-log)Kuanysh Yabekov
- 2026-09-23 13:55ADD: backend module initKuanysh Yabekov
Структура репозитория (425 файлов)
.gitignore AGENTS.md CLAUDE.md ML/.dockerignore ML/.gitignore ML/Dockerfile ML/README.md ML/TRAINING.md ML/agent_example.py ML/data/cache/prev_turbine_1_ecmwf_ifs025_202312_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202401_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202402_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202403_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202404_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202405_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202406_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202407_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202408_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202409_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202410_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202411_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202412_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202501_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202502_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202503_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202504_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202505_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202506_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202507_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202508_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202509_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202510_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202511_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202512_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202601_2-3.csv ML/data/cache/prev_turbine_1_ecmwf_ifs025_202602_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202312_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202401_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202402_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202403_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202404_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202405_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202406_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202407_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202408_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202409_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202410_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202411_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202412_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202501_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202502_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202503_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202504_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202505_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202506_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202507_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202508_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202509_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202510_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202511_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202512_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202601_2-3.csv ML/data/cache/prev_turbine_1_gfs_seamless_202602_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202312_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202401_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202402_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202403_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202404_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202405_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202406_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202407_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202408_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202409_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202410_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202411_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202412_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202501_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202502_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202503_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202504_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202505_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202506_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202507_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202508_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202509_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202510_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202511_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202512_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202601_2-3.csv ML/data/cache/prev_turbine_1_icon_seamless_202602_2-3.csv ML/data/raw/turbine_1.csv ML/data/raw/turbine_2.csv ML/models/wind_model.joblib ML/models/wind_model.json ML/models/wind_model_turbine_2.joblib ML/models/wind_model_turbine_2.json ML/outputs/before_tasks/turbine_1/evaluation_model.json ML/outputs/before_tasks/turbine_1/report.json ML/outputs/before_tasks/turbine_1/test_predictions.csv ML/outputs/before_tasks/turbine_2/evaluation_model.json ML/outputs/before_tasks/turbine_2/report.json ML/outputs/before_tasks/turbine_2/test_predictions.csv ML/outputs/forecasts/forecast_2026-01-31.csv ML/outputs/forecasts/forecast_2026-01-31.json ML/outputs/integration/summary.json ML/outputs/integration/turbine_1_response.json ML/outputs/integration/turbine_2_response.json ML/outputs/selection/site_comparison_ecmwf_ifs025.json ML/outputs/selection/site_comparison_gfs_seamless.json ML/outputs/selection/site_comparison_icon_seamless.json ML/outputs/selection/timezone_comparison.json ML/outputs/selection/turbine_1_Asia_Almaty.joblib ML/outputs/selection/turbine_1_Asia_Almaty.json ML/outputs/selection/turbine_1_Asia_Almaty_validation.csv ML/outputs/selection/turbine_1_Etc_GMT-5.joblib ML/outputs/selection/turbine_1_Etc_GMT-5.json ML/outputs/selection/turbine_1_Etc_GMT-5_validation.csv ML/outputs/selection/turbine_1_Etc_GMT-6.joblib ML/outputs/selection/turbine_1_Etc_GMT-6.json ML/outputs/selection/turbine_1_Etc_GMT-6_validation.csv ML/outputs/selection/turbine_2_Asia_Almaty.joblib ML/outputs/selection/turbine_2_Asia_Almaty.json ML/outputs/selection/turbine_2_Asia_Almaty_validation.csv ML/outputs/selection/turbine_2_Etc_GMT-5.joblib ML/outputs/selection/turbine_2_Etc_GMT-5.json ML/outputs/selection/turbine_2_Etc_GMT-5_validation.csv ML/outputs/selection/turbine_2_Etc_GMT-6.joblib ML/outputs/selection/turbine_2_Etc_GMT-6.json ML/outputs/selection/turbine_2_Etc_GMT-6_validation.csv ML/outputs/selection/weather_site_comparison.json ML/outputs/task_report/metrics.md ML/outputs/task_report/summary.json ML/outputs/task_report/turbine_1_evaluation.json ML/outputs/task_report/turbine_1_february.json ML/outputs/task_report/turbine_2_evaluation.json ML/outputs/task_report/turbine_2_february.json ML/outputs/training/turbine_1/data_audit.json ML/outputs/training/turbine_1/evaluation_model.joblib ML/outputs/training/turbine_1/evaluation_model.json ML/outputs/training/turbine_1/evaluation_validation_predictions.csv ML/outputs/training/turbine_1/forecast_next_48h.csv ML/outputs/training/turbine_1/frozen_settings.json ML/outputs/training/turbine_1/previous_models/20260923T105706Z/wind_model.joblib ML/outputs/training/turbine_1/previous_models/20260923T105706Z/wind_model.json ML/outputs/training/turbine_1/previous_models/20260923T115948Z/wind_model.joblib ML/outputs/training/turbine_1/previous_models/20260923T115948Z/wind_model.json ML/outputs/training/turbine_1/production_validation_predictions.csv ML/outputs/training/turbine_1/report.json ML/outputs/training/turbine_1/test_predictions.csv ML/outputs/training/turbine_2/data_audit.json ML/outputs/training/turbine_2/evaluation_model.joblib ML/outputs/training/turbine_2/evaluation_model.json ML/outputs/training/turbine_2/evaluation_validation_predictions.csv ML/outputs/training/turbine_2/forecast_next_48h.csv ML/outputs/training/turbine_2/frozen_settings.json ML/outputs/training/turbine_2/previous_models/20260923T120013Z/wind_model_turbine_2.joblib ML/outputs/training/turbine_2/previous_models/20260923T120013Z/wind_model_turbine_2.json ML/outputs/training/turbine_2/production_validation_predictions.csv ML/outputs/training/turbine_2/report.json ML/outputs/training/turbine_2/test_predictions.csv ML/requirements-dev.txt ML/requirements.txt ML/scripts/docker_smoke.py ML/scripts/prepare_tasks_baseline.py ML/tests/test_api.py ML/tests/test_contract.py ML/tests/test_offline.py ML/tests/test_packaging.py ML/tests/test_quality.py ML/tests/test_training_integrity.py ML/tests/test_v2.py ML/windml/__init__.py ML/windml/__main__.py ML/windml/analysis.py ML/windml/api.py ML/windml/calibration.py ML/windml/cli.py ML/windml/compare_sites.py ML/windml/config.py ML/windml/data.py ML/windml/experiments.py ML/windml/features.py ML/windml/metrics.py ML/windml/model.py ML/windml/pipeline.py ML/windml/powercurve.py ML/windml/service.py ML/windml/task_report.py ML/windml/timeutils.py ML/windml/tools.py ML/windml/train_dataset.py ML/windml/weather.py README.md backend/.dockerignore backend/.gitattributes backend/.gitignore backend/Dockerfile backend/build.gradle.kts backend/gradle/wrapper/gradle-wrapper.jar backend/gradle/wrapper/gradle-wrapper.properties backend/gradlew backend/gradlew.bat backend/settings.gradle.kts backend/src/main/kotlin/com/ybkuanysh/backend/BackendApplication.kt backend/src/main/kotlin/com/ybkuanysh/backend/agent/AgentController.kt backend/src/main/kotlin/com/ybkuanysh/backend/agent/AgentService.kt backend/src/main/kotlin/com/ybkuanysh/backend/agent/AgentTools.kt backend/src/main/kotlin/com/ybkuanysh/backend/agent/AgentWeatherView.kt backend/src/main/kotlin/com/ybkuanysh/backend/api/ErrorHandler.kt backend/src/main/kotlin/com/ybkuanysh/backend/api/WesController.kt backend/src/main/kotlin/com/ybkuanysh/backend/config/WebConfig.kt backend/src/main/kotlin/com/ybkuanysh/backend/cycle/CycleModels.kt backend/src/main/kotlin/com/ybkuanysh/backend/cycle/CycleStore.kt backend/src/main/kotlin/com/ybkuanysh/backend/cycle/ForecastCycleService.kt backend/src/main/kotlin/com/ybkuanysh/backend/cycle/ReportWriter.kt backend/src/main/kotlin/com/ybkuanysh/backend/dto/Dto.kt backend/src/main/kotlin/com/ybkuanysh/backend/forecast/ForecastAnalytics.kt backend/src/main/kotlin/com/ybkuanysh/backend/forecast/ForecastService.kt backend/src/main/kotlin/com/ybkuanysh/backend/metrics/EvaluationData.kt backend/src/main/kotlin/com/ybkuanysh/backend/metrics/MetricsService.kt backend/src/main/kotlin/com/ybkuanysh/backend/ml/MlClient.kt backend/src/main/kotlin/com/ybkuanysh/backend/ml/MlModels.kt backend/src/main/kotlin/com/ybkuanysh/backend/ml/MlProperties.kt backend/src/main/kotlin/com/ybkuanysh/backend/turbine/TurbineRegistry.kt backend/src/main/kotlin/com/ybkuanysh/backend/weather/OpenMeteoClient.kt backend/src/main/kotlin/com/ybkuanysh/backend/weather/WeatherController.kt backend/src/main/kotlin/com/ybkuanysh/backend/weather/WeatherModels.kt backend/src/main/kotlin/com/ybkuanysh/backend/weather/WeatherProperties.kt backend/src/main/kotlin/com/ybkuanysh/backend/weather/WeatherService.kt backend/src/main/resources/application.yaml backend/src/main/resources/static/openapi.yaml backend/src/test/kotlin/com/ybkuanysh/backend/BackendApplicationTests.kt backend/src/test/kotlin/com/ybkuanysh/backend/agent/AgentTests.kt backend/src/test/kotlin/com/ybkuanysh/backend/agent/AgentWeatherToolTests.kt backend/src/test/kotlin/com/ybkuanysh/backend/api/WesControllerTests.kt backend/src/test/kotlin/com/ybkuanysh/backend/cycle/ForecastCycleServiceTests.kt backend/src/test/kotlin/com/ybkuanysh/backend/forecast/ForecastServiceTests.kt backend/src/test/kotlin/com/ybkuanysh/backend/metrics/MetricsServiceTests.kt backend/src/test/kotlin/com/ybkuanysh/backend/ml/MlModelsTests.kt backend/src/test/kotlin/com/ybkuanysh/backend/support/FixtureMl.kt backend/src/test/kotlin/com/ybkuanysh/backend/weather/WeatherServiceTests.kt backend/src/test/resources/config/application.yaml backend/src/test/resources/evaluation/turbine_1/test_predictions.csv backend/src/test/resources/evaluation/turbine_2/test_predictions.csv backend/src/test/resources/ml/forecast_turbine_1_2026-01-31.json backend/src/test/resources/ml/forecast_turbine_1_2026-02-03.json backend/src/test/resources/ml/forecast_turbine_1_2026-02-04.json backend/src/test/resources/ml/forecast_turbine_2_2026-01-31.json backend/src/test/resources/ml/forecast_turbine_2_2026-02-03.json backend/src/test/resources/ml/forecast_turbine_2_2026-02-04.json backend/src/test/resources/ml/forecast_v2_turbine_1_2026-02-10.json backend/src/test/resources/scada/turbine_1.csv backend/src/test/resources/scada/turbine_2.csv backend/src/test/resources/weather/ecmwf_ifs_2026-01-31T12.json contracts/ml-service.openapi.yaml data/cycles/t1/2026-01-31.json data/cycles/t1/2026-02-01.json data/cycles/t1/2026-02-02.json data/cycles/t1/2026-02-03.json data/cycles/t1/2026-02-04.json data/cycles/t1/2026-02-05.json data/cycles/t1/2026-02-06.json data/cycles/t1/2026-02-07.json data/cycles/t1/2026-02-08.json data/cycles/t1/2026-02-09.json data/cycles/t1/2026-02-10.json data/cycles/t1/2026-02-11.json data/cycles/t1/2026-02-12.json data/cycles/t1/2026-02-13.json data/cycles/t1/2026-02-14.json data/cycles/t1/2026-02-15.json data/cycles/t1/2026-02-16.json data/cycles/t1/2026-02-17.json data/cycles/t1/2026-02-18.json data/cycles/t1/2026-02-19.json data/cycles/t1/2026-02-20.json data/cycles/t1/2026-02-21.json data/cycles/t1/2026-02-22.json data/cycles/t1/2026-02-23.json data/cycles/t1/2026-02-24.json data/cycles/t1/2026-02-25.json data/cycles/t1/2026-02-26.json data/cycles/t2/2026-01-31.json data/cycles/t2/2026-02-01.json data/cycles/t2/2026-02-02.json data/cycles/t2/2026-02-03.json data/cycles/t2/2026-02-04.json data/cycles/t2/2026-02-05.json data/cycles/t2/2026-02-06.json data/cycles/t2/2026-02-07.json data/cycles/t2/2026-02-08.json data/cycles/t2/2026-02-09.json data/cycles/t2/2026-02-10.json data/cycles/t2/2026-02-11.json data/cycles/t2/2026-02-12.json data/cycles/t2/2026-02-13.json data/cycles/t2/2026-02-14.json data/cycles/t2/2026-02-15.json data/cycles/t2/2026-02-16.json data/cycles/t2/2026-02-17.json data/cycles/t2/2026-02-18.json data/cycles/t2/2026-02-19.json data/cycles/t2/2026-02-20.json data/cycles/t2/2026-02-21.json data/cycles/t2/2026-02-22.json data/cycles/t2/2026-02-23.json data/cycles/t2/2026-02-24.json data/cycles/t2/2026-02-25.json data/cycles/t2/2026-02-26.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-01-30T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-01-31T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-01T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-02T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-03T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-04T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-05T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-06T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-07T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-08T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-09T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-09T12.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-10T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-10T12.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-11T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-11T12.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-12T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-13T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-14T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-15T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-16T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-17T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-18T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-19T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-20T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-21T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-22T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-23T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-24T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-25T00.json data/weather-cache/ecmwf_ifs/43.6432_78.5388/2026-02-26T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-01-31T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-01-31T12.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-01T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-02T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-03T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-04T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-04T12.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-05T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-06T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-07T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-08T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-09T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-10T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-10T12.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-11T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-11T12.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-12T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-13T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-14T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-15T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-16T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-17T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-18T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-19T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-20T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-21T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-22T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-23T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-24T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-25T00.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-25T12.json data/weather-cache/ecmwf_ifs/43.6452_78.5356/2026-02-26T00.json docker-compose.yml docs/README.md docs/architecture.md docs/archive/README.md docs/archive/ml-integration.md docs/archive/ml-tasks.md docs/archive/ml.md docs/backend.md docs/frontend.md docs/overview.md docs/roadmap.md docs/task.md frontend/.dockerignore frontend/.gitignore frontend/DESIGN.md frontend/Dockerfile frontend/README.md frontend/eslint.config.js frontend/index.html frontend/nginx.conf frontend/package-lock.json frontend/package.json frontend/public/favicon.svg frontend/public/icons.svg frontend/src/App.css frontend/src/App.tsx frontend/src/api.ts frontend/src/assets/hero.png frontend/src/assets/react.svg frontend/src/assets/vite.svg frontend/src/components/AgentLogPanel.tsx frontend/src/components/AlertsList.tsx frontend/src/components/ChatPanel.tsx frontend/src/components/DateSelector.tsx frontend/src/components/ForecastChart.tsx frontend/src/components/ForecastMeta.tsx frontend/src/components/ForecastSummaryTiles.tsx frontend/src/components/ForecastVersions.tsx frontend/src/components/HorizonSelector.tsx frontend/src/components/MetricsCards.tsx frontend/src/components/SiteTour.tsx frontend/src/components/TurbineMap.tsx frontend/src/components/TurbineSelector.tsx frontend/src/index.css frontend/src/main.tsx frontend/src/markdown.tsx frontend/src/siteTourStorage.ts frontend/src/types.ts frontend/tsconfig.app.json frontend/tsconfig.json frontend/tsconfig.node.json frontend/vite.config.ts scripts/backtest.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.