Архитектура фронтенда для LLM: как спасти пет-проект от хаоса

К концу второго месяца vibe coding на фронте моего пет-проекта жили пять компонентов кнопки, четыре спиннера, компонент страницы на 700 строк и шапка, которая показывала один баланс, пока модалка рядом показывала другой. LLM-агент писал всё это уверенно, быстро и с хорошим стилем кода. Фронтенд под

Архитектура фронтенда для LLM: как спасти пет-проект от хаоса

К концу второго месяца vibe coding на фронте моего пет-проекта жили пять компонентов кнопки, четыре спиннера, компонент страницы на 700 строк и шапка, которая показывала один баланс, пока модалка рядом показывала другой. LLM-агент писал всё это уверенно, быстро и с хорошим стилем кода. Фронтенд под LLM деградирует даже быстрее бэкенда — и тому есть причины: от качества обучающей выборки, где вперемешку лежат три поколения React, до самой природы JSX, где разметка, логика и состояние легально живут в одном файле. Под катом — что в итоге сработало: Feature-Sliced Design, урезанный до трёх слоёв, как карта для агента; dependency-cruiser в роли архитектурного контракта, который нельзя нарушить; кодогенерация API-клиента из OpenAPI вместо доменной модели; за что я простил Tailwind; и честно — про самое слабое место конвейера: агент, который верстает вслепую. Это продолжение статьи про бэкенд, но читается и само по себе.

Feature-Sliced Design как карта для LLM-агента

Feature-Sliced Design (FSD) — это методология организации фронтенда, которая делит код на слои: shared, entities, features, widgets, pages, app. В контексте LLM-агента полная версия FSD оказалась избыточной: агент путался в границах между entities и features, а widgets дублировали логику страниц. Урезанная версия до трёх слоёв — shared, features, pages — сработала как карта для агента. Shared содержит переиспользуемые утилиты, компоненты и API-клиенты; features — бизнес-логику и связанные с ней компоненты; pages — композицию фич для конкретных маршрутов. Агент получает чёткие инструкции: в shared — только общее, в features — только одну фичу, в pages — только сборку. Это резко снизило количество дублирующихся компонентов.

Почему полный FSD не подходит для LLM?

Полная версия FSD с шестью слоями создаёт избыточную сложность для машинной генерации. LLM-агент часто путает entities и features, так как границы между ними размыты. Например, компонент пользовательской карточки может быть и entity (если он просто отображает данные), и feature (если он содержит логику редактирования). В результате агент создаёт дублирующиеся реализации в разных слоях. Урезанная версия из трёх слоёв устраняет эту неоднозначность: всё, что связано с бизнес-логикой, идёт в features, а общие утилиты — в shared. Это упрощает инструкции для агента и снижает количество ошибок.

Dependency-cruiser как архитектурный контракт

Dependency-cruiser — это инструмент, который анализирует зависимости между модулями и запрещает недопустимые связи. В проекте настроили правило: слой pages может импортировать только features и shared, features — только shared, shared — ничего из вышележащих слоёв. Нарушение правила ломает CI-сборку. Это работает лучше любых code review: агент может писать что угодно, но dependency-cruiser не пропустит импорт из pages в features. Контракт жёсткий и автоматический — идеально для сценария, где человек не проверяет каждую правку.

Как настроить dependency-cruiser для проекта с LLM?

Настройка dependency-cruiser начинается с установки пакета и создания конфигурационного файла. В нём определяются правила для каждого слоя. Например, для слоя pages разрешён импорт только из features и shared. Для features — только из shared. Shared не может импортировать из других слоёв. Дополнительно можно настроить исключения для тестов или конфигурационных файлов. После настройки dependency-cruiser запускается в CI перед каждым коммитом. Если агент нарушает правило, сборка падает, и разработчик получает уведомление. Это гарантирует, что архитектура остаётся чистой даже при активной генерации кода.

Кодогенерация API-клиента из OpenAPI

Вместо того чтобы описывать доменную модель вручную и просить агента её придерживаться, мы генерируем TypeScript-клиент из OpenAPI-спецификации бэкенда. Это даёт агенту точные типы для всех запросов и ответов. Агент не может ошибиться в названии поля или типе данных — компилятор TypeScript поймает ошибку. Более того, агент видит структуру данных и может строить UI, опираясь на реальные поля, а не на вымышленные. Кодогенерация также включает хуки для React Query, что стандартизирует работу с состоянием запросов.

Почему OpenAPI-клиент лучше доменной модели?

Доменная модель, описанная вручную, часто расходится с реальным API. LLM-агент может использовать устаревшие или неверные типы, что приводит к ошибкам во время выполнения. OpenAPI-спецификация является единственным источником правды: она автоматически синхронизируется с бэкендом. Генерация клиента из спецификации исключает человеческий фактор. Кроме того, агент получает документацию по API прямо в коде: типы запросов и ответов, возможные ошибки, форматы данных. Это ускоряет разработку и снижает количество багов.

За что я простил Tailwind

