惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
U
Unit 42
GbyAI
GbyAI
M
MIT News - Artificial intelligence
美团技术团队
罗磊的独立博客
雷峰网
雷峰网
量子位
博客园 - 【当耐特】
Last Week in AI
Last Week in AI
D
Docker
小众软件
小众软件
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
阮一峰的网络日志
阮一峰的网络日志
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
WordPress大学
WordPress大学
V
V2EX
博客园_首页
腾讯CDC
The Cloudflare Blog
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания
Два способа создания доступного DataPicker
Илья Новиков · 2026-06-28 · via Все публикации подряд на Хабре

Простой

6 мин

1.1K

Введение

Я открыл демо-версию 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, а затем вновь открывают всплывающее окно или очищают значение.

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

  1. 80% работы доверяем AI, остальные 20% делаем руками (то, что мы делали в предыдущей статье). Вы даете модели подробную подсказку, получаете большую часть компонента, а остальное дорабатываете вручную.

  2. Системное проектирование с помощью AI-агента. Вы готовите требования, архитектурные правила, задачи, тесты, проверки, и только потом позволяете агенту писать код. При этом, модель дорабатывает результат через итерации и prompt engineering. Подход хорошо описан в документации к инструменту по ссылке.

Оба подхода могут работать, разница только в том, где они дают сбой. Давайте посмотрим на них поближе.

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

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

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

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

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

  1. Строгое следование APG может привести к созданию разметки, которая выглядит правильно, но работает с реальными экранными считывателями хуже, чем контролируемое отклонение от руководства.

  2. Диалоговое окно может начать мигать из-за того, что обработчики onBlur и onClick конфликтуют друг с другом.

  3. Разница между атрибутами aria-live="polite" и assertive выглядит незначительной в коде, но становится реальной проблемой UX, когда screen reader начинает озвучивать изменения.

В этом заключается главный недостаток разработки с помощью AI. Модель может писать код, который выглядит правильно, но она не может достоверно оценить поведение системы в целом.

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

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

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

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

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

Схема работы Ralph-цикла

Схема работы Ralph-цикла

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

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

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

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

  • Файл tasks.json служил для отслеживания задач. Мы разбили работу на небольшие этапы: создание папок, определение типов даты, написание чистых функций даты, создание компонентов UI, а затем их соединение.

  • Файл progress.md был рабочим журналом. Агент должен был фиксировать, что изменилось и в каком состоянии находился проект.

И задействовали субагентов:

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

Результаты:

Результат AI-агента (desktop)

Результат AI-агента (desktop)

Результат AI-агента (mobile)

Результат AI-агента (mobile)

Пример зачитывания screen reader'ом кнопки для открытия DataPicker'а

Пример зачитывания screen reader'ом кнопки для открытия DataPicker'а

Пример зачитывания screen reader'ом ячейки календаря

Пример зачитывания screen reader'ом ячейки календаря

Пример отображения DataPicker'а

Пример отображения DataPicker'а

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

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

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

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

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

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

  1. Ядро содержало чистую логику в lib/date и lib/input.

  2. UI содержал «глупые» компоненты без состояния.

  3. Модель связывала состояние, поведение и представление.

Это разделение было сделано не ради красоты, оно снижало затраты на внесение изменений:

  • Ошибка в вычислении даты относится к чистой функции.

  • Ошибка фокусировки относится к модельному слою.

  • Визуальное состояние относится к UI.

Нам больше не приходилось отлаживать весь компонент как один большой блок.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Что я понял?

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

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

Заключение

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

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

Один promt может сгенерировать огромное количество кода, а система может предотвратить отклонение этого кода от заданного курса.

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

Я пока не рассматриваю агентов как автономных разработчиков, но вижу в них сильных исполнителей в рамках контролируемой среды.