AI в рабочем процессе фронтендера
Вы не пишете код руками — вы пишете спецификацию человеческим языком, отправляете её в контекстное окно агенту (Claude Code, OpenCode, Codex) и проверяете результат. Эффективность этого цикла зависит от трёх вещей: качества спецификации, правил, которые вы задаёте агенту заранее, и дисциплины проверки. Эта статья — о реальном рабочем цикле: как Spec-Driven Development формализует «спецификация → генерация → проверка», где AI силён, а где ломается, как выстроить проверку результата и когда агенту нельзя доверять. Для каждой задачи приведены критерии применимости и таблицы сравнения, а в конце — сквозной пример от спецификации до продакшена.
Содержание
- Цикл: спецификация → генерация → проверка
- Spec-Driven Development: методология
- Где AI силён, а где ненадёжен
- Задачи рабочего процесса
- AGENTS.md: правила для агента
- Как формулировать задачу агенту
- Управляемая генерация vs вайбкодинг
- Когда агент врёт и как это ловить
- Когда использовать AI, а когда нет
- Case study: от спецификации до продакшена
- Ключевые тезисы для интервью
- Заключение
- Полезные ссылки
Цикл: спецификация → генерация → проверка
Работа через агентов — это не «отдать задачу и получить код». Это цикл, где вы играете роль архитектора и ревьюера, а агент — исполнителя:
1. Спецификация → что делать, как должно выглядеть, критерии качества
2. Генерация → агент пишет код по спецификации
3. Проверка → вы проверяете результат против спецификации
4. Итерация → несоответствия возвращаются агенту с уточнением
Критерии выхода на каждом этапе
Цикл работает только если у каждого этапа есть чёткий признак завершения. Иначе «генерация» длится вечно, а «проверка» превращается в ощущение.
| Этап | Вход | Критерий выхода | Чем измерить |
|---|---|---|---|
| Спецификация | Задача/фича | Сформулированы поведение, границы, edge cases и критерии приёмки | Может ли другой разработчик выполнить по ней задачу без уточнений |
| Генерация | Спецификация | Код + тесты по спецификации, пройдены lint и типы | Файлы созданы, команды из AGENTS.md отработали |
| Проверка | Код + спецификация | Каждый пункт спецификации подтверждён тестом или явным ревью | Сверка «спецификация → тест» построчно |
| Итерация | Список несоответствий | Агент исправил именно указанное, ничего не сломал | Повторный прогон тестов и сверки |
Без критериев выхода цикл вырождается в бесконечный диалог «сделай лучше» — худшая форма работы с агентами: она тратит токены и время, но не приближает к готовности.
Спецификация — это продукт разработчика
Качество кода агента напрямую определяется качеством спецификации. Абстрактная задача даёт код с допущениями; конкретная — рабочий результат.
// Плохо: абстрактно
Сделай компонент загрузки файлов
// Хорошо: конкретно
Создай React-компонент FileUpload:
- Drag & drop зона с подсветкой при hover
- Поддержка множественной загрузки, максимум 5 файлов
- Валидация: только image/* и application/pdf, макс 10MB каждый
- Прогресс-бар для каждого файла во время загрузки
- Обработка ошибок: сообщение под файлом, возможность повторить
- API: POST /api/upload, FormData
- TypeScript, без библиотек для drag&drop
- Компонент контролируемый: value и onChange
Разница радикальная: первый вариант даст «общий» компонент с десятком допущений, второй — код, который можно использовать.
Спецификация — это и критерии приёмки
В спецификацию включайте не только что делать, но и как проверить, что сделано правильно. Это позволяет передавать результат обратно агенту с точными замечаниями, а не с ощущением «что-то не то». Критерий приёмки должен быть проверяемым: либо тестом, либо однозначным условием. «Кнопка красиво анимируется» — не критерий, «на submit кнопка disabled и показывает спиннер» — критерий.
Spec-Driven Development: методология
Spec-Driven Development (SDD) — методология, где спецификация является единственным источником истины. Разработчик описывает что нужно сделать, LLM генерирует как это реализовать, а тесты служат критерием готовности.
Традиционный подход: Ты → Код → Тесты → Документация
SDD: Ты → Спецификация → LLM → Код + Тесты
Спецификация заменяет сразу три артефакта: тесты (LLM генерирует их из спецификации), документацию (спецификация и есть документация) и требования (всё записано явно).
SDD vs TDD: что изменилось
| Аспект | TDD | SDD |
|---|---|---|
| Кто пишет тесты | Человек вручную | LLM из спецификации |
| Кто пишет код | Человек вручную | LLM из спецификации |
| Скорость итерации | Минуты | Секунды |
| Фокус внимания | «Как» реализовано | «Что» должна делать система |
| Источник истины | Тесты + код | Спецификация |
Важно: SDD не отменяет TDD как принцип («сначала тесты, потом код»). Отменяется только ручная механика — тесты пишет не человек, а LLM, но пишет их до реализации по поведению из спецификации.
Три столпа SDD
- Спецификация — единственный источник истины: поведение, сценарии, ограничения, критерии готовности. Правило: спецификация описывает поведение, не реализацию.
- Генерация — LLM превращает спецификацию в код, тесты, моки, документацию. Правило: один промпт — одна генерация.
- Верификация — тесты: критерий готовности, обратная связь для LLM, документация для людей. Правило: без тестов нет готовности.
Анатомия спецификации
Обязательные элементы:
## Функция: formatDate
### Поведение:
- Принимает: date (Date), locale (string)
- Возвращает: string
- Формат зависит от locale
### Примеры:
formatDate(new Date('2024-01-15'), 'ru-RU') → '15.01.2024'
formatDate(new Date('2024-01-15'), 'en-US') → '01/15/2024'
### Edge cases:
- Invalid date → throws Error
- Unknown locale → uses default 'en-US'
### Ограничения:
- Поддержка только Gregorian calendar
- Локали: 'ru-RU', 'en-US', 'de-DE'
Опционально: контекст, зависимости, требования к производительности. Формат — Markdown: читаем для людей, понятен LLM, версионируется в git.
Каждый элемент спецификации отвечает на конкретный вопрос:
| Элемент | Отвечает на вопрос | Без него |
|---|---|---|
| Поведение | Что система делает? | Агент придумает своё «разумное» поведение |
| Примеры | Как это выглядит на данных? | Нельзя проверить результат — тесты не на что опереть |
| Edge cases | Что на границах? | Happy path реализован, но баги на пустых/невалидных данных |
| Ограничения | Что запрещено? | Агент использует неподходящую библиотеку или подход |
| Критерии приёмки | Когда считаем готовым? | Нет основания для проверки и итераций |
Роль тестов в SDD
Тесты — это definition of done: нет тестов — нет готовности. Они же дают LLM обратную связь — без тестов агент не знает, работает ли код, потому что «выглядит нормально» ≠ работает. Запуск тестов — шаг валидации, а упавший тест возвращается агенту с выводом ошибки, а не чинится вручную.
Тесты в SDD выполняют три функции одновременно:
- Критерий готовности — фича не завершена, пока тесты не зелёные.
- Обратная связь для LLM — вывод ошибки теста агент использует для исправления.
- Документация для людей — по тестам видно публичное API и ожидаемое поведение.
Роль разработчика
Разработчик пишет спецификации, валидирует результат, итерирует и ревьюит (удаляет мусорные тесты, следит за архитектурой). Он не пишет код и тесты руками (если не критично), не отлаживает руками и не пишет документацию — спецификация и есть документация. Новые навыки: spec-writing, prompt-engineering, review skills.
Когда SDD не подходит
- Исследовательские задачи — прототипы, proof of concept, когда не знаешь, что нужно → vibe coding.
- Trivial задачи — опечатка, константа, простой рефакторинг → прямое редактирование.
- Legacy без тестов — сначала characterization tests для существующего поведения, потом SDD для новых фич.
- Критичные системы — медицина, финансы, авиация: требуется ручное ревью каждой строки.
Где AI силён, а где ненадёжен
Надёжные задачи
AI наиболее эффективен там, где есть чёткая спецификация и устоявшиеся паттерны — чем больше примеров модель «видела» при обучении, тем выше качество:
- CRUD и boilerplate: формы, таблицы, API-клиенты, роутинг
- Утилитарные функции: форматирование дат, валидация, парсинг, трансформация данных
- Конвертация форматов: JSON ↔ TypeScript типы, CSS → inline styles, HTML → JSX
- Шаблоны по описанию: «компонент с debounce-поиском»
// Паттерн useDebounce встречается в обучающих данных тысячи раз —
// такой код будет рабочим из коробки
function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
Ненадёжные задачи
- Бизнес-логика с неочевидными правилами — модель не знает ваших внутренних требований и доменных ограничений
- Архитектурные решения с трейдоффами — выбор зависит от контекста проекта, который модель не видит целиком
- Код, зависящий от специфичных версий библиотек — модель может использовать API, устаревший в вашей версии, или ещё не существующий
- Performance-критичные пути — AI оптимизирует читаемость, а не производительность
Таблица: признак надёжности
Ключевой признак, по которому можно решить до генерации — насколько задача паттерновая и изолированная.
| Признак | Надёжно | Ненадёжно |
|---|---|---|
| Паттерн | Устоявшийся (формы, хуки, клиенты) | Уникальный для вашего домена |
| Изоляция | Чистая функция, отдельный модуль | Пересекает много модулей, глобальное состояние |
| Знание контекста | Всё нужное можно записать в спецификацию | Зависит от негласных решений проекта |
| Проверяемость | Результат проверяется тестом | «Работает?» сложно формализовать |
| Версии библиотек | Стандартный API | Экзотические версии, свежие изменения |
Практическое правило: если задачу можно описать так, что другой разработчик решит её без встречи с вами — генерация будет надёжной. Если нет — агент тоже не справится.
Паттерн: итеративная генерация
Вместо попытки сгенерировать всё сразу — разбиваем на этапы, где вывод каждого становится входом следующего (prompt chaining):
// Этап 1: скелет компонента с типами
const skeleton = await generate(`
Создай TypeScript-типы и сигнатуры для FileUpload:
- Props: value, onChange, accept, maxSize, maxFiles
- Internal state: файлы, статусы, прогресс, ошибки
Не пиши реализацию — только типы и пустые функции.
`);
// Этап 2: реализация ключевой логики
const coreLogic = await generate(`
Реализуй handleFiles для FileUpload:
- Валидация типа и размера
- Добавление в state с уникальным id
- Уведомление через onChange
${skeleton}
`);
// Этап 3: UI и UX-детали
const ui = await generate(`
Реализуй рендер FileUpload:
- Drop zone с обработчиками drag events
- Список файлов с прогресс-барами
- Сообщения об ошибках под каждым файлом
${coreLogic}
`);
Каждый этап — фокусированная задача с понятным критерием качества. Это прямое применение prompt chaining: сложная задача разбивается на последовательность простых, где ошибка раннего этапа не «размазывается» по всему результату.
Когда итеративная генерация нужна, а когда нет
| Случай | Подход | Почему |
|---|---|---|
| Компонент с нестандартной логикой | Итеративная генерация | Ошибка скелета не замаскируется реализацией |
| Типовой CRUD/boilerplate | Один промпт | Паттерн известен, лишние вызовы — лишние токены и latency |
| Рефакторинг крупного модуля | Итеративная, с тестами между этапами | Безопасность: поведение контролируется на каждом шаге |
| Прототип | Один промпт | Точность не критична, скорость важнее |
Задачи рабочего процесса
Code review: AI как first-pass рецензент
AI эффективен как первый проход review — он находит категорию проблем быстро и без усталости. Но его находки — не приговор, а кандидаты на проверку.
| Что AI находит хорошо | Что AI пропускает |
|---|---|
| Очевидные баги: обращение к undefined, забытый cleanup, missing dependency | Архитектурные проблемы, видимые только в контексте проекта |
| Нарушения идиом: мутация state, синхронные операции в async-контексте | Нарушение негласных соглашений команды |
Паттерны безопасности: XSS через dangerouslySetInnerHTML, отсутствие валидации | Проблемы, требующие знания бизнес-логики |
| Стилистические проблемы | Тонкие race conditions и concurrency-баги |
Вместо общего «проверь код» — сузить фокус до конкретной категории:
const securityReview = `Проанализируй этот код на уязвимости:
- XSS: пользовательский ввод → DOM
- Injection: пользовательский ввод → запросы
- Data leakage: чувствительные данные в логах или URL
\`\`\`tsx
${code}
\`\`\``;
Сужение фокуса даёт более глубокий анализ в конкретной области — модель не распыляется на все категории сразу.
Когда использовать AI-review:
- ✅ Как первый проход перед человеческим ревью — снять очевидное
- ✅ Для проверки диффа на специфичную категорию (security, performance, a11y)
- ✅ Для объяснения чужого кода при онбординге
- ❌ Как замену ревьюера — архитектурные решения и доменную логику человек видит лучше
- ❌ Как финальное «благословение» на merge — решения принимает человек
Объяснение чужого кода
Одна из самых сильных сторон AI — первое приближение к незнакомой кодовой базе. Но AI-объяснение — гипотеза, а не истина: модель интерпретирует код на основе паттернов, а не намерений автора. Если код содержит баг, AI может «объяснить» баг как фичу. Проверяйте объяснение against исходным кодом, а вместо пассивного чтения ведите активный диалог серией вопросов («Что происходит в useEffect на строке 42?», «Почему здесь useReducer вместо useState?»).
Рефакторинг под присмотром
AI хорошо справляется с механическими рефакторингами, где правила чёткие: конвертация class → hooks, callback → async/await, извлечение утилит, приведение к единому стилю. Плохо — с семантическими, где нужно сохранить инварианты: смена state management, изменение публичного API, оптимизация производительности без бенчмарков.
| Тип рефакторинга | Пример | Надёжность |
|---|---|---|
| Механический | class → hooks, callback → async/await | Высокая — правила однозначны |
| Структурный | split/merge файлов, извлечение утилит | Средняя — нужно проверять связи |
| Семантический | смена state management, изменение API | Низкая — инварианты невидимы в коде |
| Производительность | оптимизация hot path | Низкая — AI «оптимизирует» по шаблонам, не по бенчмаркам |
Ключевой принцип — рефакторинг не меняет поведение, и AI нужно явно сказать это: «Сохранить все lifecycle-поведение, порядок side effects, не менять публичные методы». Комбинация с генерацией тестов на текущее поведение даёт страховку: тесты фиксируют поведение, рефакторинг его сохраняет, проверка обнаруживает отклонения.
Генерация тестов
Тесты — задача с идеальной структурой для AI: чёткий формат, конкретный вход, проверяемый выход. Но ключевой паттерн — тесты по спецификации, а не по коду. Просить «напиши тесты для этого кода» — ошибка: модель сгенерирует тесты, которые проверяют реализацию вместе с её багами.
// Плохо: тесты по реализации
Напиши тесты для функции formatDate: <код>
// Хорошо: тесты по спецификации
Напиши тесты для formatDate по спецификации:
- Принимает Date и формат-строку (DD.MM.YYYY, YYYY-MM-DD, relative)
- Формат "relative": "только что" (<1 мин), "N мин назад" (<1 ч),
"N ч назад" (<24 ч), "вчера", "DD.MM.YYYY" (старше 24 ч)
- Часовой пояс: UTC
- Невалидный ввод: возвращает "—"
Не смотри на реализацию — тестируй только спецификацию.
Продвинутый приём — попросить AI сгенерировать мутации (намеренные баги) и проверить, что тесты их обнаруживают. Это даёт двойную проверку: тесты не просто «покрывают код», а действительно валидируют поведение.
Что AI генерирует плохо в тестах: интеграционные тесты со сложным окружением (моки баз данных, внешних API), тесты на concurrency, E2E со специфичными selectors — AI не видит вашу инфраструктуру и реальный DOM.
| Вид тестов | Надёжность генерации | Почему |
|---|---|---|
| Unit по спецификации | Высокая | Чёткий вход/выход, поведение описано |
| Edge cases | Высокая, если просить явно | Модель не перечисляет их сама |
| Интеграционные с окружением | Низкая | Моки инфраструктуры AI не знает |
| Concurrency | Низкая | Модель рассуждает о коде линейно |
| E2E со selectors | Низкая | AI не видит реальный DOM |
Документация и changelogs
AI эффективен для генерации документации по коду — JSDoc, README, migration guides — при условии, что указана целевая аудитория и уровень детализации. Но AI генерирует документацию, которая описывает код, а не объясняет решения: документация «почему» — почему этот API, почему этот подход — остаётся за разработчиком.
AGENTS.md: правила для агента
AGENTS.md (или CLAUDE.md) — файл с постоянными инструкциями проекта: стек, команды, соглашения, запреты, стандарты качества. Главный принцип — всё постоянное (то, что повторяется в каждой задаче) идёт в этот файл, всё одноразовое (конкретный модуль, критерии приёмки, доменные правила) — в текущую задачу.
Прежде чем наполнять файл, стоит знать: длинный AGENTS.md соблюдается хуже, обзор структуры репозитория бесполезен, а общий эффект контекстных файлов на результат не гарантирован. Устройство rules-файла, skills, hooks, subagents и управление контекстом — отдельная тема, см. Контекст-инжиниринг агентов.
Как формулировать задачу агенту
Паттерны промптинга из предыдущей статьи здесь работают напрямую. Основные правила для задач агенту:
Одна задача — одно сообщение
// Плохо: пять задач в одном запросе
Исправь баг с фильтрацией, добавь сортировку,
перепиши на TS, добавь тесты и обнови README
// Хорошо: фокус на одной задаче
Исправь баг: при фильтрации таблицы показываются удалённые записи.
Критерий: поле isDeleted === false должно отфильтровываться сервером.
Контекст, который агенту неоткуда узнать
Агент не видит ваш проект целиком и не знает внутренних решений. Всё неочевидное — в задачу:
// Плохо: скрытые требования
Сделай скидку в корзине
// Хорошо: явные правила домена
Сделай расчёт скидки в корзине:
- Промокоды НЕ суммируются с корпоративными скидками
- Для подписчиков — отдельный расчёт с округлением вниз
- Применяется только к товарам с ценой > 1000₽
- Максимум одна скидка на позицию
«Рассуждай, потом действуй» для сложных задач
Для анализа и отладки включайте chain-of-thought: «проанализируй, затем реши» даёт лучший результат, чем «реши сразу».
Таблица: элементы хорошей задачи
| Элемент | Вопрос к себе | Пример |
|---|---|---|
| Контекст | Откуда агент узнает о проекте? | «Компонент в src/components, клиент API — src/lib/api.ts» |
| Задача | Что конкретно сделать? | «Добавь сортировку по цене в таблицу» |
| Критерий | Как проверить, что готово? | «Клик по заголовку „Цена“ сортирует по убыванию, стрелка меняет направление» |
| Границы | Что НЕ делать? | «Не менять API, не добавлять библиотеки» |
| Контекст домена | Какие правила неочевидны? | «Промокоды не суммируются с корпоративными скидками» |
Управляемая генерация vs вайбкодинг
Вайбкодинг — стиль, при котором разработчик описывает задачу и принимает сгенерированный код без глубокого понимания и контроля. Он опасен в продакшне не из-за отдельных багов, а из-за архитектурных решений, которые AI принимает вместо вас.
Вайбкодинг:
Разработчик → "Сделай дашборд с графиками" → AI → [код] → Деплой
Управляемая генерация:
Разработчик → спецификация → AI → [код] → проверка → тесты → интеграция
// Что сгенерирует агент без спецификации:
const Dashboard = () => {
const [data, setData] = useState([]);
useEffect(() => {
fetch('/api/dashboard')
.then(r => r.json())
.then(setData);
}, []); // Нет обработки ошибок
// Нет loading-состояния
// Нет cleanup (отмена запроса при unmount)
// Нет обработки невалидного ответа
return <Charts data={data} />; // data может быть [] — Charts это учитывает?
};
Каждая из проблем — не «баг», а архитектурное решение. AI не знает, какие решения приняты в вашем проекте. Вы — знаете. Это и есть причина, по которой спецификация и проверка незаменимы.
Сравнение подходов
| Критерий | Вайбкодинг | Управляемая генерация |
|---|---|---|
| Спецификация | Отсутствует | Явная, с критериями приёмки |
| Контроль результата | Минимальный | Сверка против спецификации |
| Тесты | Опционально | Обязательны |
| Риск | Архитектурные решения принимает AI | Архитектурные решения принимает человек |
| Скорость | Максимальная | Ниже, но предсказуемая |
| Применимость | Прототипы, спики, обучение | Production |
Когда вайбкодинг работает
- Прототипы и спики — быстро проверить идею, которую, возможно, выбросите
- Личные проекты — вы единственный пользователь и готовы чинить баги сами
- Обучение — экспериментировать с новыми технологиями, смотреть, как AI реализует паттерны
- Одноразовые скрипты — парсинг, миграция данных, которые не пойдут в продакшн
Когда вайбкодинг опасен
В продакшн-коде вайбкодинг создаёт системные риски. Проблема не в том, что AI пишет баги — баги есть и в ручном коде. Проблема в том, что при вайбкодинге никто не отвечает за архитектуру: loading-состояние, обработку ошибок, cleanup, edge cases — каждое из этих решений AI принимает молча, и они «просачиваются» в продакшн незаметно.
Когда агент врёт и как это ловить
Агент не врёт намеренно — он генерирует правдоподобный текст. Опасность в том, что уверенность не коррелирует с точностью.
Типичные сценарии
| Сценарий | Как выглядит | Почему происходит | Как ловить |
|---|---|---|---|
| Галлюцинированный API | Метод библиотеки, которого нет в вашей версии | Модель «знает» много версий, но не вашу | Сверять с package.json и документацией версии |
| «Уверенно неверно» | Код выглядит корректно, но не компилируется | Агент не запускает код, пока не попросят | Требовать прогон lint/tests из AGENTS.md |
| Пропущенные edge cases | Happy path работает, границы — нет | Модель не знает ваш домен | Тесты по спецификации с явными границами |
| Повторение ошибки по инерции | В legacy есть баг, агент его копирует | Баг «выглядит» как паттерн | Характеризационные тесты, явное описание желаемого поведения |
Как ловить
- Запускайте тесты и линтер — требуйте от агента прогон проверок перед завершением (запишите это в AGENTS.md)
- Не доверяйте объяснениям агента — «я сделал всё по спецификации» не заменяет запуск кода
- Проверяйте против версий — если агент использует API библиотеки, сверяйте с версией в package.json
- Тесты по спецификации — они ловят регрессии, когда агент «закрепляет» баг
Паттерн «генерация + проверка»
Паттерн «генерация + проверка» — не принимайте результат агента на веру: попросите проверить собственную работу вторым вызовом с независимым фокусом. Агент, генерируя код, «влюблён» в свой результат; второй вызов смотрит критически.
Шаг 1: Реализуй компонент по спецификации: <спецификация>
Шаг 2: Проверь, соответствует ли этот код спецификации.
Спецификация: <спецификация>
Код: <код>
Укажи все несоответствия. Если соответствует — скажи "ok".
Это ловит то, что первый проход пропустил: при генерации модель стремится к правдоподобности результата, при проверке — к поиску несоответствий.
Как проверять результат агента
Проверка — не «пробежать глазами», а сверка против спецификации по четырём осям:
| Ось | Вопрос | Инструмент |
|---|---|---|
| Функциональность | Реализовано ли всё из спецификации? | Сверка «пункт спецификации → тест/код» |
| Крайние случаи | Что при пустых данных, ошибке, unmount? | Тесты на edge cases |
| Соглашения | Соответствует ли код стилю и паттернам проекта? | Ревью, линтер, сравнение с соседними файлами |
| Качество | Тесты? Линтер? Типы? | Команды из AGENTS.md |
Когда использовать AI, а когда нет
Обобщим критерии применимости AI-генерации для всей статьи:
| Задача | AI хорошо? | Условие | Альтернатива |
|---|---|---|---|
| Boilerplate, CRUD, утилиты | ✅ | Паттерн устоявшийся | Писать руками медленнее |
| Бизнес-логика | ⚠️ | Только с явной спецификацией домена | Ручная реализация + ревью |
| Архитектурные решения | ❌ | Трейдоффы требуют контекста проекта | Человек |
| Code review | ⚠️ | Как first-pass с фокусом | Человек как рецензент |
| Механический рефакторинг | ✅ | Поведение контролируется тестами | Вручную — дольше |
| Тесты по спецификации | ✅ | Спецификация есть | Ручные тесты |
| Интеграционные тесты | ❌ | Зависит от инфраструктуры | Человек |
| Документация «что» | ✅ | Аудитория и детализация заданы | — |
| Документация «почему» | ❌ | Решения знает только команда | Человек |
| Прототип | ✅ | Точность не критична | — |
Правило-резюме: AI берёт на себя то, что можно описать и проверить. Всё, что требует неявного контекста и решений — остаётся человеку.
Case study: от спецификации до продакшена
Соберём весь цикл на одном сквозном примере — фича «фильтр по дате в таблице заказов».
Шаг 1. Спецификация
## Фича: фильтр заказов по диапазону дат
### Поведение:
- Селектор «с даты» и «по дату» в шапке таблицы заказов
- Таблица фильтруется по полю created_at
- Даты — локаль пользователя, формат DD.MM.YYYY
### Правила домена:
- created_at в UTC, на клиенте переводить в локаль
- Диапазон не может быть больше 90 дней (бизнес-ограничение)
- Пустой диапазон = фильтр не применяется
### Edge cases:
- Начало > конец → показать ошибку под селектором
- Диапазон > 90 дней → блокировать выбор
- Пустые даты → таблица без фильтра
- Заказы на границе диапазона (00:00 начала, 23:59 конца) — включаются
### Критерии приёмки:
- Тест: выбор диапазона обновляет URL и запрос к API
- Тест: границы диапазона включаются
- Тест: ошибка при начале > конца
Шаг 2. Генерация
Задача агенту — по спецификации, в одну итерацию, с учётом AGENTS.md проекта:
Реализуй фильтр заказов по диапазону дат по спецификации:
<спецификация из шага 1>
Создай: компонент DateRangeFilter, хук useDateRange, тесты (Vitest).
Соблюдай: src/components, src/hooks, CSS Modules, клиент из src/lib/api.ts.
Перед завершением: pnpm lint && pnpm test.
Шаг 3. Проверка
Сверка против спецификации по четырём осям:
| Ось | Что проверяем | Типичная находка агента |
|---|---|---|
| Функциональность | Все пункты спецификации реализованы | Забыт «пустой диапазон = фильтр не применяется» |
| Крайние случаи | Edge cases из спецификации | Граница 23:59 конца дня отсекается из-за Date без времени |
| Соглашения | src/components, CSS Modules, клиент из src/lib | Компонент сам делает fetch вместо клиента |
| Качество | Тесты зелёные, lint, типы | — |
Каждая находка возвращается агенту с указанием пункта спецификации, а не с «что-то не то»:
Тест «граница диапазона» падает: заказ с created_at 31.05 23:59 не попадает в выбор по 31.05.
Спецификация: "Заказы на границе диапазона включаются".
Исправь сравнение, чтобы конец дня включался.
Шаг 4. Итерация и интеграция
Агент исправляет сравнение, тесты зелёные. Перед merge — человеческое ревью: соглашения соблюдены, тесты читаются как спецификация, архитектура адекватная (хук отделён от компонента). Только после этого фича в продакшене.
Что показывает кейс
- Качество результата заложено в спецификации — критерии приёмки дали агенту и человеку общий язык для проверки.
- Находки приходят с указанием пункта спецификации — итерация дешёвая, агент исправляет точечно.
- Человек отвечает за доменные решения — 90-дневное ограничение, UTC→локаль, включение границ — всё это не «дано модели», а записано разработчиком.
- Тесты — критерий готовности — без зелёных тестов по спецификации фича не существует.
Ключевые тезисы для интервью
- Работа с AI — цикл «спецификация → генерация → проверка»; спецификация — продукт разработчика, качество кода агента определяется её качеством, у каждого этапа — критерий выхода.
- SDD — методология, где спецификация — единственный источник истины: три столпа (спецификация, генерация, верификация тестами); спецификация описывает поведение, не реализацию, и включает примеры и edge cases.
- AI надёжен в задачах с чёткой спецификацией и устоявшимися паттернами (CRUD, утилиты, конвертация) и ненадёжен в бизнес-логике, архитектурных решениях и performance-критичных путях.
- AGENTS.md — постоянные инструкции для агента: стек, команды, соглашения, запреты, стандарты качества; одноразовое — в задачу, а не в файл.
- Вайбкодинг опасен в продакшне не из-за багов, а из-за архитектурных решений, которые AI принимает вместо вас; приемлем для прототипов и обучения.
- Тесты генерируются по спецификации, а не по коду — иначе агент закрепит баги реализации; мутации проверяют, что тесты действительно валидируют поведение.
- Агент может быть уверенно неверным: галлюцинированный API, нерабочий код, пропущенные edge cases; проверка — запуск тестов, сверка с версиями, недоверие объяснениям.
- Проверка результата — сверка против спецификации по четырём осям: функциональность, крайние случаи, соглашения, качество; находки возвращаются агенту с указанием пункта спецификации.
- Чем глубже вы знаете фронтенд, тем эффективнее работаете с агентами: вы знаете что спрашивать, видите проблемы в сгенерированном коде и принимаете архитектурные решения.
Заключение
AI-агент — усилитель компетенции, а не замена ей. Ваш вклад в цикл — спецификация (что и зачем делать), правила (AGENTS.md) и проверка (дисциплина сверки с критериями). Агент вносит скорость генерации; вы — точность направления и качество результата.
SDD — это не замена TDD, а его эволюция для эры LLM: спецификация — единственный источник истины, тесты — критерий готовности, разработчик — архитектор, а не кодер, LLM — исполнитель, а не соавтор. SDD подходит для production-разработки; для прототипов — vibe coding, для критичных систем — ручная разработка.
Главное правило, которое объединяет всё: AI берёт на себя то, что можно описать и проверить. Всё, что требует неявного контекста и архитектурных решений — остаётся человеку. Если компетенция высокая — агент усиливает продуктивность. Если низкая — усиливает количество багов.
Полезные ссылки
- Anthropic — How to work with Claude — рекомендации по формулированию задач
- The Cursor Rule — примеры системных инструкций для AI-ассистентов
- Vibe Coding (Andrej Karpathy) — оригинальный пост о термине и подходе
- LLM Coding Assistant Best Practices (Google) — стратегии промптинга для задач кодогенерации
- Vitest — тестовый фреймворк для примеров из статьи
- Behavior-Driven Development — методология, с которой сравнивается SDD
- Characterization testing — тесты для фиксации поведения legacy-кода