AI/ML
7 мин.
02 сентября 2026

Как ИИ замыкает на себе самую скучную часть разработки

На примере переезда Web версии Яндекс Еды на микро-фронтэнд архитектуру

Сегодня я расскажу про кейс переезда, который до сих пор продолжается, — переезда Яндекс.Еды на микрофронтендовую технологию. Зачем мы это сделали, почему у нас это получилось здорово и что нам помогает делать это гораздо быстрее.

Как работают эксперименты и проверка гипотез

Про то, как работают эксперименты и проверка гипотез, расскажу чуть позднее. Как правило, у бигтехов есть конфигуратор, некая «экспериментница» — история, которая позволяет на часть пользователей раскатить какой-то функционал. Как правило, это фича-флаги. Это работает на всех фронтовых платформах, на всех бэкенд-платформах — неважно.

То есть эта штука позволяет, например, раскатить фичу на 50% пользователей, на 30%, или на людей, которые находятся в России, в Казахстане — раскатить какой-то конкретный кусок. Она позволяет гибко конфигурировать приложение в зависимости от обстоятельств и условий.

Почему мы пришли к микрофронтендам

Почему вообще мы пришли к микрофронтендам, зачем нам это оказалось нужно? На самом деле в международном направлении, в особенности в странах Африки, в которых Яндекс работает, — это Кот-д'Ивуар, Замбия и подобные страны — очень плохой мобильный интернет. Наш банк достаточно тяжёлый, честно, я не помню до конца, сколько он весит, но грузить его — это прямо больно. У нас даже ребята ездили в Африку и старались там оптимизировать.

В том году или позапрошлом я выходил на фронтенд-конференцию, и ребята из Мегамаркета рассказывали, как они на разных своих продуктах переиспользуют микрофронтенды. Мне показалось это классным решением в целом для Яндекса. Я притащил это в команду платформы, и мы начали это потихоньку делать. Тогда ещё AI не была такой популярной и не могла выполнять такой пласт задач, который может сделать сейчас.

Что даёт микрофронтенд помимо переиспользования

Поскольку у нас крупный продукт, релизы происходят раз в неделю, отвод релизной ветки — тоже раз в неделю. И когда каким-то образом случается так, что в проде оказывается что-то очень плохое, откатывается вся функциональность, которая была за эту неделю отведена. Это могут быть какие-то срочные фичи и так далее. Откат занимает тоже некоторое количество времени.

Вот буквально сравнение того, что мы делаем в монолите, когда релизимся, и что мы делаем в микрофронте:

  • Частота релизов: в монолите — раз в неделю, в микрофронте — сколько душе угодно.
  • Длительность выхода: от двух часов в монолите — это полный раскат на что-то типа 90 подов; в микрофронте — это буквально загрузка в S3-хранилище. Об этом чуть позднее расскажу.
  • Зона поражения при ошибке: в монолите — деградация всей отведённой функциональности; в микрофронте, соответственно, узкая зона ответственности.
  • Откат: в монолите занимает около двух часов вместе с откатом всех этих 90 подов; в микрофронте — по щелчку пальца. Об этом тоже расскажу, как мы это сделали.
  • Регресс и код-фриз: при релизе монолита есть дежурные QA-инженеры, которые буквально шерстят весь функционал с каждым отводом и смотрят, ничего ли плохого не случилось. В микрофронте достаточно ответственной команде просто посмотреть ту конкретную часть, которая была изменена, и она спокойно убегает в прод, никого не ломая.

Как устроена работа с микрофронтами

У нас есть базово три части: монолит, JS микрофронта и какие-то типы, которые мы продолжаем интегрировать.

Как мы воспользовались нашей системой экспериментов и конфигураций, чтобы сделать очень красиво? Во время публикации микрофронта мы буквально загружаем его в S3-хранилище со ссылкой на файл. Ссылка представляет собой название микрофронта, точка, версия. И S3 может хранить очень большое количество версий — буквально сколько угодно.

В тот момент, когда CI говорит о том, что микрофронт зарелизился, автоматика сама создаёт драфт на изменение технического конфига, который просто буквально меняет версию. О чём я говорил, когда упоминал мгновенный откат: если что-то не так, буквально заходит SRE-инженер в этот конфиг, меняет версию назад — и всё, старая версия микрофронта на месте. Это просто происходит моментально.

А все типы, все штуки, которые должны использоваться за пределами этого микрофронта — например, другими микрофронтами или монолитом, — выплёвываются в пакет в npm, и он скачивается и ставится. Тут тоже всё просто.

Работа с версионностью

Вот пример небольшой того, как у нас происходит работа с версионностью. Здесь можно увидеть, что мы тащим эксперимент по конкретному микрофронту, тащим эксперимент по конфигу, версии фронта, и кешируем. Если он закеширован — соответственно, отдаём. Мы считаем, что во время работы с приложением необязательно обновлять версию: после полной перезагрузки закешированных значений не будет. Из контейнера достаём, кастим его и импортим через технологию Module Federation.

Наружу выплёвывается регистр в случае, если этот микрофронт подтянулся.

Проброс общих частей

