Маленький дисклеймер на входе

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

В этом году я решила, что хватит уже это терпеть. Тренд на «вайбкодинг» — когда ты разговариваешь с нейросетью, а она пишет код — звучал так, будто наконец-то можно без команды собрать проект самой. Пишешь: «хочу сервис, который собирает все семейные платежи в одном календаре» — и через день у тебя задеплоенный MVP с регистрацией, импортом PDF, авто-привязкой чеков к платежам и календарной подпиской.

Спойлер: да, это работает. Реально работает. У меня сейчас на проде живой сервис Бытовые счета, он умеет всё перечисленное выше плюс ещё много чего, и я там написала ровно ноль строк кода руками. Всё — через Claude Code, IDE-расширение от Anthropic.

Спойлер номер два: там, где всё идёт по плану, вайбкодинг — магия. Там, где ломается — оно превращается в очень специфический жанр квеста, в котором тебе сильно помогает базовое аналитическое мышление и мешают розовые очки.

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

Расскажу пять конкретных косяков из личного опыта.


Что такое «Бытовые счета»

Чтобы дальнейшие истории были понятны, два слова о самом продукте — он же подопытный кролик моих экспериментов с Claude.

«Бытовые счета» — это диспетчерская для семейных платежей. Идея выросла из собственной боли. У любой семьи есть десяток регулярных трат, и живут они в разных местах: ЖКХ приходит на почту PDF-квитанцией, няне переводишь по номеру телефона, кружки ребёнка оплачиваются через приложение школы, подписки списываются сами, страховку надо продлевать раз в год. Всё разрознено, ничто не связано между собой, и раз в пару месяцев кто-то обязательно забывает заплатить — а дальше пени и нервы.

Сервис собирает это в одно место. Логика такая:

  • Загружаешь PDF-квитанцию или чек — система сама вытаскивает из него получателя, сумму и дату, без ручного ввода.

  • Платёж попадает в общую картину: видно, что предстоит оплатить, что уже оплачено, что просрочено.

  • Платежи можно подписать в свой календарь (Apple, Google и подобные).

  • Можно пригласить супруга в общий семейный аккаунт и вести всё вдвоём.

Технически это веб-приложение на Next.js с мобильной PWA-версией (ставится иконкой на телефон и ведёт себя как нативное приложение). Весь код — через Claude Code, и, повторюсь, мной, аналитиком без инженерного бэкграунда. А теперь — про то, как это создавалось.


История 1: «Это не код, это хостер»

В какой-то момент у меня одновременно жило два проекта: основной — образовательный сайт на Next.js (datadriven-course.ru), и второй (bytovye-scheta.app). Чтобы не платить за два VPS на свои, я попросила Claude разместить оба на одном сервере.

— Это возможно? — спросила я. — У меня нет инженерных знаний, чтобы оценить риски.

— Да, абсолютно, — сказал Claude. — Стандартная конфигурация NGINX, два server-блока, каждый сайт на своём домене. Никаких конфликтов.

Я кивнула. Перенесли. И в этот же день начались странности: оба сайта стали периодически зависать на iPhone. То откроется, то нет. То Safari белеет на полчаса, то всё нормально. С компьютера — первая загрузка ок.

Я говорю Claude: проверь.

Claude проверяет. Сертификат — валидный. DNS — корректный. nginx — без ошибок в логе. И тут начинается:

— Знаешь, проблема, скорее всего, в хостере. Aeza недавно попала под пристальное внимание Роскомнадзора, потому что её IP-блоки использовались как VPN. У меня есть статья на Хабре от прошлого года, где люди жалуются на блокировки.

И прикладывает ссылку на статью. Реальную. Годовалой давности. Где люди жаловались на Aeza.

Я говорю:

— Окей, давай проверим, желательно бесплатно.

Claude предлагает Claudflare, только dns . Регаюсь там, что-то колдую, получилось. Проверяем. Мимо. Прошу искать дальше:

