📱 Подписаться
IT и цифровая трансформация

Два способа создания доступного DataPicker'а с помощью AI: 80/20 в пользу AI или системное проектирование с агентом

📰 Habr 👁️ 0 просмотров

inova992 часа назад

Два способа создания доступного DataPicker'а с помощью AI: 80/20 в пользу AI или системное проектирование с агентом

Уровень сложностиПростойВремя на прочтение6 минОхват и читатели3.8KJavaScript*ReactJS*TypeScript*Веб-разработка*Искусственный интеллектКейсВведение

Я открыл демо-версию DatePicker'а, и она выглядела вполне обычно. Поле ввода, кнопка, всплывающий календарь, keyboard navigation, метки для screen reader'ов, макеты для настольных компьютеров и мобильных устройств.

С внешней стороны ничего особенного. Интересным был не сам компонент, а то, как мы его создали.Привет, коллеги!

Меня зовут Илья, я технический директор компании «Исходный код». Наша frontend-команда последние шесть месяцев занималась улучшением доступности компонентов React (a11y). Мы хотели проверить простой вопрос на задаче, которая снаружи выглядит небольшой, но внутри очень быстро разрастается: сможет ли AI-агент создать доступный DatePicker производственного уровня для React и TypeScript?

Ответ — да.

Более точный ответ — да, если рассматривать AI как часть инженерной системы, а не как волшебную машину для печати кода.

Open-source проект доступен по ссылке на Github. Демо-версия DataPicker'а доступна по этой ссылке.

Почему DatePicker — это хороший тест?

DatePicker кажется простым, но это не так.

Сначала появляется сетка календаря и выбранное значение, затем следуют: keyboard navigation, управление фокусом, screen reader'ы, контролируемое состояние, локализация, мобильная верстка, проверки доступности (a11y) и все те мелкие состояния, которые возникают, когда реальные пользователи дважды нажимают или переключаются с помощью клавиши Tab, а затем вновь открывают всплывающее окно или очищают значение.

Мы сравнили два подхода:

• 80% работы доверяем AI, остальные 20% делаем руками (то, что мы делали в предыдущей статье). Вы даете модели подробную подсказку, получаете большую часть компонента, а остальное дорабатываете вручную.
• Системное проектирование с помощью AI-агента. Вы готовите требования, архитектурные правила, задачи, тесты, проверки, и только потом позволяете агенту писать код. При этом, модель дорабатывает результат через итерации и prompt engineering. Подход хорошо описан в документации к инструментупо ссылке.Оба подхода могут работать, разница только в том, где они дают сбой. Давайте посмотрим на них поближе.

Подход 1. 80% работы доверяем AI, остальные 20% делаем руками

Очевидный шаг — дать модели Claude четкий запрос на основе WAI-ARIA APG и попросить ее сгенерировать DatePicker.

Для прототипа этого может быть достаточно, ведь модель знает, как выглядит сетка календаря, она может писать компоненты React, обработчики, атрибуты ARIA и логику keyboard navigation.

Проблема начинается когда первая версия выглядит почти готовой.

Большинство ошибок возникает не внутри отдельного элемента, а на стыках между элементами:

• Строгое следование APG может привести к созданию разметки, которая выглядит правильно, но работает с реальными экранными считывателями хуже, чем контролируемое отклонение от руководства.
• Диалоговое окно может начать мигать из-за того, что обработчики onBlur и onClick конфликтуют друг с другом.
• Разница между атрибутами aria-live="polite" и assertive выглядит незначительной в коде, но становится реальной проблемой UX, когда screen reader начинает озвучивать изменения.В этом заключается главный недостаток разработки с помощью AI. Модель может писать код, который выглядит правильно, но она не может достоверно оценить поведение системы в целом.

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

Подход 2. системное проектирование с помощью AI-агента

Мы выбрали более медленный путь.

Я не хотел одного большого запроса типа «создай мне DatePicker». Мне нужен был контролируемый процесс, в котором у AI-агента было бы меньше возможностей для импровизации и больше давления, чтобы он следовал инженерным правилам.

Агент работал в конфигурации по типу цикла Ralph на основе codex cli и gpt 5.4-mini.

Схема работы Ralph-циклаМы предоставили ему файл AGENTS.md со строгими правилами проекта. В нем агент описывался как старший frontend-инженер, работающий над доступным DatePicker'ом производственного уровня для React и TypeScript.

Полный promt доступен по ссылке.

Затем мы добавили внешнюю память:

