Зелёный СветТехнологический партнёр

Открытая практика / Блог

Modern Web Guidance на практике: как мы встроили браузерные стандарты в пайплайны

Агенты пишут наш веб-код — и систематически ошибаются в десяти областях. Разбираем, как мы внедрили Modern Web Guidance в пайплайны и что дал первый пилот: доступность 0.90 → 1.00 за три правки.

Мы в GreenLight делаем сайты и агентные системы. Большую часть кода пишут ИИ-агенты — так быстрее, и для типовых задач результат хороший. Но в начале ноября Google выпустил набор под названием Modern Web Guidance (MWG), и его главная идея объяснила нам, чего нам не хватало.

Проблема, которую измеряют, а не обсуждают

MWG — это не библиотека и не фреймворк, а слой знаний для агента: база гайдов, которые писали и проверяли инженеры браузеров, с данными о совместимости фич между Chrome, Firefox и Edge. Скилл заставляет агента искать гайд до того, как писать HTML, CSS или клиентский JS, — вместо того чтобы полагаться на память весов.

Причина проста: агенты систематически ошибаются в одних и тех же местах. В статье Google перечисляет десять областей — фокус и inert, reduced-motion, формы и autofill, свайпы, диалоги и popover, тёмная тема, отзывчивость (INP), сдвиги раскладки (CLS), защита от DOM XSS и санитизация, passkeys и WebAuthn. По измерениям Google, агенты без MWG проходят примерно половину проверок, с MWG — около 90%.

Для студии, которая продаёт веб-интерфейсы, это не абстрактная метрика. Это качество того, что мы отдаём клиенту.

Мы не стали верить на слово — измерили свой сайт

Первый шаг был скучным и правильным: замерить baseline. Мы прогнали Lighthouse по нашему сайту-полигону (живой, прод) и получили картину, которую приятно цитировать только целиком:

Категория Оценка
Performance 0.89
Accessibility 0.90
Best Practices 1.00
SEO 1.00

Вроде неплохо. Но детали важнее баллов:

  • Контраст текста 3.28:1 вместо требуемых WCAG 4.5:1 — серый #8a8a8a на светлом фоне #faf9f7. Для пользователя с ослабленным зрением это текст, который тяжело читать.
  • Ссылка корзины без имени — иконка без подписи. Программа чтения с экрана объявляет её просто как «ссылка», без контекста.
  • LCP 3.8 секунды — главное изображение страницы не было ни предзагружено, ни помечено приоритетом, и браузер узнавал о нём только после запуска JS.

Обратите внимание: все три находки — из списка десяти ошибок, которые Google называет системными для агентов. Это не случайность и не невнимательность модели. Это то, что агент не знает без подсказки.

Три правки вместо переписывания

Мы применили MWG как предусмотрено: агент ищет гайд по конкретной задаче, читает его и правит код.

1. Контраст. Гайд по цвету и контрасту требует 4.5:1 для обычного текста. Мы подобрали серый #6f6f6f — на том же фоне он даёт 4.78:1. Визуально почти то же самое, а требование закрыто. Одна строка в токенах темы.

2. Имя для иконки-ссылки. Гайд по иконкам и доступности: у интерактивного элемента должно быть доступное имя. Добавили aria-label к обеим ссылкам корзины (десктоп и мобильная версия) — две строки.

3. Приоритет главного изображения. Гайд по LCP: изображение должно быть «открываемым» из начального HTML и загружаться с высоким приоритетом. Добавили preload в <head> и fetchpriority="high" на сам <img>.

Результат, который можно проверить

Повторный аудит той же страницы после правок:

Показатель До После
Accessibility 0.90 1.00
Находок по контрасту 12+ 0
Находок по именам ссылок 1 0

Балл доступности вырос до единницы, и — что важнее — обе конкретные находки закрыты детерминированно: мы проверили их по элементам, а не по общему впечатлению.

Честная оговорка про производительность: мы мерили текстовый контур на локальной сборке, а локальный сервер — не production, поэтому сравнивать секунды LCP «до» и «после» между окружениями некорректно. Правка LCP применена и проверена в разметке (preload и fetchpriority присутствуют в DOM), но её эффект в секундах мы измерим только после выкладки на прод — и мы не будем утверждать цифру, которую не видели.

Второй случай: код, который уже прошёл ревью

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

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