— Конечно, вот настоящая причина! Шрифты Google… и дальше что-то на умном.

Меняем и это. Безрезультатно.

Я возвращаюсь к Claude и говорю буквально:

— Слушай, ты меня неправильно ведёшь. Симптом — зависает. Зависать начало только последние сутки. До этого первый проект грузился без сбоев. Что мы изменили сегодня? Иди ищи в коде.

Claude думает. Идёт в логи. Находит:

— О! В новом конфиге bytovye-scheta я указал listen 443 ssl http2;. Это конфликтует с соседним server-блоком datadriven-course.ru, который тоже на 443 порту, но без http2. NGINX даёт предупреждение protocol options redefined, и часть SSL-сессий рандомно ломается. Особенно на iPhone, потому что Safari агрессивно переиспользует соединения.

Решение — убрать http2 из listen-директивы нового сайта. Одна строка.

Разрабы наверняка скажут, что это было очевидно. Но я не разраб. А вайбкодинг, типа, для каждого. Ага.

Как это выглядит в чате

За часы дебаггинга Claude несколько раз торжественно объявлял, что причина наконец-то найдена:

Claude объявляет «Очень важная находка»
Claude объявляет «Очень важная находка»
Claude: «Окончательная правда»
Claude: «Окончательная правда»

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

Но вот за что я Claude зауважала: в какой-то момент он тебе признается.

Claude: «Стоп. Я должна признать, что не справляюсь»
Claude: «Стоп. Я должна признать, что не справляюсь»
Claude признаёт, что ходит по циклу
Claude признаёт, что ходит по циклу
Извинение Claude за правки вслепую
Извинение Claude за правки вслепую

Он буквально пишет: «4+ часа делаю правки, и каждый раз приписываю это новой найденной причине», «возможно, я только усугубила», и извиняется. Честно говоря, такую саморефлексию я не у каждого живого подрядчика видела — обычно человек до последнего держится за свою версию. Мимимишечка.

Чему меня это научило:

Claude отлично умеет генерировать правдоподобные гипотезы. У него есть статистика того, что обычно ломается. И он выдаёт самую вероятную причину. Если симптом — «сайт периодически зависает на iPhone» — статистически чаще всего виноват CDN, провайдер, сертификат или хостер. И Claude идёт туда. С источниками. С обоснованием. И очень-очень убедительно.

Без аналитического мышления — без вопроса «а что мы поменяли прямо перед тем, как сломалось?» — вы идете за ним.

Опытный разработчик в этой ситуации первым делом смотрит git log за последние сутки. Это рефлекс. У Claude такого рефлекса нет — он смотрит туда, куда ты его направишь.


История 2: «Сервер action “x” не найден»

Мобильная веб-версия проекта установилась у меня на iPhone как PWA (Progressive Web App — это когда сайт добавляется иконкой на главный экран и ведёт себя как нативное приложение). И после очередного деплоя я обнаружила: на телефоне кнопки не реагируют. Тапаешь «Попробовать бесплатно» — ничего. Тапаешь «Войти» — ничего. Форма приглашения супруга — отправляется в никуда.

Описываю симптом. Claude говорит:

— Скорее всего проблема в hydration React. Кнопка <Link> от Next.js работает через JavaScript, а на медленной мобильной сети JS догружается долго. Замени <Link> на обычные <a> — они работают без JS.

Звучит разумно. Меняем. Деплоим. На обычном Safari в iPhone — работает. В установленной PWA — всё ещё нет.

— Хм, — говорит Claude. — Тогда, скорее всего, дело в Service Worker. PWA закэшировала старый код. Я могу обновить версионирование SW.

Делаем. Не помогает.

— Может быть это в самой Next.js версии. Давай посмотрим, какая у нас. Обновлю до latest.

Я уже хочу обновляться. И тут — внезапная мысль.