• Файл PRD.md был основным источником достоверной информации. В нем были зафиксированы требования: API, поддерживающий только элементы с атрибутом controlled, полная keyboard navigation, правильная разметка ARIA и предсказуемое поведение.
• Файл tasks.json служил для отслеживания задач. Мы разбили работу на небольшие этапы: создание папок, определение типов даты, написание чистых функций даты, создание компонентов UI, а затем их соединение.
• Файл progress.md был рабочим журналом. Агент должен был фиксировать, что изменилось и в каком состоянии находился проект.И задействовали субагентов:

• Специалист по PRD
• Архитектор кода
• Frontend-специалистБлагодаря этому задача «напиши мне DatePicker» превратилась в процесс, в ходе которого создается и проверяется достойный DatePicker.

Результаты:

Результат AI-агента (desktop)Результат AI-агента (mobile)Пример зачитывания screen reader'ом кнопки для открытия DataPicker'аПример зачитывания screen reader'ом ячейки календаряПример отображения DataPicker'а

Верификатор был важнее promt'а

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

Он запускал модульные тесты и тесты доступности с помощью Vitest и Playwright, собирал проект с помощью Vite и проверял типы с помощью tsc -noEmit.

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

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

В результате проект естественным образом перешел к трехуровневой архитектуре:

• Ядро содержало чистую логику в lib/date и lib/input.
• UI содержал «глупые» компоненты без состояния.
• Модель связывала состояние, поведение и представление.Это разделение было сделано не ради красоты, оно снижало затраты на внесение изменений:

• Ошибка в вычислении даты относится к чистой функции.
• Ошибка фокусировки относится к модельному слою.
• Визуальное состояние относится к UI.Нам больше не приходилось отлаживать весь компонент как один большой блок.

Архитектура не решила всех проблем

Я не хочу преподносить это как волшебство, даже хорошая архитектура по-прежнему давала сбои в некоторых местах. Однажды небольшое изменение в расчете недели вызвало каскадную проблему в DatePicker'е, она возникла из слоя, откуда мы этого не ожидали. Это показало нам полезный предел: одних слоев недостаточно, большой системе также нужны контракты между слоями и проверка этих контрактов.

Теперь мы более ответственно подходим к границам. У слоя должно быть не только название, но и контракт, и этот контракт должен тестироваться.

Настоящая разница заключается в стоимости изменений.

Создание кода с помощью AI изначально обходится недорого. Достаточно составить один четкий promt, чтобы получить рабочую v1.0. Для минимально жизнеспособных продуктов (MVP), хакатонов, экспериментов и одноразовых прототипов это зачастую является правильным выбором.

Стоимость проявляется позже.

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

Системная инженерия изначально обходится дорого.

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

Окупаемость проявляется, когда компонент меняется.

Нужен выбор времени? Мы расширяем ядро, добавляем компонент UI и обновляем уровень модели. Остальные части остаются практически нетронутыми. Изменения не бесплатны, но они предсказуемы. Именно эта предсказуемость и является главной ценностью.

Это не борьба методов

Я бы не стал применять системное проектирование с помощью AI-агента повсеместно.

Подход «80% работы доверяем AI, остальные 20% делаем руками» хорошо подходит, когда цена ошибки низкая: прототипы, R&D, хакатоны, изолированные утилиты и эксперименты, которые можно выбросить. Кстати, познакомиться с нашим DataPicker'ом из прошлой статьи можнопо ссылке.

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

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

Что я понял?

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

Заключение

Создание компонента DatePicker'а с использованием AI — это сложно не потому, что React сложен, а потому, что у компонента есть множество мелких требований: состояние, фокус, поведение клавиатуры, вывод для screen reader'ов, логика даты, макет и контролируемое поведение API.

Для меня это главный урок:

Один promt может сгенерировать огромное количество кода, а система может предотвратить отклонение этого кода от заданного курса.Будущее AI в разработке — это не только более совершенные модели, а еще и качественная инженерия вокруг моделей.

Я пока не рассматриваю агентов как автономных разработчиков, но вижу в них сильных исполнителей в рамках контролируемой среды.Теги:• datapicker
• frontend
• claude
• ии
• typescript
• javascript
• web
• ux
• ui
• aiХабы:• JavaScript
• ReactJS
• TypeScript
• Веб-разработка
• Искусственный интеллект

Получайте больше инсайтов о систематизации бизнеса

Подписывайтесь на Telegram-канал Business Operations — ежедневные материалы о бизнес-процессах, операционном управлении и повышении эффективности

💬 Подписаться на канал