Открытая практика / Блог
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 по существующему лайтбоксу.
Находки:
- Блокировка скролла на
body. Мы блокировали прокрутку фона черезoverflow: hiddenнаbodyи компенсировали исчезнувший скроллбар паддингом. Гайд говорит прямо: так делать нельзя. Это убирает скроллбар (вёрстка прыгает), может сбрасывать позицию прокрутки и ломаетposition: sticky. Правильно — чистый CSS:overscroll-behavior: containнаdialog:modalи на::backdrop. - Собственный обработчик Esc. Мы ловили Esc сами, чтобы гарантированно снять
блокировку скролла. Нативный
<dialog>и так закрывается по Esc — обработчик дублировал платформу. Убрали. - Клик по подложке руками. То же самое делает нативный
closedby="any". Оставили свой обработчик только как фолбэк для браузеров без поддержки. - Нет начального фокуса. Гайд требует
autofocusна главном элементе. Поставили на кнопку закрытия.
Итог: минус два обработчика и один хак с паддингом, ноль сдвигов вёрстки, фокус попадает куда надо, а код следует платформе вместо того, чтобы её обходить. Это и есть главный смысл MWG — не «научить модель», а не дать ей изобретать то, что в браузере уже есть.
Как это работает, простыми словами
Представьте разработчика, который пишет рабочий код, но не усвоил чек-лист браузерного инженера: куда ставить фокус, как должен вести себя модальный диалог, какую вещь платформа уже умеет сама. Модель — такой же разработчик, только больше: она пишет быстро и много, но чек-листа не знает.
MWG — это и есть тот чек-лист. Его написали люди, которые делают браузеры. Он доставляется агенту в нужный момент — до написания кода, а не после ревью.
Механика простая:
- Агент получает задачу («сделай модальное окно»).
- Скилл направляет его: найди гайд в базе.
- Агент ищет («accessible modal dialog»), получает конкретный гайд с примерами кода и пометкой о совместимости (Baseline: в каких браузерах и с какой версии это работает).
- Агент пишет по гайду, а результат проверяется по чек-листу — не «на глаз», а по конкретным проверяемым условиям.
Важно: это не «модель стала умнее». Это «модели дали нужный контекст». Модель не обязана помнить всё — она должна знать, где взять проверенный ответ.
Почему это выгодно бизнесу: меньше возвратов и переделок; качество воспроизводимо и не зависит от того, какая модель запущена сегодня; знание ведут инженеры браузеров, поэтому советы агента не устаревают вместе с платформой.
Что интересно коллегам-инженерам и ИИ-экспертам: это пример «внедрения знания», сделанного правильно. Не большая модель, не промпт «на всю жизнь», а поддерживаемая, версионируемая и измеряемая база знаний. Она не привязана к конкретному агенту или харнессу, она кросс-браузерная, а её утверждения подкреплены публичным 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 на одной задаче из списка десяти ошибок и сравните результат с тем, что даёт модель без подсказки. Наш опыт говорит, что разница видна уже на первой странице.