— Стоп. Покажи мне логи сервера прямо сейчас. Что туда прилетает, когда я нажимаю кнопку?

Claude смотрит. И там:

Error: Failed to find Server Action "x". This request might be from an older or newer deployment.

Эта ошибка повторяется сотни раз. Каждое нажатие любой кнопки — ошибка.

Объяснение тривиальное. Next.js 16 на каждой сборке генерирует уникальные ID для server actions (это специальные функции, которые умеют выполнять серверный код по нажатию кнопки в форме). Старая PWA в моём iPhone закэшировала старый клиентский код, который шлёт серверу старые ID. Сервер их не узнаёт и возвращает ошибку. У пользователя визуально — «ничего не происходит».

Решение — закрыть PWA, открыть, и она подхватит свежий JS. Если упрямится — удалить PWA с главного и поставить заново. Сделали. Заработало.

Без шагов «покажи логи сервера» — Claude бы туда сам не пошёл. Он опять шёл по самым популярным причинам подобного симптома (hydration, SW, версии библиотек). А реальная причина — это специфическая особенность именно той версии Next.js, которую он мне и подсунул, и Claude её не вспомнил.

Это вторая важная мысль про вайб-кодинг: Claude не смотрит туда, куда вы его не привели. Логи сервера, ошибки в браузерной консоли, состояние БД — для опытного разработчика это рефлекс «первым делом проверить». Для Claude — это нужно явно попросить.


История 3: Подключение почты, которая никому не дойдёт

У меня в продукте есть восстановление пароля. И приглашение супруга в семейный аккаунт. Оба сценария требуют отправки писем. Я попросила Claude подключить какой-нибудь транзакционный почтовый сервис.

Claude предложил Brevo (французский сервис, у них есть бесплатный план 300 писем в день). Хороший выбор: они официально поддерживают самозанятых из РФ.

— Какой адрес использовать как отправителя? — спрашиваю.

— Можешь использовать твой личный Outlook, — говорит Claude. — Это сработает для теста, потом перейдёшь на свой домен.

И мы идём по этому пути. Я регистрируюсь в Brevo. Подтверждаю отправителя (Brevo шлёт письмо с кодом). Создаю API-ключ. Прописываю его на сервере. Brevo требует whitelist IP-адресов сервера. Подтверждаю по почте «да, это мой сервер». Между делом получаю штук пять подтверждающих писем от самой Brevo.

Делаю первую тестовую отправку себе на Mail.ru. И — ничего не приходит.

Идём смотреть статус у Brevo. У них хороший API для статистики доставки.

event: softBounces
reason: 550 spam message rejected.

Mail.ru отказывается принимать письмо. Гуглим. Дело в том, что у outlook.com строгая DMARC-политика: любые письма «от Outlook-адреса», отправленные не через серверы Microsoft, по умолчанию помечаются как поддельные. Brevo шлёт через свои IP, не через Microsoft. Mail.ru видит «адрес outlook, но отправитель не microsoft» — и считает спамом.

Разобрались, но обидно вот что: эту проблему можно было предвидеть на самом старте. DMARC p=reject у Outlook известен с 2024 года, как мне потом уверенно рассказал Claude, как и конфликт с Mail.ru. Если бы Claude проверил эти два факта — он бы сразу сказал: «У тебя ничего не уйдёт на Mail.ru. Используй Gmail или сразу подключай свой домен».

Вместо этого — я прошла весь путь: регистрация, верификация, IP whitelist, ключ, тест.

Это третья закономерность: Claude охотно ведёт по пути, который статистически часто работает в среднем по миру. Но «в среднем» — это про Запад, где Gmail/Outlook составляют 90% получателей. У меня в РФ — 90% получателей это Mail.ru и Yandex, и там правила игры другие. Локальную специфику Claude часто не учитывает, пока вы её сами не подсунете.


История 4: «Запиши секрет ты сам». «Не могу». «Запиши». «Не могу»

