Два пути к идеальному DatePicker: классический промптинг или системный подход по работе с AI

Два пути к идеальному DatePicker: классический промптинг или системный подход по работе с AI

Привет, коллеги!

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

Исходный код доступен по ссылке:https://github.com/Codesrc-public-ru/ralf-datapicker

За основу мы возьмем два реальных кейса. Первый -«AI-драфтинг», отлично описанный нашей статье "Создаем WCAG-доступный DatePicker на React: как Claude пишет основу, а мы доводим до ума". Идея: получить 80% кода от нейросети, а остальное довести вручную. Это путь быстрых итераций и реактивного решения проблем.

Второй -«Системный инжиниринг», подход описан в этой документации к инструментуhttps://github.com/snarktank/ralph. Идея: сначала детальное проектирование, потом итеративная работа модели. Это путь проактивного управления сложностью.

Оба приводят к результату. Но какой ценой? И что скрывается под капотом каждого из них? Давайте разберем.

Подход №1: AI-драфтинг. Реактивная разработка

Этот подход напоминает скоростную сборку прототипа. Берется детальный промпт, основанный на WAI-ARIA APG, и скармливается Claude. На выходе - практически готовый компонент. Кажется, победа, но, как показывает опыт коллег, именно здесь начинается самое интересное.

Проблемы, с которыми они столкнулись, - это классическиеинтеграционные баги:

  • Конфликт спецификации и реальности:слепое следование APG (ячейки- без button внутри) привело к менее надежной работе скринридеров, чем осознанное отступление от гайда.
  • Неявное управление состоянием:«моргающий» диалог при повторном клике - типичный баг, когда несколько обработчиков событий (onBlur, onClick) конфликтуют в непредсказуемой последовательности.
  • Тонкости a11y:проблема с aria-live="polite" против assertive - это не то, что может предсказать AI. Это нюанс UX, который выясняется только при реальном тестировании со скринридером.

Это путь, где продукт создается методом последовательного приближения, а архитектура возникает «случайно» (эмерджентно) в процессе латания дыр.

Подход №2: Не кодер, а система. Как мы запрягли AI-агента.

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

В роли исполнителя у нас был подходRalph цикла- кастомный автономный агент на базе codex cli с моделью gpt 5.4-mini. Чтобы он не «фантазировал», мы написали ему жесткийсистемный промпт, который был буквально впечатан в его «личность» (AGENTS.md):

  • # Accessible DatePicker - Project Architecture & Coding Rules

You are a senior frontend engineer and software architect working on a production-grade, accessible DatePicker component for React + TypeScript.

Полный промпт находитсявот тут.

Его реальным «мозгом» и «памятью» стал набор внешних файлов, который мы подкладывали в его рабочую директорию:

  • PRD.md(Product Requirements Document):наш свод законов. Там было черным по белому: controlled-only API, полная навигация с клавиатуры, корректная aria-разметка. Это незыблемые принципы.
  • tasks.json:детальный таск-трекер для агента. Мы декомпозировали всю работу на атомарные шаги: «создай структуру каталогов», «опиши типы для дат», «напиши чистую функцию addMonths», «собери UI-компонент Button».
  • Использованные субагенты:Специалист по ПРД -https://subagents.cc/agents/prd-specialistАрхитектор кода -https://subagents.cc/agents/code-architectФронтендер -https://subagents.cc/agents/frontend-developer

Сам подход был похож на конвейер:

  1. На каждой итерации агент выбирает задачу из tasks.json
  2. Пишет или меняет код.
  3. Мы запускаем внешний контур проверки (The Verifier). Это не часть агента, а наш собственный скрипт, который прогонял unit- и a11y-тесты (Vitest + Playwright), сборку проекта (Vite build) и проверку типов (tsc --noEmit).
  4. Результаты работы агент записывает вprogress.md

Если хоть одна проверка падала - агент получал лог ошибки и команду «переделывай». Он не мог перейти к следующему таску, пока текущий не был идеален. Именно такая системавынудилаагента проактивно выстроить ту самую трехслойную архитектуру:

  • Ядро (lib/date/, lib/input/):чистая логика.
  • Представление (ui/):«глупые» stateless-компоненты.
  • Связующий слой (model/):логика, которая всем этим управляет.

Этот подход переносит фокус с «напиши мне DatePicker» на проектирование системы, которая этот DatePicker производит и проверяет, а это и есть проактивная разработка в действии.

