Как мы за год собрали с нуля крупнейшую F&R-платформу для сети масштаба «Магнита»
33 000 магазинов, 46 РЦ сети «Магнит», 17 млрд прогнозов на 90 дней, 8 ПБ данных и ни одного готового решения, которое можно было бы просто взять с рынка. В 2024 году мы начали с нуля собирать собственную F&R-платформу (Forecast and Replenishment) для «Магнита» — систему прогнозирования спроса и пополнения.
Меня зовут Фоменко Алексей, я руководитель ИТ-проекта ИС Прогнозирования и Пополнения, и в этой статье я расскажу, почему прошлые попытки не сработали, с какими ограничениями мы столкнулись, как выстроили разработку и что в итоге успели запустить за первый год. Это практический разбор того, как строить огромную критичную систему в условиях дефицита времени и готовых решений.

Почему готовые подходы не сработали
Система прогнозирования и пополнения для сети масштаба «Магнита» — это большой технологический контур, который должен одновременно считать прогноз спроса, формировать рекомендации к заказу, работать с данными из десятков внутренних систем и давать бизнесу понятный интерфейс для работы. У всех предыдущих попыток создания собственной ИС Прогнозирования и пополнения были разные сложности, но все они так или иначе были связаны с масштабом информационной системы, которая должна покрывать крупнейшую по числу магазинов розничную сеть в стране.
На мировом рынке практически нет готовых решений, способных покрыть объемы и масштаб сети «Магнит». Немногие поставщики, обладающие схожими решениями, которые лишь частично соответствовали нашей потребности, в какой-то момент времени были вынуждены сойти с дистанции по разным причинам: от невозможности качественно масштабироваться на всю сеть до внешних не зависящих от них факторов.
Поэтому в апреле 2024 года было принято решение идти в собственную разработку, хотя на тот момент у нас ещё не было ни полной архитектуры, ни готовой платформы данных, ни достаточной команды под такой объем работ.
С каким масштабом мы работали
На момент старта речь шла о сети примерно о 29 тысячах магазинов и 51 распределительном центре. Для такой географии нужно было построить сразу несколько взаимосвязанных контуров:
нам нужно было:
-
Прогноз спроса, основанный на множественном составе параметров от сезонности до прогноза погоды, способный считать на несколько месяцев вперёд.
-
Систему расчетов пополнения сети и РЦ необходимыми товарами в необходимом количестве для минимизации излишков товарных запасов, затоваривания магазинов, РЦ, отдельно взятой полки и подготовки ежедневных рекомендаций для ответственных специалистов на основании прогноза спроса.
-
Реализовать локальное, устойчивое хранилище данных на 8 ПБ, необходимых для бесперебойной работы нашей ИС, а также платформу данных, получающую, трансформирующую и подготавливающую данные для дальнейших расчётов.
-
Реализовать собственное ядро расчётов (платформу).
-
“Обернуть” все вышеперечисленное в удобную, внешнюю визуальную часть нашего цифрового продукта, с которой взаимодействует пользователь.
Отдельная сложность заключалась в том, что система должна была быть не просто производительной, а ещё и адаптивной: под новые форматы поставок, изменения бизнес-логики, новые типы промо, рост объёмов данных и дальнейшее масштабирование. То есть нам был нужен не «разовый проект под пилот», а платформа, которую можно развивать дальше без постоянного накопления временных решений.
Как мы организовали работу
На старте мы разделили продукт на несколько ключевых направлений: прогноз, пополнение, данные и интеграции, расчётную платформу и UI. У каждого предметного направления появился свой экспертный контур: продуктовая и предметная экспертиза с одной стороны, техническая с другой.
В разработках каждой из команд были использованы скрам и канбан. Исключением являлась команда прогноза, процессы разработки которой, основанные на моделях машинного обучения и проверке гипотез, выбивались из общего ритма команд разработки.
Производственный цикл мы поделили на двухнедельные спринты. По итогу каждого проводили демонстрации результатов для команды и заказчика. При необходимости проводили анализ ретроспективы рабочих и процессных ситуаций для извлечения новых уроков и устранения слабых мест в процессах. Спринты начинались с планирования беклога команд на 2 недели вперёд.
Квартальные цели мы определяли и уточняли в рамках квартального планирования.
Мы работали в данных моделях, параллельно улучшая текущие процессы до момента вывода пилота нашего продукта в промышленный контур.
Вывод продукта в пром — это всегда ключевое событие в жизни любого продукта. С этого момента меняются многие процессы как отдельных команд, так и продукта в целом. Одним из правильных изменений процессов является запуск релизного конвейера. Каждая команда сама определяет оптимальный ритм релизов исходя из своих процессов и требований заказчика. Главное — держать баланс между частотой, качеством, скоростью сборки и стоимостью инфраструктуры.
Мы отказались от спринтов как таковых, поскольку они больше не задавали реальный ритм для нашего продукта. Настоящий ритм и необходимая скорость развития исходили из потребности релизов. Перешли к планированию состава релизов, скорректировали сроки реализации инкремента в рамках релизов. Здесь можно провести аналогию с методом планирования от обратного.
Ввели новые сущности в виде основного и второстепенного релиза. Учитывая нашу высокую скорость и огромное количество кросс-функциональных процессов/зависимостей, результаты которых не всегда могут поспеть к тому или иному релизу, мы пришли к применению флагов функциональности (Feature toggle), которые позволили гибко управлять составом наших поставок и докатывать определённый функционал по мере его готовности, не дожидаясь готовности ключевых релизных веток.
Для нас это было важно по одной простой причине: в большом кросс-функциональном продукте отдельные части почти никогда не созревают синхронно. Если ждать готовности всех зависимостей одновременно, скорость разработки резко падает; если поставлять всё без дисциплины, растут риски и технический долг. Флаги функциональности помогли удержать баланс между скоростью, качеством и управляемостью поставок.
Почему архитектура не должна становиться узким горлышком
Одна из главных практических проблем таких проектов — соблазн сначала долго проектировать идеальную архитектуру, а уже потом начинать разработку. На бумаге это выглядит логично, но в реальности при сроке пилота в 10–12 месяцев такой сценарий просто не работает.
Мы сознательно пошли по более гибкому пути: определили общие архитектурные границы, ключевые нефункциональные требования и целевую форму продукта, но не стали тормозить разработку в ожидании абсолютно завершенной архитектурной картины. При этом быстро стало понятно, что сама архитектурная функция тоже может стать узким горлышком, если через неё проходят все решения без достаточной автономии команд – с точки зрения потенциала управления, невозможно ресурсом команды архитектуры поддерживать высокую скорость и масштаб развития столь большого продукта. В какой-то момент времени у вас остановится разработка на одном из очередных новых архитектурных решений, и ваша команда погрязнет в бюрократии согласования на очередной архитектурной развилке. При этом, что очень важно, функция архитектуры, застрявшая в согласованиях, перестанет успевать за общими темпами разработки. Неизбежно начнут появляться “временные” решения и начнёт расти технологический долг команды. Сама же архитектура начнет походить на “лоскутное одеяло,” и даже усиление функции архитектуры дополнительными, сильными специалистами с рынка, скорее всего, не сможет глобально изменить положение вещей.
В такой ситуации нужно найти баланс между требованиями к системе, скоростью разработки и автономией команд. Для этого нужно зафиксировать общие архитектурные границы, нефункциональные требования и ключевые блоки продукта. Для команды нужен единый образ результата, к которому она должна прийти, при этом у команды должна быть своя автономность и независимость с точки зрения принятия более низких технологических решений и их дальнейшей реализации.
Без этого архитектура распадается на локальные компромиссы, команды начинают двигаться в разных ритмах, продукт превращается в набор слабо связанных между собой решений.
Ещё один важный принцип: ожидания зависят от образа результата. Команда должна четко понимать образ результата, в какую сторону ей нужно двигаться: будь то технологическая архитектура продукта или модель развития и наращивания функционала в соответствии с реальными потребностями компании.
Роль технического лидерства и почему это важно на большом проекте
Сценарий, когда вы попытаетесь “вшить” в архитектуру инструменты по управлению командами разработки, может иметь положительный эффект. Однако это возможно в ситуациях, когда у продукта есть единая, консистентная технологическая стратегия развития и командам задан единый вектор движения. В таком случае процессы разработки строятся максимально эффективно. Однако, если техлид не покрывает все команды разработки, у вас повторно возникает риск лоскутного одеяла, но уже в рамках самих команд. Единое ядро лидерства начинает разбиваться на более мелкие. У команд начинают появляются “лучшие сценария развития” и свои локальные цели. В этом случае собрать всех в единый, сквозной процесс становится гораздо сложнее.
Как ни банально прозвучит, но это можно вылечить только одним способом: концентрацией технологического управления и технологической стратегии развития в один сквозной процесс.
Как работать с ожиданиями заказчика
Управлять этими ограничениями можно — и нужно. Начинать стоит с управления ожиданиями. Если, к примеру, рассматривать ожидания заказчика, то необходимо приоритизировать и выпускать в первую очередь именно тот функционал, который реально требуется компании и несёт бОльшую ценность. В таком случае вам не придётся резать общий состав работ проекта. Приоритетный функционал выходит в первых фазах, и компания начинает получать максимальную выгоду на первых этапах. Далее, когда запущено функциональное ядро, проект может переходить в продуктовое развитие и докатывать менее масштабные вещи в рамках развития продукта.
Блок прогноза
Команда прогноза на старте была небольшой — около 8 человек. При этом именно она отвечала за отправную точку всей цепочки: ежедневный прогноз спроса, который затем использовался в контурах пополнения.
Процесс разработки прогноза отличался от классической продуктовой разработки, потому что был построен вокруг данных, гипотез и моделей машинного обучения. По сути, цикл выглядел так: анализ гипотез и метрик, поиск и подготовка данных, поставка данных в продуктовый контур, исследование моделей, прототипирование, ретро-тесты, параллельный расчет, после чего — вывод в промышленную среду через MLOps-контур.
Если тезисно описать этапы процесса разработки и поставки инкрементов прогноза, то они выглядят следующим образом:
-
Бизнес-анализ: предварительный анализ новых перспективных гипотез, внешних запросов, качества текущих метрик и их улучшение, проблем, ухудшающих качество текущих моделей и т.д.
-
Поиск лучших источников данных в рамках компании, анализ их качества, разметка данных и дальнейшая их подготовка. Также на внешнем контуре блока прогноза, были развернуты модули и сервисы поиска необходимых данных внутри компании, их классификации, кластеризации, трансформации и обработки.
-
Поставка данных в контур платформы данных продукта
-
Проведение исследований потенциальных моделей, после чего формулирование и проверка гипотез по развитию моделей. Раскроем подробнее:
Например: как наш прогноз будет учитывать рекламные коммуникации, и какая точность прогноза спроса при этом будет считаться успешной? Какие методы мы будем использовать и какой вычислительный подход? Если сложилось впечатление, что основные временные затраты находятся в первых трёх этапах, то это не так.
Данный этап является исследовательским, а любое исследование циклично. Получив результат при первой итерации, вы можете продолжать проводить итерации бесконечно, поскольку чаще всего вы будете получать небольшое улучшение результата. При этом даже небольшое улучшение результата выражается в сотых или тысячных долях процента улучшения качества прогноза, что в свою очередь несёт дополнительную прибыль и преимущество для компании.
У этой медали обратная сторона. В какой-то момент времени испытуемая модель перейдет в состояние переобучения, подстраиваясь под шумы и отклонения тренировочного объема данных, теряя навыки и способность оперативно обучаться и подстраиваться под динамично-меняющиеся наборы реальных данных во внешнем промышленном контуре.
В этой ситуации всегда важно поймать баланс: зафиксировать оптимальный результат на текущий момент времени и, если модель показывает лучший результат, чем сложившиеся метрики по компании, отправлять её дальше в промышленный контур. Также важно зафиксировать гипотезы команды, которые могут привести к дальнейшему улучшению показателей и поместить данную задач в исследовательский беклог, который в этот момент переходит в пункт 1. Во всем этом процессе, особенно на этом этапе, максимально важна экспертиза команды по машинному обучению. Могу с уверенностью сказать, что нам удалось собрать одну из лучших команд в индустрии машинного обучения.
-
Прототипирование: проверка возможности реализации данной модели в общих цепочках текущих расчётов прогноза, с учетом необходимого качества и сроков поставки расчётов прогноза. По окончании прототипирования, следует проведение ретро-тестов на ретро-данных. Далее следует важный шаг относительно принятия решения: катим ли мы данную модель в пром. контур?
-
Когда получено положительное решение, по п.5, наступает этап подготовки функционала в промышленный контур:
-
● Проводится пользовательское приёмочное тестирование (параллельный расчёт) на тех же данных, что крутятся в промышленном контуре и сверкой качества расчёта модели.
-
Поставка функционала в конвейер непрерывного тестирования, разработки и эксплуатации моделей машинного обучения (MLOps)
-
-
Когда все этапы пройдены и успешно завершены, происходит непосредственная поставка и разворачивание модели в промышленном контуре.
За время проекта мы вышли на собственные решения на базе градиентного бустинга и деревьях решений, адаптированных моделей Кростона и набора собственных библиотек и внешних прогнозных модулей. Но сами модели были только частью задачи: не меньше времени и усилий ушло на разметку данных, выстраивание источников, согласование интерпретации результатов с бизнесом и борьбу с отсутствием единого источника правды по части промо и других факторов спроса.
С инженерной точки зрения блок прогноза работал в очень жёстких ограничениях. Нужно было ежедневно считать 17 млрд прогнозов на горизонт 90 дней, использовать более 1,5 ПБ данных в хранилище прогноза, поднимать данные более чем из 25 корпоративных систем и укладываться в ограниченное окно расчета при чувствительных ограничениях по ресурсам.
К январю 2026 года нам удалось запустить отказоустойчивую прогнозную машину в облаке на всю географию 46 РЦ сети «Магнит». Дополнительно мы сократили расчетное окно с 10 до 4 часов, то есть в 2,5 раза, и уменьшили объем используемых ресурсов более чем в 4 раза по сравнению с исходным подходом. Отдельным достижением стало покрытие более 90% специфических промо- и активностей компании по объёму продаж.
Блок пополнения
Если прогноз отвечал на вопрос «что и где купят», то пополнение должно было превратить этот прогноз в работающие рекомендации к заказу по цепочке «магазин — РЦ — поставщик». На старте в блоке пополнения было около 10 человек, хотя объём задачи уже тогда был существенно больше.
Ситуацию осложняло то, что команда начала строить функциональность, когда ни прогнозный контур, ни платформа данных еще не были полностью готовы. Приходилось временно использовать результаты из существующих разрозненных систем, компенсировать ошибки в исходных данных и быстро поднимать альтернативные интеграции, чтобы вообще начать тестировать расчетные блоки.
Несмотря на это, к концу 2024 года команда выросла до 50 человек и вывела в работу корневой функционал продукта — непрерывный сквозной расчет рекомендаций к заказу. Технически блок был реализован на стеке Java, Ignite, Kafka, Apache Spark, Trino, Apache Iceberg, dbt, Kubernetes и других компонентов. В отличие от прогноза, специфика процессов разработки выглядела вполне классично:
Сбор требований по новой функциональности -> Разработка -> Тестирование -> приемка и демонстрация результата команде и заказчику -> сборка в релиз и дополнительная приемка авто-тестами -> Поставка в промышленный контур.
Наша команда пополнения, действительно, добилась очень крутых результатов. На момент подготовки статьи функционал покрывает большую часть типов товаров в рамках 10 РЦ, а сквозная цепочка расчёта от торговой точки до контрагента уже была собрана
Платформа данных
Без платформы данных весь остальной контур просто не мог бы работать. Для продукта такого масштаба было необходимо собрать качественные данные из большого числа внутренних систем, организовать их доставку, очистку, нормализацию, обогащение и подготовку под разработку и бизнес-потребление.
На практике это означало интеграцию с 25 системами-источниками, создание порядка 100 конвейеров доставки данных и подключение более чем к 250 источникам. В момент старта у команды почти ничего не было готово: ни процессов интеграции, ни модели данных, ни полноценной облачной инфраструктуры, ни достаточной команды.
Дополнительную сложность создавало то, что источники жили своей жизнью, у каждого был собственный беклог и собственные приоритеты. Данные невозможно «просто забрать»: для каждой интеграции нужен совместный системный анализ, разработка конвейеров, инфраструктура, проверки качества и синхронизация интересов между командами.
В момент X, когда было принято решение идти в собственную разработку, текущие наработки F&R находились в контуре собственной локальной инфраструктуры, мощности которой не хватило бы на запуск пилота и её дальнейшее масштабирование. По этой причине нужно было идти в облако, и разворачивать всю инфраструктуру с нуля, а также организацию стандартов облачного объектного хранилища данных для неструктурированной информации (s3). Со стороны облака также были вопросы по готовности инфраструктуры, организации приватных точек доступа, различии версий k8s (оркестратор по автоматизации развертывания, масштабирования и управления конвейеризированными приложениями данных) и т.д.
Нам удалось оперативно решить эти задачи с помощью временных инструментов в пользу потребности высокой скорости разработки. Более подробно я расскажу об этом в рамках Финопс.
Изучая блоки продукта, понимаешь, что каждый блок уникален, по-настоящему важен и незаменим. Стрим платформы данных должен был обеспечить все команды необходимыми качественными данными, как кислород.
Внутри платформы, после организации интеграции с источником данных мы выстроили своё собственное хранилище данных из нескольких слоёв:
-
Сырой слой, где данные хранятся в первичном, нетрансформированном виде
-
Операционный слой хранилища данных, где проводится первичная “очистка” данных и подготовка. Данные в этот слой попадают в режиме, близком к реальному времени. Данные имеют определённый уровень детализации, но всё же без необходимой агрегации.
-
Слой детальных, нормализованных и обогащенных данных.
Детальный слой содержит в себе данные максимального уровня детализации в атомарном виде. Обогащенный слой уже содержит в себе данные, обогащенные необходимыми бизнес-сущностями. С этого уровня данные можно спокойно отдавать в разработку.
-
Слой бизнес-данных (бизнес витрины) – адаптированные данные для конечного пользователя. Уровень данных, содержащий в себе необходимые бизнес-метрики, бизнес-логику и понятную для бизнеса структуру.
Такой подход позволил разделить хранение, подготовку и потребление данных и сделать платформу удобной и для разработчиков, и для аналитики, и для бизнес-пользователей.
Команда данных выросла с 4 до 30 человек. Она подготовила продукт к первому нагрузочному тестированию в декабре 2024 года, обеспечила инфраструктуру и данные для пилота в апреле 2025 года, затем — для активного масштабирования по 4000 товарам в сентябре 2025 года и для нагрузочного тестирования прогноза на всю сеть в январе 2026 года.
Отдельно отмечу направление FinOps, потому что оно часто оказывается за кадром технических рассказов, хотя в крупных платформах напрямую влияет на жизнеспособность решения. После периода быстрого роста и ряда вынужденных временных инфраструктурных решений мы в четвертом квартале 2025 года целенаправленно занялись техническим долгом: убрали избыточное бэкапирование, оптимизировали обработку данных, улучшили использование Kubernetes, пересмотрели релизный конвейер и режим потребления облачных ресурсов. В результате стоимость владения облачной инфраструктурой удалось сократить на 25%.
Отдельный стрим платформы расчётов
Через несколько месяцев после старта стало ясно, что ядро расчётного блока пополнения развивается в другом темпе, чем прикладной функционал. Для реализации потока данных, необходимо провести совместные работы с ИС источника:
Чтобы не тормозить развитие всего направления, мы выделили расчётное ядро в отдельный технический стрим платформы.
По сути, это был самостоятельный инженерный трек, сфокусированный на устойчивости и масштабируемости технологической базы. Команда выросла с нескольких инженеров до 24 человек и занялась развитием независимого расчетного ядра на базе Ignite.
UI и рабочее место пользователя
Последним, но очень важным слоем стала команда UI, потому что именно она превращала весь сложный внутренний контур в рабочий инструмент для конечного бизнес-пользователя. На старте у неё были те же проблемы, что и у остальных: нехватка людей, не до конца сформированный образ результата и частые расхождения с бизнес-заказчиком.
Ситуация начала меняться, когда мы перестроили взаимодействие в сквозной процесс и начали вовлекать бизнес-команду на всех этапах — от бизнес-анализа и прототипирования до разработки и пользовательского тестирования. Структура процессов команды выглядела следующим образом: микрофронтендные сервисы, бекенд-сервисы, процессы по инжинирингу данных, локальных хранилищ данных.
В результате UI-команда не просто делала фронтенд, а постепенно превратилась почти в самостоятельную продуктово-техническую единицу со своими микро-фронтендами, backend-сервисами, локальными хранилищами и процессами data engineering. Команда выросла с 5 до 20 специалистов и заметно сократила сроки поставки функциональности.
Результаты работы за первый год
Если собрать результаты в одну линию, то за 8 месяцев — с апреля по декабрь 2024 года — мы разработали и запустили MVP в тестовом контуре и провели нагрузочное тестирование. За 12 месяцев — с апреля 2024 по апрель 2025 года — вывели пилот F&R в промышленную среду на географию одного РЦ и порядка 600 магазинов.
В сентябре 2025 года запустили функциональность по основным цепочкам поставок и группе из 4000 товарных позиций. В декабре 2025 года сократили стоимость облачной инфраструктуры на 25%. В январе 2026 года масштабировали прогноз на всю сеть, то есть на географию 46 РЦ сети «Магнит», и расширили пополнение до 3 РЦ.
Для нас это был не только технологический, но и организационный результат. За это время ИТ-команда проекта выросла примерно в 5 раз, при этом продукт не развалился на изолированные куски, а дошел до устойчивого запуска и масштабирования.
Что оказалось самым важным
Во-первых, мы не ставили на одну карту — будь то методология, стек или одно сильное направление. Результат дался только за счёт одновременного движения по нескольким контурам: поиск необходимых данных и их качественная обработка, собственное машинное обучение, пополнение, улучшение гибкости архитектуры стабильная инфраструктура, и коммуникация с бизнесом.
Во-вторых, мы достаточно рано приняли, что в таком проекте идеальных условий не будет. Нельзя дождаться полного набора людей, идеальной архитектуры, готовых данных и полной синхронизации всех участников, а потом начать работать. Приходится двигаться поступательно, но при этом удерживать общий образ результата и не превращать каждое временное решение в постоянное.
В-третьих, проекту помогла сильная команда. Это звучит банально, но в нашем случае именно так и было: люди одновременно строили новый контур, масштабировали команды, поднимали инфраструктуру, договаривались с источниками и вывозили высокий темп поставки. Здесь нужно отдельно поблагодарить наших коллег из HR – они смогли организовать максимально эффективный процесс поиска технических специалистов высокого уровня, которые стали частью нашей большой проектной семьи.
У нас сложилась очень сильная техническая команда из действительно замечательных людей.
Мы столкнулись со множеством вызовов, связанных с архитектурой, функционалом технологического лидерства проекта, неготовности базовой инфраструктуры и прочими. Нам приходилось балансировать между десятком параллельных процессов и ограничений в условиях дефицита времени и высоких требований, оперативно принимать решения, не говоря о стандартном проектном треугольнике: бюджет-скорость-качество. Но несмотря на это, мы пришли к цели.
Мы действительно смогли создать самый масштабный проект по цифровой трансформации в цепочке поставок и первый в России проект по созданию и внедрению полностью отечественного ПО в F&R для такого размера бизнеса в офлайн-ритейле.
Данный продукт должен принести ощутимую пользу не только нашей компании, но и всей ИТ-индустрии в целом. Внедрение системы F&R позволит сократить товарные запасы в распределительных центрах и магазинах, повысить точность прогнозирования заказов и поставок и в конечном счете – доступность товаров на полке для покупателей. Разработанные технологии и полученный опыт позитивно повлияют на развитие отрасли. Наша собственная команда получила очень серьезное развитие, которое продолжится рамках данного продукта или других проектов. Уверен, что вы встретите наших ребят на многих конференциях или вам попадутся интересные статьи о результатах работы их направлений.
Автор: Aleks_F1