Чтобы Brevo заработал на сервере, API-ключ нужно прописать в файл .env.local на VPS. Я была в отчаянии после всех квестов с DMARC и спросила Claude:

— Просто пропиши ты этот ключ. У тебя есть SSH-доступ.

— Не могу, — сказал Claude. — Это блокируется sandbox-правилами. Запись секретов на production-сервер требует твоей явной авторизации.

Я попыталась несколько раз. Каждый раз — отказ.Но ведь мы уже так делали ранее.

— Окей, — говорю, — пропиши тогда сам через одну SSH-команду, а я подтвержу.

— Не могу через подтверждение, эта блокировка hard-deny. Тебе нужно сделать это руками. Вот команда, копируй в PowerShell.

Оказалось, то ли я ткнула, то ли в новой сессии выбрался другой режим по умолчанию. Сменила режим Claude Code на «bypass permissions» (это особый режим без sandbox-блокировок). Сказала: пиши. И Claude за десять секунд через одну SSH-команду всё прописал нормально, перезапустил сервис, протестировал отправку, увидел 201 Created от Brevo.

Claude отказывается записать секрет на прод и объясняет, почему это правильно
Claude отказывается записать секрет на прод и объясняет, почему это правильно

Это четвёртый урок. Claude — это не только модель, это ещё и среда, в которой она работает. Среда имеет жёсткие ограничения по умолчанию: не писать секреты на прод, не делать необратимых операций, не запускать опасные команды. Это правильная защита: я не уверена, что среднестатистический пользователь способен оценить, что произойдёт, когда нейросеть прямо сейчас в production пропишет какой-то API-ключ.

Но если вы — менеджер без аналитического мышления, для которого «production», «sandbox», «bypass» — это всё одинаково страшные слова — вы будете эти ограничения трактовать как «нейросеть отказывается работать, вайб-кодинг не работает, надо нанимать настоящего разработчика».

На самом деле — нет, надо просто разобраться, в каком режиме вы запускаете инструмент.


История 5: Маленькая ложь в FAQ

На лендинге у меня есть FAQ-секция. Один из вопросов — «Что с моими данными? Где вы их храните, кому передаёте?».

Я попросила Claude написать успокаивающий, но точный ответ. Claude написал:

«Мы не храним чеки — они удаляются сразу после извлечения полей. В базе остаются только структурированные данные…»

Звучало хорошо. Я даже почти выкатила. И вдруг что-то царапнуло — а на самом деле мы их удаляем?

Я попросила Claude показать в коде, где удаление чеков. Claude посмотрел. И сообщил:

— Эээ, на самом деле в текущей реализации после импорта чек остаётся в таблице receipts_inbox со статусом assigned. Я бы рекомендовал поправить текст FAQ.

То есть он сам же только что написал маркетинговое утверждение, которое не соответствует коду, который сам же и писал. Не из злого умысла. Просто потому что в FAQ он мыслил «как должно быть для пользователя», а в коде — «как удобнее реализовать».

Мы переписали код. Но что, если бы я не задала контрольный вопрос?

Это пятый и, возможно, самый коварный сценарий. Claude может галлюцинировать факты о вашем собственном коде. Особенно когда вы просите его описать что-то, что он кодил много сообщений назад — он начинает описывать как должно быть в идеальном продукте, а не как есть в вашем.


А теперь — за что Claude всё-таки молодец

Может сложиться впечатление, что вайбкодинг — пустая трата времени. Это не так.

Когда проект наконец был выполнен и я готовилась к pre-prod-релизу, я попросила Claude провести полный аудит безопасности и продуктовой логики. Запустила специальную фичу — workflow, которая позволяет одной команде запустить несколько параллельных подагентов с разными ролями. Один смотрит безопасность, другой — race conditions, третий — edge cases, четвёртый — продуктовую воронку, пятый — согласованность маркетинговых текстов с кодом, шестой — производительность.