По поводу того, как мы пробрасываем в микрофронтенд какие-то общие части. У нас, например, темы, эксперименты и так далее хранятся в монолите. И в микрофронтенд набрасывается только узкая часть сервисов, которая только ему и нужна.

Вот пример одного из таких сервисов: здесь можно увидеть темы, конфигурацию, переводы, хуки, аналитику, диплинк-менеджеры — какое-то количество сервисов. Это пример того, как двигается вот этот сервис, который мы потом используем, чтобы пробрасывать его в микрофронты, которые за них.

Масштаб сегодня

Сегодня у нас около 20 микрофронтов в проде, но это на самом деле не так много, учитывая, какая огромная еда в целом.

Забыл сказать: помимо того, что мы просто можем выделить ка-то зону микрофронта, мы можем ещё и указать от энтрипоинты. Например, есть модалка адресов, которая используется во всём приложении. Она лежит отдельным энтрипоинтом. То есть микрофронт лежит в одном репозитории, но энтрипоинт для конкретно этой модалки лежит наружу отдельно, его можно отдельно включить.

Соответственно, у нас сейчас пока что два репозитория — это монолит и репозиторий, который мы называем «фастфудом» (типа он быстрее). Ну и остался план-хвост монолита, который потихонечку худеет.

Переезд: с чего начинается

Скука начинается с переезда. Шаги у нас, на самом деле, одни и те же. Мы разделили процесс на два этапа, выделили одинаковые шаги и как раз здесь завели автоматизацию.

Что происходит в первой части?

  • Создаётся каркас микрофронта — это делает скриптик, очень легко.
  • Создаётся эксперимент в «экспериментнице», о которой я говорил.
  • Создаётся скоуп типов.
  • Создаётся свитчер на уровне монолита, который по эксперименту говорит: брать эту функциональность из монолитной части или из микрофронта.
  • Роуты, npm-зависимости, спецификации экспериментов и всякие переводы.

В конце это два пул-реквеста в два репозитория: фастфуд и монолит.

По итогу первого этапа у нас есть микрофронт, который на самом деле просто содержит заглушку. Есть свитчер, который на уровне монолита переключает монолитную часть либо микрофронт-часть. Есть все типы, которые нужны, чтобы работал этот микрофронт. И какая-то инфраструктура вокруг в виде экспериментов, которая позволяет по щелчку пальцев переключать версии.

Автоматизация первого этапа

Расскажу, как мы автоматизировали первый этап и как нам на втором этапе нейронки всё ещё помогают.

Для первого этапа у нас есть скилл — генерация микрофронта. Что он делает? Как раз генерирует вот этот каркас с какими-то дефолтными файлами — tsconfig и так далее. Короче, просто каркас, чтобы потом в него писать.

Автоматически через MCP (MCP знаете все, да, что такое? Забыл спросить) создаётся эксперимент в наших конфигураторах. Потом создаются в рамках этого микрофронта общие типы, и на уровне монолита рождается этот переключатель, который смотрит на конфиг и выбирает, куда что включить — микрофронт или оставить в монолите. Грузятся какие-то первоначальные дефолтные роуты и генерируются эксперименты для этой конфигурации.

У каждого микрофронта теперь есть только те эксперименты, которые для него нужны. Раньше в монолите было какое-то количество экспериментов, а теперь каждый микрофронт инкапсулирует в себе только нужные и подсасывает именно их.

По результату выполнения этого скилла у нас буквально создаётся два пул-реквеста: один — в Фастфуд, с новым микрофронтом, второй — в монолит, с переключателем и с пробросами некоторых сервисов. Человеку остаётся только оформить эксперимент, который создался, и завести ключи в бункере.

Блин, забыл про бункер упомянуть. Бункер — это наша внутренняя технология, которая позволяет подсасывать переводы для конкретного интерфейса.

Этап два: куда уносить код

Второй этап достаточно нетривиальный, от раза к разу меняется. Нужно выделить границы того, какие зависимости в модуле есть — какие компоненты, какие данные для хранилища и так далее. Очень многое переиспользовать на самом деле не всегда удаётся. Но при этом мы стараемся переиспользовать то, что в других микрофронтах уже выносилось, и не дублировать код между микрофронтами.

Компонент из монолита тянет за собой несколько штук. Первое — это общие компоненты, хуки, типа инпутов, всяких useScope, useDispose. Какие-то штуки, которые на самом деле можно унести во что-то внешнее, и потом другие микрофронты это тоже смогут использовать.

Соответственно, наша задача — проанализировать то, что можно вынести в общее место, что уже вынес кто-то до нас, и мы можем это оттуда взять и переиспользовать; и что нужно сделать так, чтобы внутри микрофронта была какая-то сущность, которая инкапсулирует свои типы и свои зависимости наружу, чтобы другие микрофронты и прод могли их потребить.

Как помогает AI на втором этапе

Вот это нам и помогает на втором этапе сделать AI. Она буквально смотрит во весь репозиторий, анализирует все микрофронты, смотрит на лучшие практики, импортирует что-то, создаёт какие-то конкретные вещи, которые нигде не используются, в папку shared. Как раз то, что находится в папке shared, у нас публикуется во внутреннем npm и потом потребляется другими микрофронтами или прод-приложениями.

