- BrainTools - https://www.braintools.ru -

Вайб-кодинг без розовых очков: как я писала свой продукт с Claude

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

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

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

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

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

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

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


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

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

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

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

  • Загружаешь 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 недавно попала под пристальное внимание [7] Роскомнадзора, потому что её 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 за последние сутки. Это рефлекс [8]. У Claude такого рефлекса [9] нет — он смотрит туда, куда ты его направишь.


История 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.

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

Объяснение тривиальное. 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, как и конфликт [11] с 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 всё-таки молодец

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

Когда проект наконец был выполнен и я готовилась к 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 [13] сейчас на проде, пока бесплатно, я тестирую его на первых пользователях. Но вайбкодинг — такая заразная штука, что у меня уже готова следующая идея))

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

Автор: Mamalytic

Источник [14]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/32839

URLs in this post:

[1] мышление: http://www.braintools.ru/thinking

[2] интуиции: http://www.braintools.ru/article/6929

[3] опыта: http://www.braintools.ru/article/6952

[4] боли: http://www.braintools.ru/article/9901

[5] забывает: http://www.braintools.ru/article/333

[6] Логика: http://www.braintools.ru/article/7640

[7] внимание: http://www.braintools.ru/article/7595

[8] рефлекс: http://www.braintools.ru/article/9352

[9] рефлекса: http://www.braintools.ru/article/8998

[10] ошибка: http://www.braintools.ru/article/4192

[11] конфликт: http://www.braintools.ru/article/7708

[12] впечатление: http://www.braintools.ru/article/2012

[13] bytovye-scheta.app: https://bytovye-scheta.app

[14] Источник: https://habr.com/ru/articles/1057200/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1057200

www.BrainTools.ru

Rambler's Top100