План аудита: шесть субагентов с разными ролями
План аудита: шесть субагентов с разными ролями

За 15 минут в фоне это выкатило 62 подтверждённые находки: 3 критических, 14 высокого приоритета, 33 средних, 11 низких. Среди критических — настоящая уязвимость Host Header Injection в форме сброса пароля (атакующий мог через подмену заголовка получить ссылку для сброса пароля на свой домен). Это серьёзный баг, который я бы не нашла ни сама, ни через ручное код-ревью.

После аудита я запустила второй workflow на исправление: четыре параллельных стрима, каждый чинит свою категорию. Результат: 33 фикса задеплоено за минуты, plus автоматический smoke-тест на проде — 12 из 12 сценариев прошли.

Итог исправлений: 33 фикса задеплоено, 12 из 12 smoke-тестов прошли
Итог исправлений: 33 фикса задеплоено, 12 из 12 smoke-тестов прошли

В этих сценариях — где задача чётко поставлена, контекст ограничен, и есть способ проверить результат — Claude работает как небольшая команда младших инженеров под управлением сеньора. Очень быстрая, очень дешёвая, очень дисциплинированная команда. И это великолепно.

Также Claude отлично справляется с:

  • Рефакторингом по чёткому ТЗ. «Перепиши вот эту функцию так, чтобы она была атомарной» — работает с первого раза.

  • Генерацией шаблонного кода. Создать новую страницу с формой, обработчиком, валидацией, тестами — за пять минут.

  • Объяснением чужого кода. «Что делает вот этот файл?» — получаешь чёткий разбор.

  • Документацией. Что у нас в HANDOFF.md проекта — на 99% написано Claude по моим репликам.

  • Маркетинговыми текстами, где не критично совпадение с кодом (заголовки лендинга, тексты email, FAQ — но с обязательной проверкой фактов, как я писала выше).


Что я думаю про вайб-кодинг как метод

Вайбкодинг — это не «теперь каждый может программировать». Вайбкодинг — это мощный мультипликатор существующих когнитивных способностей в области разработки.

Если у вас уже есть аналитическое мышление, базовое понимание архитектуры приложений (хотя бы на уровне «клиент-сервер-БД»), и вы умеете задавать конкретные вопросы — Claude превращает вас в одного человека, который делает работу за небольшую команду. С ним делается реально много и быстро.

Если у вас этого нет — Claude не даст вам ничего, потому что вы не сможете:

  • Поймать, когда он галлюцинирует.

  • Сказать «иди в логи», когда он копает не туда.

  • Заподозрить, что причина проблемы — в коде, который вы деплоили вчера, а не в внешнем хостере.

  • Спросить «покажи мне реальный код», когда он рассказывает теорию.

  • Понять, в каком режиме Claude Code сейчас работает и почему он не может что-то сделать.

Можно ли это компенсировать через готовые промпты с курсов? Частично. Все эти курсы «как пользоваться Claude Code» сейчас дают вам шаблонные обороты речи, которые повышают вероятность того, что Claude вас правильно поймёт. Это полезно. Но это не заменяет умение думать о проблеме.

У меня нет компетенций разраба, но у меня есть нечто соседнее: я умею анализировать продукт, замечать несоответствия в логике, ловить ложь в маркетинговых утверждениях. Этого хватило, чтобы остановить Claude, когда он шёл не туда, и развернуть его на правильный путь.

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


Мой проект “диспетчерская семейных платежей” bytovye-scheta.app сейчас на проде, пока бесплатно, я тестирую его на первых пользователях. Но вайбкодинг — такая заразная штука, что у меня уже готова следующая идея))

Если у вас есть свой опыт вайбкодинга — расскажите в комментариях, где у вас Claude (или другая модель) накосячил. Или похвастайтесь, что ли. Вдруг это я туповата, а не помощник.