Изначально Tailwind казался антиподом порядка: миллионы классов в разметке, нет чёткой границы между стилями и логикой. Но для LLM-агента Tailwind оказался идеальным: агент не проектирует абстракции CSS, а просто применяет утилитарные классы. Это снижает количество ошибок в стилях и ускоряет генерацию. Единственное условие — договориться о наборе цветов и отступов через tailwind.config, чтобы агент не изобретал новые значения. После этого Tailwind перестал быть источником хаоса.

Как Tailwind помогает LLM-агенту верстать быстрее?

LLM-агенты обучены на огромном количестве кода, включая Tailwind. Они хорошо знают его синтаксис и часто генерируют корректные классы. В отличие от CSS-модулей или styled-components, Tailwind не требует создания новых имён классов или компонентов стилей. Агент просто добавляет классы прямо в JSX, что ускоряет процесс. Кроме того, Tailwind поощряет использование ограниченного набора значений, что снижает вариативность и вероятность ошибок. Настройка tailwind.config с кастомными цветами и отступами дополнительно ограничивает агента, предотвращая появление неконсистентных стилей.

Самое слабое место: агент верстает вслепую

LLM-агент не видит, как выглядит результат его работы. Он генерирует код, но не может проверить, что кнопка попала в модалку, а спиннер скрылся за шапкой. Это приводит к визуальным багам, которые не ловятся ни типами, ни dependency-cruiser. Решение — добавить в конвейер визуальное регрессионное тестирование (например, Percy или Playwright) и скриншотные тесты на каждую страницу. Но даже это не гарантирует, что агент не сломает layout при следующем изменении. Пока единственный способ — периодически просматривать результат вручную.

Как решить проблему слепой вёрстки LLM?

Визуальное регрессионное тестирование — первый шаг. Инструменты вроде Percy делают скриншоты страниц и сравнивают их с эталонными. Если агент изменяет layout, тест падает, и разработчик видит разницу. Однако такие тесты требуют начальной настройки и обновления эталонов при осознанных изменениях. Более продвинутый подход — интеграция с браузерным рендерингом внутри агента. Например, можно запустить headless-браузер, который отображает сгенерированный код и передаёт скриншот обратно агенту для самокоррекции. Это пока экспериментально, но уже появляются прототипы. В любом случае, ручная проверка остаётся необходимой до тех пор, пока агенты не научатся видеть.

Кого затронет и как

Разработчики пет-проектов, использующие vibe coding, получат готовый рецепт: FSD из трёх слоёв, dependency-cruiser, кодогенерация API-клиента и Tailwind. Команды, внедряющие LLM-агентов в продуктовую разработку, смогут адаптировать подход для своих проектов, но должны учитывать, что визуальное тестирование остаётся узким местом. В российских реалиях dependency-cruiser можно заменить на eslint-plugin-import с правилами запрета импортов, но это менее надёжно. Для бизнеса важно понимать: без архитектурных ограничений LLM-агент быстро превратит код в «спагетти», которое невозможно поддерживать.

Какие инструменты подойдут для российских проектов?

В России dependency-cruiser может быть заменён на eslint-plugin-import с правилами no-restricted-paths. Это позволяет задать, какие модули могут импортировать другие. Однако eslint-plugin-import менее строг: он проверяет только импорты, но не экспорты или циклические зависимости. Для полного контроля можно комбинировать оба инструмента. Что касается кодогенерации, OpenAPI-клиенты работают одинаково везде. Tailwind также не имеет региональных ограничений. Визуальное тестирование можно организовать через Playwright, который бесплатен и не требует облачных сервисов.

Что будет дальше

В ближайшее время ожидается появление инструментов, которые позволят LLM видеть результат вёрстки — например, интеграция с браузерным рендерингом внутри агента. Также вероятно развитие кодогенерации: OpenAPI-клиенты станут стандартом для всех LLM-фреймворков. Сама методология FSD, вероятно, адаптируется под нужды AI-ассистентов, возможно, появится упрощённая версия специально для машинной генерации. Пока же лучшая стратегия — автоматические архитектурные контракты и минимизация свободы агента.

Какие тренды в архитектуре фронтенда для LLM стоит ждать?

Уже сейчас заметен рост интереса к визуальным тестам и их интеграции в CI/CD для LLM-проектов. Появятся специализированные библиотеки, которые позволят агенту получать обратную связь по вёрстке. Также вероятно, что методологии вроде FSD будут адаптированы: например, появится слой "components" для чистых UI-элементов без логики. Кодогенерация станет более умной: агенты смогут сами генерировать OpenAPI-спецификации на основе кода бэкенда. В целом, архитектура для LLM-агентов будет стремиться к максимальной автоматизации и минимальной свободе.

Итог

Vibe coding с LLM неизбежен, но без архитектурных ограничений он ведёт к хаосу. Feature-Sliced Design, dependency-cruiser, кодогенерация API-клиента и Tailwind — работающий набор, который позволяет агенту писать быстро, а проекту оставаться поддерживаемым. Слабое место — визуальное тестирование, но и оно решается добавлением скриншотных проверок. Следите за темой: архитектура для LLM-агентов станет одним из ключевых направлений фронтенда в 2024–2025 годах.