- BrainTools - https://www.braintools.ru -

Как я разрабатывал агента для сбора страниц на Elementor

В этой статье хочу рассказать как я разрабатывал агента, который принимает запросы из телеги и создает страницы на WordPress + Elementor, не путает проекты, не трогает прод и не собирает каждый раз дизайн рандомно.

То есть мысль перед созданием была следующая – есть Elementor MCP, есть агент, есть запрос пользователя, а значит, агент может вызвать нужные методы, добавить контейнеры, виджеты, текст, кнопки и готово. Спрашивается, почему бы и не сделать такого агента, удобно же.

Но по факту все, конечно же, оказалось сложнее.

Чтобы это начало работать нормально, пришлось сделать отдельный навык – очередь задач, SQLite, CLI-проверки, правила для телеги, валидаторы, перенос бета в прод и отдельный компилятор на Python.

Так что расскажу все по порядку, возможно, кому то пригодится.

Тут будет по сути хронология работы с агентом, так что идем от начала до сегодняшнего дня.

Началось не с фигмы и не с компилятора

У нас есть несколько сайтов на WordPress + Elementor. Периодически в телегу прилетает обычный рабочий запрос, по типу «сделай страницу», «поправь блок», «создай лендинг», «нужно по документу собрать страницу».

К этому моменту мой агент в OpenClaw уже умел делать соседние задачи – писать тексты, готовить SMM, работать с изображениями, публиковать анонсы. Поэтому первая идея была такой – раз есть Elementor MCP-инструменты, пусть агент просто вызывает их и собирает страницу. Собственно, так он и делал и, естественно, это не работало так как надо.

Когда запрос один все выглядит нормально, но как только появляются реальные пользователи, несколько проектов и риск задеть прод все начинает сыпаться.

Нужно было настроить агента так, чтобы он собирал страницу по определенным правилам –  в нужном окружении, по очереди, с проверками и понятным состоянием.

Так появился навык в отдельном пространстве, куда главный агент делегирует именно эти задачи под названием “web42-elementor-builder”

Как я разрабатывал агента для сбора страниц на Elementor - 1

Первая версия

Навык начинался как обычный scaffold:

  • SKILL.md [1] – главный файл с правилами;

  • settings/triggers.yaml и settings/intents.yaml – чтобы понять, какие фразы запускают какой workflow;

  • skills-map.yaml – карта intent → workflow;

  • workflows/ – YAML-файлы для операций со страницами, контейнерами, виджетами, стилями и публикацией;

  • modules/ – отдельные инструкции для окружения, роутинга, резолва страниц, валидации;

  • scripts/ – первые Python CLI для задач, окружений и SQLite.

На этом этапе важнее всего было принять архитектурное решение – агент не должен сам читать и менять состояние, все операции с задачами, окружениями и базой идут только через CLI.

Живая отладка быстро сломала красивую схему

29 июня я проверял навык в телеге с двумя пользователями, оба попросили создать страницы и тут выяснилось, что scaffold не вывозит.

И первый баг был самый неприятный, задача первого пользователя могла тупо потеряться. То есть, пользователь просит страницу, агент спрашивает проект, ждет ответа, а task record создает уже потом. Кроме того, пока первый пользователь думает, второй тоже отправляет запрос и агент создает активную задачу для второго, а первый фактически проваливается между шагами.

Так что сначала надо было настроить порядок операций. Task record нужно создавать до любого вопроса пользователю, даже если проект еще неизвестен, в задаче фиксируется плейсхолдер вроде pending_project, то есть пользователь сразу занимает место в очереди и его запрос больше не теряется.

Как я разрабатывал агента для сбора страниц на Elementor - 2

Второй баг был про дубликаты – один пользователь мог запустить сразу несколько задач. Поэтому, я добавил проверку на уровне db.py [2]: перед созданием новой задачи вызывается get_user_open_task(telegram_user_id). Если у пользователя уже есть active или queued задача, новая не создается.

Третий баг хорошо показал логику [3] поведения [4] агентов – даже когда навык уже существовал, агент все равно пытался делать прямое обращение к МСР

