Два пути к идеальному DatePicker: классический промптинг или системный подход по работе с AI
- вторник, 28 апреля 2026 г. в 00:00:07
Привет, коллеги!
Сегодня мы копнем в самую суть инженерного подхода. На повестке дня - сравнение двух кардинально разных философий создания сложного UI-компонента. Это не просто рассказ о DatePicker, это анализ стратегического выбора, который каждая команда делает каждый день: скорость в ущерб предсказуемости или наоборот?
Исходный код доступен по ссылке: https://github.com/Codesrc-public-ru/ralf-datapicker
За основу мы возьмем два реальных кейса. Первый - «AI-драфтинг», отлично описанный нашей статье "Создаем WCAG-доступный DatePicker на React: как Claude пишет основу, а мы доводим до ума". Идея: получить 80% кода от нейросети, а остальное довести вручную. Это путь быстрых итераций и реактивного решения проблем.
Второй - «Системный инжиниринг», подход описан в этой документации к инструменту https://github.com/snarktank/ralph. Идея: сначала детальное проектирование, потом итеративная работа модели. Это путь проактивного управления сложностью.
Оба приводят к результату. Но какой ценой? И что скрывается под капотом каждого из них? Давайте разберем.
Этот подход напоминает скоростную сборку прототипа. Берется детальный промпт, основанный на WAI-ARIA APG, и скармливается Claude. На выходе - практически готовый компонент. Кажется, победа, но, как показывает опыт коллег, именно здесь начинается самое интересное.
Проблемы, с которыми они столкнулись, - это классические интеграционные баги:
Конфликт спецификации и реальности: слепое следование APG (ячейки-<td> без button внутри) привело к менее надежной работе скринридеров, чем осознанное отступление от гайда.
Неявное управление состоянием: «моргающий» диалог при повторном клике - типичный баг, когда несколько обработчиков событий (onBlur, onClick) конфликтуют в непредсказуемой последовательности.
Тонкости a11y: проблема с aria-live="polite" против assertive - это не то, что может предсказать AI. Это нюанс UX, который выясняется только при реальном тестировании со скринридером.
Это путь, где продукт создается методом последовательного приближения, а архитектура возникает «случайно» (эмерджентно) в процессе латания дыр.
Наш путь был другим. Мы сразу решили, что управлять разработкой будет не один большой промпт, а целая инженерная система, в которой 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
Сам подход был похож на конвейер:
На каждой итерации агент выбирает задачу из tasks.json
Пишет или меняет код.
Мы запускаем внешний контур проверки (The Verifier). Это не часть агента, а наш собственный скрипт, который прогонял unit- и a11y-тесты (Vitest + Playwright), сборку проекта (Vite build) и проверку типов (tsc --noEmit).
Результаты работы агент записывает в progress.md
Если хоть одна проверка падала - агент получал лог ошибки и команду «переделывай». Он не мог перейти к следующему таску, пока текущий не был идеален. Именно такая система вынудила агента проактивно выстроить ту самую трехслойную архитектуру:
Ядро (lib/date/, lib/input/): чистая логика.
Представление (ui/): «глупые» stateless-компоненты.
Связующий слой (model/): логика, которая всем этим управляет.
Этот подход переносит фокус с «напиши мне DatePicker» на проектирование системы, которая этот DatePicker производит и проверяет, а это и есть проактивная разработка в действии.
Результаты работы агента:





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

AI-драфтинг: низкий порог входа, но стоимость изменений - лотерея. С хорошим промптом AI может выдать отличное, структурированное решение. Но без жестких архитектурных рамок он часто генерирует монолитный код, где любая фича превращается в болезненный рефакторинг. Ключевой риск - непредсказуемость. Техдолг начинает копиться сразу.
Системный инжиниринг: высокая стоимость входа (время на проектирование и большой расход токенов). Нужно добавить поддержку выбора времени? Мы просто расширяем ядро, добавляем новый UI-компонент и обновляем связующий слой. Остальные части системы остаются нетронутыми. Это инвестиция, которая окупается на дистанции.
AI-драфтинг: архитектура сгенерированного кода - это по сути черный ящик. Она неявная и хрупкая. Разделение ответственности отсутствует, что делает код трудным для понимания и отладки. Чтобы починить «моргающий диалог», нужно держать в голове всю картину целиком.
Системный инжиниринг: думаете, хорошая архитектура в большом проекте спасет от всех проблем? Как бы не так. Мы тоже так думали. Разложили все на три слоя, чтобы спокойно вносить правки. А потом небольшое изменение в логике расчета недель привело к каскадному сбою в датапикере. Прилетело оттуда, откуда не ждали. Это не значит, что подход плохой. Это значит, что для больших систем его недостаточно. Теперь мы всегда добавляем четкие «контракты» между слоями и автоматическую валидацию. Это как отбойники на трассе - не дают случиться аварии.
Это самый показательный пункт.
Самая частая ошибка при работе с 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-разработчик в “Исходном Коде”.
А какой стратегии придерживаетесь вы? Где для вас проходит граница, за которой скорость перестает оправдывать риски?