Мой путь в вайб-кодинг: архитектура, MVP и выжить несмотря на биллинг
Итак, обо мне
Я в теме вайб-кодинга уже как 10 месяцев. Если бы речь шла не об AI, а именно о вайб-кодинге, такой срок было бы смешно даже упоминать. Система, с которой я работаю, — Replit, поэтому некоторые вещи, о которых пойдет речь ниже, могут быть вообще неприменимы к вашим системам.
За это время я накодил веб-игру (просто, чтобы попробовать), приложение для самостоятельной подготовки к экзамену с испанского DELE (сейчас неактивный), приложение для анализа документов на недвижимость в Испании (в процессе), и приложение для анализа снов https://dreampower.app/. Последний можно реально попробовать: у него уже есть пользователи, есть органический трафик и даже первый доход. Собственно, дальше я буду говорить именно о нем.
Я хочу поделиться челенджами, с которыми я столкнулся, когда создавал это приложение. Сейчас в нем более 50k строк кода на Python (окей, понимаем, что качество кода не на высоте, поэтому можно смело сбрасывать до 40k, учитывая огромное количество комментариев, которые оставляет AI-агент). При этом система биллинга занимает около 20k строк кода — фактически половину приложения.
Помимо просто объема кода, в приложении есть несколько непростых для меня моментов. Это система авторизации (разрабатывалась с нуля), интеграции с e-mail-системами, Sentry, работа с сохранением данных в сессии, телеграмм-бот, кроны, управление доступами и квотами.
Мои знания в программировании ненулевые: я знаю SQL, умею читать Python так, чтобы в целом составить представление, что делает код. И это все. Я разрабатывал проекты, и достаточно большие, но всегда был со стороны продакта. Как оказалось, этого более чем достаточно для вайб-кодинга сложных проектов, что бы не говорили противники этого подхода.
В процессе создания анализатора снов я столкнулся з несколькими “процессными вызовами” — трудностями, которые не имели отношения к самой природе приложения, а касались подхода и процесса построения. В итоге я наработал для себя несколько решений, которыми я и хочу поделиться.
Дисклеймер: это могут быть или не очень релевантные для вас вызовы, или не самые эффективные решения для этих задач. Воспринимайте это как основу для брейншторма.
Мне кажется, этот разговор нужно начать с базовых принципов, которые я для себя сформулировал во время создания приложения. Их было два:
- Приложение должно быть достаточно хорошим, чтобы выполнять основной процесс. К нему больше подходит слово “прототип”, чем «production-ready» (как любит говорить агент в Replit).
- Приложение должно иметь достаточно хорошую архитектуру, чтобы его можно было постоянно достраивать.
Принцип №1 снимает напряжение и угрызения совести за то, что постоянно что-то отваливается (а чем больше приложение, тем чаще что-то отваливается). А вот принцип №2 подводит нас к первому большому вызову.
Как построить архитектуру приложения так, чтобы не пришлось все перестраивать с нуля
Вопрос на миллион и десять статей. Повторюсь: ниже — мои решения, которые точно далеки от идеала.
Берем на роботу архитектора
Ну, возможно, не буквально “берем” и не совсем “на роботу”. Я сразу понимал, что подход, который рекламирует Replit — “закинь свой промпт в агент, и он все сделает” — приведет к беде. Выяснилось, что:
- Агент может вообще не оценить критически промпт и сделать его условно «дословно».
- Агент не всегда держит в голове контекст всего приложения, поэтому он или:
- может сделать вещи, которые просто не будут стыковаться с другими большими частями (ему ж об этом в промпте никто прямо не сказал, правда?), или
- будет дублировать код, не осознавая, что уже есть похожая функция, которую можно переделать так, чтобы она учитывала потребности новой фичи.
В результате моим архитектором стал ChatGPT в режиме «мышления». Чтобы резко повысить его полезность, я сразу задумался над тем, как передавать ему весь контекст приложения (я знаю о возможности конектить ChatGPT к Git, но не уверен, что это полностью решает вопрос контекста).
Как я передаю контекст? Очень просто. Я начал заставлять Replit-ассистента писать документацию и поддерживать ее. Главный челлендж был в выборе формата этой документации. Стандартная tech-spec была слишком громоздкой и раздувала документы. В итоге я пришёл к такому формату:
- ассистент пишет специальные “сжатые” tech-spec-документы по отдельных блоках функционала;
- ассистент пишет документы user flow.
По-простому: ключевое описание функционала (сразу делаем для AI, а не для людей, поэтому можно сильно сжимать) плюс описание флоу пользователя в формате mermaid, чтобы ChatGPT вообще понял, как работает само приложение.
В результате вышло 11 документов, которые я постоянно поддерживаю в актуальном состоянии, скачиваю с Replit и закидаю в проект ChatGPT.
Теперь стандартный флоу разработки выглядит так:
- Появляется идея фичи. Идем обсуждать ее в ChatGPT.
- Как только достигаем нужного уровня понимания, ChatGPT генерирует “проект” для Replit-агента. Обычно этот проект не включает конкретные сниппеты кода (конкретно для Replit это оказалось не очень полезным и лишним).
- Дальше агенту, в режиме планирования, закидывается этот проект с такими инструкциями: “Проверь его относительно нашей кодовой базы, названий модулей / сменных / импортов. Определи возможности рефакторинга. Задай вопросы и дай свои комментарии.”
- Агент приносит и вопрос, и замечания, и параллельно фокусируется на рефакторинге старого кода в контексте этого проекта.
- Ответ агента закидывается в ChatGPT, тот дает свои комментарии и т.д., пока агенту не станет более-менее все понятно. Обычно это занимает 1-2 итерации. После этого проект можно кодить.
Нужно обязательно понимать структуру и флоу проекта, который вы пытаетесь реализовать.
Может показаться, что мы просто берем результат из одной системы, копипастим его в другую — и все. Но нет. Когда я делаю проект (план какой-то разработки), я всегда хотя бы на каком-то уровне должен понимать все, о чем идет речь.
Например, если мы делаем биллинг и обрабатываем веб хуки, которые могут приходить в разное время или не приходить вообще, то со всем этим надо разобраться.
Иначе у меня для вас плохие новости. И архитектор, и Replit-агент десятки раз заводили меня в тупики, и слепой веры к ним нет.
Поэтому частый компонент моего промпта в ChatGPT — «explain high-level and be concise», «explain in plain language» и т.д. И тут мы плавно подходим к следующему важному моменту.
Определяем для себя, что такое «good enough»
Пример. Я начал строить биллинг, имея слабое представление, как должна выглядеть вся система. Ну окей, есть веб хуки, заказы и остальное. Но на вопросы, какие именно юзкейсы мне нужно обработать в своем приложении, чтобы все работало более-менее ок — ответа у меня не было.
Скажем, если платеж зависает на ревью, нужно ли мне это у себя реализовывать? Частично или полностью? И таких решений нужно было принять десятки. А потом нужно, чтобы все эти частичные решения еще и как-то заработали между собой вместе.
Когда просишь ChatGPT подумать над проектом и включаешь ему web-search, он, конечно, пойдет почитает того же Stripe и вернется с идеей звездолета, который нам, скорее всего, вообще не нужен.
Что я сделал. Во-первых, я для себя понял, на что я сейчас готов и на что не готов в принципе. Окей, мы делаем MVP.
Дальше я написал системный промпт в проект приложения в ChatGPT, где он должен фокусироваться на MVP-фичах и отдельно, с аргументацией, предлагать мне фичи “на вырост”, nice to have и т.д. — так, чтобы я видел их четко выделенными из общего потока и смог принять решение. Стало значительно проще.
По структуре данных все решения принимаются отдельно
Агент и архитектор с большим удовольствием примут решения относительно структуры данных самостоятельно. Это касается структуры таблиц, структуры полей таблиц и т. д. Но нам не нужно, чтобы они делали это без нас. И вот почему.
Во-первых, мне как продукт-разработчику необходима определенная прозрачность. Например, я хочу сохранить дополнительную информацию и не хочу упаковывать ее в JSON потому, что потом мне будет неудобно это читать. Неважно, что это не соответствует какой-то суперправильной структуре, которой где-то учили AI.
Я, безусловно, послушаю его аргументы, но ключевые решения оставлю за собой. И такой подход окупается.
То же самое касается всех важных данных в приложении. Например, в моем случае — это то, как мы отслеживаем этапы анализа, на которых находится пользователь, как храним данные от пользователя, где и когда их храним и т. д.
Что касается технического стека, все решения также желательно принимать вам
Мои приложения пишутся на Python / PostgreSQL / HTML / JS (по-минимуму). Почему так? Потому что я могу читать и понимать эти языки.
Будет ли это “наиболее эффективным решением” во всех случаях? Нет, конечно. Но у нас и нет цели сделать “наиболее эффективное решение”. У нас цель, смотреть выше, собрать приложение, которое не разваливается и его можно достраивать.
Чтобы в результате он начал приносить много денег, и тогда уже можно будет все эффективно переписать, нанять профессионалов и сделать конфетку. Но это уже потом.
А пока желаю вам удачного вайб-кодинга! И не падать духом (да-да, “вайб-кодинг мертв”, “он не подходит для сложных проектов” и все в таком стиле). Надеюсь, какая-то часть этих наблюдений и «костылей» окажется полезной для вас и убережет несколько вечеров, которые можно будет провести не за дебагом, а за чем-то гораздо более приятным.
Возможно, вас заинтересует
Вопросы вроде «можно ли усилить присутствие бренда в ответах Chat GPT или Gemini?» сегодня...
Рынок цифровых продуктов стабильно растет. По данным аналитических агентств, сегменты онлайн-образования, электронных книг и...
Кажется, еще вчера мы привыкали к сенсорным экранам, а сегодня все чаще слышим: «Окей,...
Наш телеграм
с важными анонсами, розыгрышами и мемами
Присоединиться