И поэтому жестко зафиксировали правило – для Web / Elementor задач главный агент не строит страницы напрямую, а делегирует ее ИИ-верстальщику внутри которого уже workspace-elementor task routing должен пройти через навык и CLI. Прямые MCP-вызовы до маршрутизации – обход системы.

Один вопрос за раз

Еще один типичный сбой – compound-вопросы.

Агент спрашивал сразу все – какой проект, какой источник, какой стиль, публиковать ли в бету или прод. Вроде бы это правильно для задачи, но в очереди задач это ломает состояние. То есть, пользователь отвечает на три вопроса сразу, агент уже переключился на другую задачу, часть ответа относится к текущему шагу, часть к будущему, часть вообще еще нельзя применять.

Поэтому появилось правило одного ближайшего блокера “если не хватает проекта – спросить только проект; если проект есть, но не выбран источник – спросить только источник”, короче просто не забегать вперед.

Для этого появился workflow_cli.py [5] next-question. Агент больше не сочиняет формулировки сам, он спрашивает CLI, какой вопрос сейчас разрешен и отправляет только его. Это выглядит менее эффектно, зато система становится воспроизводимой.

Как я разрабатывал агента для сбора страниц на Elementor - 3

Агент должен продолжать работу, пока нет настоящего блокера

На той же отладке всплыл обратный перекос.

Агент сделал внутренний шаг – сохранил метаданные, прочитал Google Doc, извлек заголовок и остановился с сообщением вроде “продолжаю”, хотя по факту для пользователя это бесполезный ответ, как и для workflow.

Я разделил состояния на те, которые могут останавливать выполнение, и те, которые обязаны вести дальше. Условно – waiting_*, blocked_*, done_* могут быть причиной остановки, а ready_* – нет. Если задача в активе и следующий шаг можно выполнить без пользователя, агент должен продолжать.

Позже из этого вырос модуль long-running-progress.md [6], то есть сообщать о долгих операциях можно, но progress-only финальный ответ запрещен. Грубо говоря “если можно идти дальше – надо идти дальше”.

Бета по умолчанию, прод только через перенос

Отдельная тема – окружения.

Есть бета и прод и понятное дело нужно его ограничить, чтобы все тесты были в бете, поэтому – create_page идет в бету по умолчанию, а прод разрешен только через отдельный transfer workflow. Да, да, супер база, но вдруг.

Для этого добавили:

  • env-project-guard.md [7] – проверку проекта и окружения перед операциями;

  • production-transfer.md [8] – порядок переноса;

  • transfer_cli.py [5] – export из beta и import в production;

  • workflow_cli.py [5] guard-production-operation – блокировку прямых правок на production.

Ключевой момент – перенос это не пересборка. Нельзя собрать заново примерно то же самое на рабочем сайте. Нужно взять проверенный результат из беты и перенести его, а перед переносом – обязательно явное подтверждение.

Как я разрабатывал агента для сбора страниц на Elementor - 4

Ошибка с отступами Elementor

Мы проверяли одну из созданных страниц и нашли системную проблему с отступами.

Агент применял padding и margin к контейнерам. В Elementor эти ключи относятся к widgets, а у контейнеров другие настройки – padding, margin, css_classes, flex_gap, grid_gaps. У widgets – padding, margin, cssclasses.

То есть агент использовал неправильный слой API. После этого появился модуль elementor-spacing-builder.md [9], в нем зафиксировали матрицу container vs widget controls. Модуль стал обязательным перед сохранением Elementor layout.

Здесь был еще один важный урок – агент смотрел в JSON/export и писал, что spacing применен, но браузер мог рендерить иначе из-за темы, каскада CSS или особенностей Elementor. Поэтому проверки только по JSON недостаточно, нужна связка schema-compatible settings + exported Elementor data, а в идеале еще и браузерная проверка computed styles.

Как я разрабатывал агента для сбора страниц на Elementor - 5

Финальный ответ пришлось вынести в отдельный CLI

Через неделю стало понятно, что агент смешивает две разные вещи – workflow questions и final handoff.

Один инструмент должен отвечать на вопрос “что спросить дальше?”, а другой “что показать пользователю, когда задача завершена?” Если смешать это в голове агента, финальный ответ превращается в смесь URL, внутренних статусов, task ID, вопросов и отладочных деталей, поэтому появился result_cli.py [5].