Как итог, по работе AI мы получаем какую-то карту зависимостей. Как правило, мы используем ещё что-нибудь типа progress.md, чтобы нейронка напоминала себе шаг за шагом, что она делает в рамках работы. Потому что одним промптом вынести весь клубок зависимостей очень сложно. Поскольку у нейронки ограниченный контекст, мы складываем это в файл, куда она потом заходит, читает и смотрит прогресс.

Как итог, мы получаем карту зависимостей, черновой импорт, перенос UI и импортов, адаптацию стилей, подготовку энтрипоинтов. Всё это скорее как план. Она также смотрит, что сделали уже соседние микрофронты: что мы можем переиспользовать, а что не нужно копировать.

Скилл для выноса общего: виджеты

Одна из зон ответственности — написали скилл для выноса того, что является общим. У нас есть такая история, как виджеты — их на самом деле десятки. Виджеты — это то, что вы видите всегда, когда заходите в Яндекс.Еду на главную: поиск, выдача, фильтры — это всё виджеты, которые конфигурируемы. У них примерно одинаковая структура зависимостей и структура работы.

Ребята из команды выбора в нашем случае сделали скилл, который буквально автоматизирует переход всех виджетов. Человеку остаётся только отревьюить, сделать небольшой diff-тест на стенде, отдать QA, чтобы он проверил. И в целом всё. Вот тут как раз хороший пример того, как мы можем с этим работать, потому что эта штука прямо общая.

На какие грабли мы натыкаемся

  • Импорт банда соседа. У нас стоят жёсткие ограничения на то, чтобы один микрофронтенд импортил другой микрофронтенд именно JS-частью. Монолит выступает как мост для общения между микрофронтами, и мы поставили жёсткие ограничения, чтобы один микрофронт не использовал другой.
  • Дублинг компонентов. Это как раз то, о чём я говорил: когда работают три команды параллельно, они выносят свою зону ответственности, и у них буквально в UI заносится три одинаковых компонента, потому что каждый используется в каждом из этих микрофронтов. Это сейчас происходит, но мы с этим боремся аккуратно.
  • Сторы не переезжают. Как бы хорошо мы ни хотели инкапсулировать зону ответственности, сторы у нас зашиты в монолитной части приложения. Однако мы сделали отдельный фастфуд MFStore, который в себе инкапсулирует модели данных. То есть он создаёт вам просто модельки — вернее, не создаёт, а описывает интерфейс, скажем так. А создаёт сами модельки непосредственно монолит. И монолит пробрасывает сервисами в каждый его фронтенд эти модельки, там с ними происходит какое-то взаимодействие, методами происходит изменение и наполнение стора в монолите, и он уже отправляет данные на остальные микрофронты. Это всё реализовано через подписку условно.
  • Чистка экспериментов. Последний скилл в этом всём — это чистка прямых экспериментов. Когда мы понимаем, что спокойно живём в микрофронте и нам не нужна эта часть в монолите, не нужен свитчер, мы просто говорим: всё, нам больше не нужен эксперимент, почисти всё, убери свитчер, теперь всегда используй данные из микрофронта. Это тоже мы автоматизируем. Пусть это не такая большая работа, чтобы удалить, — просто это рутина, которая из раза в раз одинаково повторяется.

Что остаётся человеку

За агентом — каркасы, зачистка экспов, типы, спеки, PR, комментарии, автотесты.

Человеку остаётся определить, что переезжает и когда переезжает, а также провести качественное код-ревью того, что делают нейронки. Это очень важно, потому что путь к абсолютному доверию к нейронке — это путь к багу в коде просто каждый день.

Также за человеком — пуш экспериментов в код, который обновляет версии, схемы конфигов и переводов в бункере, и какие-то архитектурные границы микрофронта, которые тоже описывает разработчик.

Другие статьи

Полезно
5 мин.
AI/ML
AI First компания: от AI-SDLC к AI PDLC
Алоян Дмитрий, генеральный директор WILIX, на Agentic Dev Camp рассказал, как перевести компанию на AI-first разработку и выстроить PDLC поверх SDLC: от «петли намерений» до автоматической «петли реализации», а также про Harness, IDP и токен-роутер.
Полезно
3 мин.
Графики оплат в договорах поставщиков: как настроить в 1С:ERP, чтобы не было задолженности
Как настроить графики платежей поставщикам в 1С, чтобы видеть точные даты оплат, снизить просрочки и упростить финансовое планирование? Разбираем ключевые настройки, которые помогут синхронизировать закупки, финансы и бухгалтерию.
Новость
2 мин.
Разработка
ZeVision: как ZeBrains автоматизирует визуальный контроль на производстве с помощью компьютерного зрения
Как компьютерное зрение помогает сократить ошибки, автоматизировать контроль качества, комплектности и безопасности? Рассказываем, как работает ZeVision, какие задачи решает платформа и каких результатов уже удалось достичь в реальных проектах.

Обсудить
проект