Результаты работы агента:

Сравниваем в лоб: цена, качество, риски

Давайте сведем все в таблицу и разберем детально.

1. Экономика и стоимость изменения (Cost of Change)

  • AI-драфтинг:низкий порог входа, но стоимость изменений - лотерея. С хорошим промптом AI может выдать отличное, структурированное решение. Но без жестких архитектурных рамок он часто генерирует монолитный код, где любая фича превращается в болезненный рефакторинг. Ключевой риск - непредсказуемость. Техдолг начинает копиться сразу.
  • Системный инжиниринг:высокая стоимость входа (время на проектирование и большой расход токенов). Нужно добавить поддержку выбора времени? Мы просто расширяем ядро, добавляем новый UI-компонент и обновляем связующий слой. Остальные части системы остаются нетронутыми. Это инвестиция, которая окупается на дистанции.

2. Архитектура и управление сложностью

  • AI-драфтинг:архитектура сгенерированного кода - это по сутичерный ящик. Она неявная и хрупкая. Разделение ответственности отсутствует, что делает код трудным для понимания и отладки. Чтобы починить «моргающий диалог», нужно держать в голове всю картину целиком.
  • Системный инжиниринг:думаете, хорошая архитектура в большом проекте спасет от всех проблем? Как бы не так. Мы тоже так думали. Разложили все на три слоя, чтобы спокойно вносить правки. А потом небольшое изменение в логике расчета недель привело к каскадному сбою в датапикере. Прилетело оттуда, откуда не ждали. Это не значит, что подход плохой. Это значит, что для больших систем его недостаточно. Теперь мы всегда добавляем четкие «контракты» между слоями и автоматическую валидацию. Это как отбойники на трассе - не дают случиться аварии.

3. Типология и локализация ошибок

Это самый показательный пункт.

  • Самая частая ошибка при работе сAI-драфтингом- верить, что он сам все сделает правильно. Не сделает. Его главная слабость - интеграция. Он может идеально написать два модуля по отдельности, но на их стыке начнется хаос: ошибки состояния, рендера, событий. А все потому, что у AI нет понимания «правильно/неправильно», он просто выполняет задачу. Наш подход - не исправлять баги, а не давать им появиться. Мы внедряем «гардрейлы» (guard rails) - это набор жестких требований и инструкций, которые AI обязан соблюдать. По сути, мы заставляем его думать об архитектуре. В этом датапикереhttps://github.com/Codesrc-public-ru/datepickerмодули как раз явные. И такой подход снижает риск скрытых дефектов в разы.
  • Системный инжинирингсмещает ошибки на уровеньюнитов. Если календарь неправильно показывает февраль в високосный год, мы знаем, что проблема находится в одной конкретной чистой функции в слое Core. Эта ошибка легко покрывается юнит-тестом и исправляется изолированно. Мы не чиним «компонент», мы чиним «алгоритм».

Итог: это не битва, а выбор стратегии управления рисками

Становится очевидно, что это не спор о том, «что лучше». Это стратегический выбор, основанный на контексте.

AI-драфтинг - это стратегия для задач с низкой ценой ошибки:

  • Прототипы и MVP:когда нужно быстро проверить гипотезу и выкинуть.
  • R&D и хакатоны:когда скорость исследования важнее долгосрочной поддержки.
  • Изолированные, некритичные утилиты.

Системный инжиниринг - это стратегия для задач с высокой ценой ошибки:

  • Разработка дизайн-систем:где каждый компонент - это продукт для десятков других команд.
  • Создание ядра приложения:где надежность и предсказуемость - не пустые слова.
  • Долгосрочные проекты:где вы знаете, что компонент будет жить, развиваться и рефакториться годами.

Познакомиться с нашим интерактивным проектом можно по ссылке:https://ralf-datapicker.netlify.app/

Наш следующий шаг -гибридный подход. Мы продолжим использовать системный инжиниринг для проектирования, но будем делегировать AI рутинные, хорошо формализованные задачи. Например: «Вот спецификация нашего математического ядра и тесты. Напиши Storybook-истории для вот этого ‘глупого’ UI-компонента сетки календаря».

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

Автор статьи:Ищенко Тимофей@Is_Tim, senior frontend-разработчик в “Исходном Коде”.

А какой стратегии придерживаетесь вы? Где для вас проходит граница, за которой скорость перестает оправдывать риски?

Читать оригинал