workflow_cli.py [5] отвечает за шаги и вопросы, result_cli.py [5] render-final собирает user-facing результат из task state и metadata – preview URL, edit URL, применяемые модули, evidence. Внутренности БД и технические трассировки в обычный ответ не попадают.

Разделение получилось небольшим, но полезным – стало меньше путаницы в том, что агент должен делать дальше и что он должен показать пользователю.

Quality gate нельзя доверять словам агента

Еще через неделю добавили отдельный quality_gate_cli.py [5], потому что агент может сказать “проверено”, не проверив. Иногда он считает, что если шаг был в плане, значит он выполнен, а иногда видит валидный JSON и делает слишком широкий вывод. 

Поэтому passing quality gate может поставить только CLI – агент запускает проверку, получает passed или failed, и дальше действует по результату. Self-asserting quality gate запрещён. Quality gate проверяет наличие обязательных артефактов и evidence, а для Figma-сценариев – strict compiler artifacts, asset binding, visual/pixel evidence и repair state, где это требуется от воркфлоу.

Как я разрабатывал агента для сбора страниц на Elementor - 6

Figma оказалась сложнее обычной Elementor-сборки

Изначально создание страниц из гугл дока было основным сценарием – документ дает контент, style audit берет референсную страницу, агент собирает структуру в Elementor.

Style audit и widget/template extraction обязательны для того, чтобы переиспользовать стиль проекта и не изобретать компоненты заново.

Но вот второй сценарий оказался намного сложнее – Figma и Elementor описывают страницу по-разному. В Figma есть дерево нод, координаты, компоненты, фреймы, варианты, vector paths, image fills, а в Elementor – контейнеры, widgets, flexbox/grid, WordPress media, responsive settings, то есть прямой маппинг “нод → виджет” быстро ломается.

Первые версии компилятора шли через упрощенные представления:

В 6 версии был scene.json и из Figma REST JSON делалось упрощенное дерево, потом deterministic compiler с self-heal пытался получить Elementor structure и проблема тут, что при упрощении терялось слишком много информации.

В 7 пробовал гибрид с JavaScript и Elementor MCP widgets.mjs – это добавило второй runtime и усложнило отладку. Python-окружение агента, Node.js-компилятор, validate-readback – все вместе стало слишком хрупким.

А в 8 сделал разворот strict Python compiler. Figma REST JSON напрямую превращается в Elementor JSON через figma_json_to_elementor.py [10]. Ассеты выбираются через figma_selective_assets.py [11], потом связываются с WordPress media через figma_bind_assets.py [11].

Короче, главное правило – никакой ручной сборки Figma-страницы агентом. Никаких скриншотов вместо страницы. Никаких HTML/CSS-подстановок чтобы похоже выглядело.

Если компилятор ошибся – исправляем Python и прогоняем заново.

Зачем понадобился semantic compiler

К 14 версии пайплайн стал таким:

Как я разрабатывал агента для сбора страниц на Elementor - 7

Смысл semantic tree в том, чтобы сначала понять, что перед нами, заголовок, текст, кнопка, карточка, изображение или декоративный элемент, а уже потом решать, как это разложить в Elementor flex/grid. Это важное разделение, потому что если сразу превращать Figma-ноды в Elementor-элементы, компилятор путает смысл и раскладку, а если разделить semantic tree и layout tree, можно отдельно улучшать распознавание и отдельно геометрию.

В v14 также закрепил правило “Figma REST JSON – единственный runtime source”. JSON из Figma-to-Elementor плагина можно использовать только в benchmark mode как golden reference, но нельзя копировать его в runtime, использовать как шаблон сборки страницы или строить страницу по нему.

Это архитектурно правильный pipeline, но он еще не означает полной визуальной эквивалентности Figma и Elementor.

Ассеты из Figma нельзя экспортировать без разбора

18 июля нашел еще один практический баг.

Тысячи VECTOR-фрагментов могли экспортироваться как отдельные SVG. WordPress media library быстро засоряется такими файлами, а сборка тормозится.

Поэтому правило изменил:

  • generic VECTOR paths не считаются самостоятельными SVG-ассетами;

  • COMPONENT/INSTANCE экспортируются как SVG только при explicit export или семантическом имени вроде icon, logo, illustration, badge, symbol;

  • raster image fills дедуплицируются по imageRef;

  • декоративные zero-geometry paths не блокируют build.

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

