Vibe Coding vs Spec Coding: одна функция возврата — два подхода

· 1 мин чтения
vibe-coding spec-coding ai-development engineering-practice specifications
Vibe Coding vs Spec Coding: одна функция возврата — два подхода

Vibe coding затягивает: описываешь желание обычным языком, AI пишет код, через десять минут endpoint работает. Автор статьи Дэниел Марш рассказал, как shipped функцию возврата средств через vibe coding — и следующие две недели латал баги, которые 90-минутная спецификация предотвратила бы полностью.

Требование

Платформе e-commerce нужна функция возврата средств по заказам: полные и частичные возвраты, вызов платёжного шлюза (Stripe-style), отслеживание статуса (pending, processing, succeeded, failed), инициирование через внутренний инструмент поддержки.

Путь A: Vibe Coding

Промпт: «Build me an order refund API in Node.js. Support full and partial refunds. Call a payment gateway. Track refund status. Use Express and Postgres.»

Через 60 секунд — готовый RefundController с createRefund и getRefundStatus. Код выглядит профессионально, happy path работает. Ship it.

Баг #1: Двойной возврат

Агент поддержки нажимает кнопку, страница зависает, нажимает снова — два возврата проходят по одному заказу. Идемпотентности нет. AI добавляет проверку: если возврат для заказа существует — отклонить. Работает, но не отлавливает накопительную сумму.

Баг #2: Переплата по частичным возвратам

Заказ $200. Возвраты: $50, $80, $100. Итого $230 — больше заказа. Проверка искала точные дубли, а не сумму. AI добавляет SUM(amount), но без транзакции вокруг insert — два параллельных возврата проходят проверку одновременно.

Баг #3: Таймаут шлюза

Шлюз не отвечает. Запись возврата в БД со статусом «processing», ответ шлюза не пришёл. Возврат завис. Повторная попытка заблокирована проверкой дубликатов. AI добавляет retry-логику, но без exponential backoff, без idempotency key, без лимита — retry может создать повторный charge на стороне шлюза.

Баг #4: Состояние гонки

Два агента одновременно обрабатывают возвраты по одному заказу. Оба проходят проверку суммы (первый возврат ещё не закоммичен), оба вызывают шлюз, оба успешны. Клиент получает двойной возврат.

Четыре патча. Каждая заплатка разумна изолированно, но архитектура превратилась в лоскутное одеяло: нет конечного автомата, нет документированных инвариантов, нет тестов на взаимодействие заплаток.

Реальная стоимость: первая версия — 10 минут. Четыре патча — две недели (расследование, тестирование, эскалации поддержки, ручная сверка записей шлюза).

Путь B: Spec Coding

То же требование, тот же AI. Другая стартовая точка — сначала спецификация.

Спецификация (90 минут)

Спек определяет: цель (безопасная обработка возвратов без переплат и дублей), неголы (пользовательский портал, аналитика причин), конечный автомат (pending → processing → succeeded/failed → pending при retry), критерии приёмки в формате Given/When/Then для каждого сценария, граничные случаи (concurrent requests через SELECT FOR UPDATE, idempotency через UUID, суммы в центах, ночная сверка со шлюзом), и план отката через feature flag.

Реализация

Промпт с прицепленной спецификацией: «Implement the refund feature described in this spec. Follow the state machine exactly. Use SELECT FOR UPDATE. Include idempotency key. All amounts in cents.»

AI генерирует: processRefund в транзакции с SELECT FOR UPDATE, проверку баланса внутри транзакции, idempotency key (UUID) при каждом вызове шлюза, background retry с exponential backoff и лимитом в 3 попытки, корректные переходы состояний по конечному автомату.

Те же сценарии — решены заранее

  • Двойной возвратSELECT FOR UPDATE + idempotency key в первой версии
  • Переплата — баланс проверяется внутри той же транзакции, что и insert
  • Таймаут шлюза — retry с тем же idempotency key, шлюз обрабатывает как безопасный повтор
  • ГонкаSELECT FOR UPDATE сериализует операции, второй запрос ждёт первого

Сравнение

Параметр Vibe Coding Spec Coding
Время до рабочего endpoint 10 минут 3 часа (со спеком)
Время до production-ready 2+ недели 4 часа
Баги в продакшене 4 критических 0
Инциденты, затронувшие клиентов 2 0
Архитектура кода Заплатки поверх заплаток Когерентная, соответствует спеку
Качество AI-вывода Только happy path Все граничные случаи
Онбординг нового разработчика Код + Slack + инциденты Прочитать спек
Уверенность при релизе Низкая Высокая

Вывод

Оба пути использовали один и тот же AI. Разница — во входных данных, а не в инструменте. Vibe coding даёт AI свободу принимать решения, которые вы сами ещё не приняли. Spec coding фиксирует решения заранее и передаёт AI ограниченную задачу с чётким определением корректности.

AI-инструменты — усилители. Усилитель, направленный в размытую сторону, усиливает путаницу. Направленный на чёткую спецификацию — усиливает точность.

Vibe coding уместен для прототипов, исследований, одноразовых скриптов, хакатонов — там, где граничные случаи не важны. Как только вы строите систему, обрабатывающую реальные деньги, пользователей или данные — нужна спецификация.

90 минут на написание спека сэкономили две недели инцидент-менеджмента. Это не трюк продуктивности, а принципиально другой способ работы.

Источник: https://spec-coding.dev/blog/same-refund-feature-vibe-coding-vs-spec-coding