Перед написанием кода мы прогнали гайд MWG dialog по существующему лайтбоксу. Находки:

  1. Блокировка скролла на body. Мы блокировали прокрутку фона через overflow: hidden на body и компенсировали исчезнувший скроллбар паддингом. Гайд говорит прямо: так делать нельзя. Это убирает скроллбар (вёрстка прыгает), может сбрасывать позицию прокрутки и ломает position: sticky. Правильно — чистый CSS: overscroll-behavior: contain на dialog:modal и на ::backdrop.
  2. Собственный обработчик Esc. Мы ловили Esc сами, чтобы гарантированно снять блокировку скролла. Нативный <dialog> и так закрывается по Esc — обработчик дублировал платформу. Убрали.
  3. Клик по подложке руками. То же самое делает нативный closedby="any". Оставили свой обработчик только как фолбэк для браузеров без поддержки.
  4. Нет начального фокуса. Гайд требует autofocus на главном элементе. Поставили на кнопку закрытия.

Итог: минус два обработчика и один хак с паддингом, ноль сдвигов вёрстки, фокус попадает куда надо, а код следует платформе вместо того, чтобы её обходить. Это и есть главный смысл MWG — не «научить модель», а не дать ей изобретать то, что в браузере уже есть.

Как это работает, простыми словами

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

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

Механика простая:

  1. Агент получает задачу («сделай модальное окно»).
  2. Скилл направляет его: найди гайд в базе.
  3. Агент ищет («accessible modal dialog»), получает конкретный гайд с примерами кода и пометкой о совместимости (Baseline: в каких браузерах и с какой версии это работает).
  4. Агент пишет по гайду, а результат проверяется по чек-листу — не «на глаз», а по конкретным проверяемым условиям.

Важно: это не «модель стала умнее». Это «модели дали нужный контекст». Модель не обязана помнить всё — она должна знать, где взять проверенный ответ.

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

Что интересно коллегам-инженерам и ИИ-экспертам: это пример «внедрения знания», сделанного правильно. Не большая модель, не промпт «на всю жизнь», а поддерживаемая, версионируемая и измеряемая база знаний. Она не привязана к конкретному агенту или харнессу, она кросс-браузерная, а её утверждения подкреплены публичным eval-дашбордом. Вопрос инженерии смещается с «какая модель лучше» на «какой контекст нужен модели, чтобы сделать работу правильно».

Главное — не разовая уборка, а пайплайн

Разовая правка сайта ничего не меняет в следующем проекте. Поэтому мы встроили MWG в наши пайплайны — контракты, по которым агенты собирают сайты.

Как это выглядит в контракте:

  • Веб-гейт обязателен для любого пайплайна, который порождает HTML, CSS или клиентский JS. Агент консультирует MWG до написания кода, а результат проверяется по нашему стандарту качества сайта.
  • Гейт — это инвариант результата, а не шаг процесса. Мы не указываем агенту, как именно делать; мы требуем, чтобы результат проходил проверку.
  • Стандарт качества сайта теперь ссылается на MWG как на механизм: раздел доступности закрывается гайдами accessibility/* и forms/*, производительность — performance/*, безопасность — security/*.

Так MWG перестаёт быть «ещё одной скиллкой для агента» и становится частью контракта — тем самым набором правил, которые мы и так используем для пайплайнов.

Что мы поняли про инструмент

  • legacy-scan узок. Мы прогнали его по двум своим репозиториям — ноль находок. Он покрывает 33 гайда из примерно 160. Это подсказка, а не аудит; не стоит продавать его клиенту как «автоматическую модернизацию».
  • Ценность — в поиске при написании. Реальный выигрыш даёт момент, когда агент ищет гайд под конкретную задачу и пишет по нему, а не по памяти.
  • Это дисциплина, а не вера. MWG сам построен на проверяемых ожиданиях и публичном eval-дашборде. Мы можем замерять свой результат до и после, а не соглашаться с обещаниями.
  • Оно находит ошибки в уже отревьюенном коде. Лайтбокс был сделан и проверен до MWG — гайд нашёл в нём четыре проблемы, включая одну, которую мы сами считали необходимой (ручная блокировка скролла). Дело не в «слабой модели», а в чек-листе, которого в контексте не было.

Что дальше

Мы держим MWG в контуре пайплайнов и продолжаем измерять. Следующий шаг — прогнать веб-гейт на нескольких задачах из списка десяти ошибок и посчитать собственный «pass rate» до и после, как это делает Google. Если цифра окажется такой же убедительной, как балл доступности 0.90 → 1.00, мы опубликуем и её.

Мы также переносим найденное в стандарт качества сайта: раздел доступности теперь опирается на гайды MWG, а не на общие рекомендации. Чтобы следующий агент — или следующая модель — не изобрёл то же самое заново.


Если вы строите сайты в агентном контуре — попробуйте MWG на одной задаче из списка десяти ошибок и сравните результат с тем, что даёт модель без подсказки. Наш опыт говорит, что разница видна уже на первой странице.