Во что это выросло

На момент подготовки статьи наш “web42-elementor-builder” – это уже не один промпт и не один SKILL.md [1].

В сумме это тысячи строк Python, десятки workflow/config-файлов и большой SKILL.md [1]. То есть полноценный регламент, а не один промпт.

Фактический объем в рабочей директории сейчас такой:

Компонент

Объем

SKILL.md [1]

2258 строк, около 90 KB

modules/

15 файлов, 5309 строк

scripts/*.py

19 Python-скриптов, 9787 строк

workflows/

15 активных YAML workflow плюс backup/recovery copies

settings/

4 файла, 489 строк

Самые крупные Python-файлы:

  • figma_json_to_elementor.py [10] — 3623 строки;

  • db.py [2] — 1764 строки;

  • workflow_cli.py [5] — 657 строк;

  • template_cli.py [5] — 623 строки;

  • task_cli.py [5] — 466 строк;

  • result_cli.py [5] — 384 строки;

  • figma_pipeline_cli.py [5] — 383 строки;

  • figma_preflight.py [12] — 373 строки;

  • transfer_cli.py [5] — 250 строк.

Цифры понятно еще будут меняться, но они хорошо показывают, что подобная вроде простая задачка в реальной работе довольно быстро превращается в систему с состоянием, правилами, проверками и запретами.

Что все еще не идеально

Figma-компилятор пока работает так себе.

В документации по ограничениям зафиксировано, что на ERP golden pair benchmark coverage около 35.6% по количеству элементов – 528 сгенерированных против 1482 в референсе. Это значит, что benchmark mode правильно блокирует заявления об эквивалентности.

Обычный компилятор можно использовать для разработки и тестов, но слабые места остаются:

  • tree alignment нужно улучшать;

  • breakpoint-specific branch generation для tablet/mobile еще не всегда корректен;

  • сложные Figma-компоненты не всегда мапятся 1:1 в Elementor.

В общем, еще есть над чем поработать.

Что по итогу на сегодняшний день

Сейчас “web42-elementor-builder” – это навык, который держит несколько инвариантов:

  • один пользователь – одна открытая задача;

  • task record создается до любого вопроса;

  • вопросы идут только через workflow_cli.py [5] next-question;

  • состояние задач и окружений меняется только через CLI;

  • beta используется по умолчанию;

  • prod не редактируется напрямую;

  • перенос в prod идет через export/import и подтверждение;

  • style audit и spacing builder обязательны для Google Docs сценария;

  • Figma-сценарий идет только через Python compiler;

  • quality gate нельзя проставить словами агента;

  • финальный ответ рендерится отдельно через result_cli.py [5].

Главный вывод

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

AI-агенту нужно четко вносить ограничения в правила, состояние, CLI, guard’ы и проверки. Промпт помогает объяснить намерение, но рабочий навык начинается там, где появляется регламент – кто владеет задачей, где хранится состояние, какие шаги нельзя пропустить, какие действия запрещены, чем подтверждается результат и где агент обязан остановиться. 

На этом все. Дайте знать, если интересно чем в итоге все закончится – отчитаюсь.
А если есть мысли что и как можно доработать – буду рад видеть в комментах.

Спасибо за внимание [13]!

Автор: RomanOpenclaw

Источник [14]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/33499

URLs in this post:

[1] SKILL.md: http://SKILL.md

[2] db.py: http://db.py

[3] логику: http://www.braintools.ru/article/7640

[4] поведения: http://www.braintools.ru/article/9372

[5] cli.py: http://cli.py

[6] long-running-progress.md: http://long-running-progress.md

[7] env-project-guard.md: http://env-project-guard.md

[8] production-transfer.md: http://production-transfer.md

[9] elementor-spacing-builder.md: http://elementor-spacing-builder.md

[10] elementor.py: http://elementor.py

[11] assets.py: http://assets.py

[12] preflight.py: http://preflight.py

[13] внимание: http://www.braintools.ru/article/7595

[14] Источник: https://habr.com/ru/articles/1062724/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1062724

www.BrainTools.ru

Rambler's Top100