Вайбкодінг: як не стати пасажиром у власному проєкті

💡 Усі статті, обговорення, новини про AI — в одному місці. Приєднуйтесь до AI спільноти!

Зараз вайб кодинг на вайбі, і це круто, тому що AI може знайти і показати ті помилки, яких ми як розробники можемо не побачити. Але якщо не слідкувати за чистотою коду в твоєму репозиторії — це може перетворитись на купу працюючого коду, який ти не зможеш підтримувати в подальшому. Я пропоную обговорити підходи і методи в стриманні вайб кодінгу, щоб твій проект не перетворився в хаос. Що робити, щоб робота з AI стала більш зручною і якіснішою?

Я помітив одну закономірність: всі, хто починає вайбкодити, проходять однакові стадії. Спочатку ейфорія — AI генерує код, все компілюється, фічі створюються миттево і все працює. Потім помірний хаос — код є, але ти вже не зовсім розумієш, як і навіщо половина з нього взагалі існує. І нарешті, якщо вчасно не зупинитись, — класичне болото, з якого важко вибратись.

Я сам через це пройшов. І от що мені допомогло залишитись на поверхні.

Вайбкодінг — це не проблема і не небезпека сама по собі. Це інструмент з дуже гострими краями. З одного боку він дає неймовірну швидкість, з іншого — ти можеш пропустити момент, коли твій проєкт перетворився на чорну скриньку, яку тільки AI і розуміє. Може в майбутньому так і буде, але в сьогоднішніх реаліях програмісти ще мають слідкувати за чистотою в своєму репозиторії.

Почни з себе, а не з промпту

Перш ніж відкривати чат — спробуй пояснити архітектуру сервісу своїми словами. Якщо не виходить — AI тут не рятівник, він тільки швидше доведе до хаосу.

Programs must be written for people to read, and only incidentally for machines to execute.

— Harold Abelson, SICP

Це написано ще до епохи LLM, але зараз звучить навіть актуальніше. Якщо код зрозумілий людині — він зрозумілий і AI, і твоєму колезі, і тобі самому через три місяці.

Перш ніж давати AI вказівки писати код — попроси його спочатку скласти план. Просто скажи: «не пиши ніякого коду, спочатку створи план». Так ти покроково розберешся з архітектурою і патернами ще до того, як з’явиться перший рядок коду. Якщо задача складна — можна підключити кілька агентів, кожен дослідить проблему під своїм кутом. Коли план готовий і ти розумієш механіку — тоді вже код.

Мова програмування

Пиши на тій мові в якій ти справжній експерт. Не тому що нові мови це погано — а тому що, коли щось піде не так (а воно піде), тобі треба вміти дебажити це руками. Без AI, просто відкривши логи. Якщо ти цього зробити не можеш, проєкт фактично тебе не слухається.

Наприклад: у тебе нова задача, і твоя основна мова Go чи PHP, але хочеться зробити новий сервіс на Rust, тому що це зараз модно. Якщо ти ніколи не писав на Rust — врядчи знаєш підводні камені дебага і деплою. Напишеш крутий сервіс, але ніхто крім AI в ньому не розбереться. А на продакшені баг. І що тоді робити? Тому краще вибирати мову в якій ти експерт, чи хоча б знаєш синтаксис.

Контекст — твоя найцінніша валюта

LLM чудово працюють, коли мають хороший контекст. І погано — коли його немає або він застарів. Тому одне з моїх базових правил: `CLAUDE.md` або `AGENTS.md` не опціональний файл. Це перше що треба написати руками, чи за допомогою AI

Що туди варто покласти:

  • Архітектура і основні модулі
  • Які патерни використовуються (і чому)
  • Що заборонено (наприклад: не генерувати нові абстракції без узгодження)
  • Стек і версії залежностей
  • Де живуть тести і як вони запускаються

Якщо цього немає — AI буде здогадуватись. А здогадки в коді дорого коштують.

Лінтери і аналізатори — не рекомендація, а вимога

Тут я навіть не буду довго пояснювати. Налаштував — і забув. Головне правило — чим більше, тим краще. Нехай вони виловлюють те, що AI написав поспіхом. Головне — запускати їх у CI, а не тільки локально. Тому що локально можна забути, а в CI не вийде змерджити без green check.

Ще один важливий момент: коли AI виправляє помилку лінтера — перевір, чи він виправив саму помилку, або просто заглушив правило. Це різні речі.

Коментарі: менше — краще

LLM мають стійку звичку коментувати кожну функцію, кожен параметр, кожен return. У результаті на одну строку коду припадає три строки пояснень. Це не документація — це шум.

Про це ще Роберт Мартін писав у своїй Clean Code — і це досі актуально, а з AI стало ще актуальніше:

Every time you write a comment, you should grimace and feel the failure of your ability of expression.

— Robert C. Martin

Грубо, але точно. Коментар — це визнання, що код сам себе не пояснює. Іноді це виправдано, але в більшості випадків краще перейменувати функцію чи змінну ніж пояснювати що вона робить.

Хороший коментар пояснює ЧОМУ, а не ЩО. `// обходимо баг у Safari 16` — корисно. `// повертає суму чисел` — видали це негайно.

Скажи своїй LLM: коментарі тільки там, де логіка неочевидна або є важливий контекст. Все інше — зайве.

Тести: стеж за тим щоб AI не грав проти тебе

Це один з найпідступніших моментів. AI може написати тест, який проходить — але не тест, який перевіряє правильну поведінку. Він може:

  • Захардкодити очікуваний результат замість реального обрахунку
  • Замокати занадто багато, щоб тест взагалі нічого не тестував
  • Видалити assertion які заважали пройти

Майкл Фезерс у своїй книзі Working Effectively with Legacy Code сформулював це коротко:

Code without tests is legacy code.

— Michael Feathers

І з AI ця проблема стала ще гострішою — код з’являється швидко, а тести або не пишуться взагалі, або пишуться для галочки.

Тому моє правило: читай тести, які написав AI, так само уважно, як і бізнес-логіку. А ще краще — пиши тест-кейси сам (хоч би у вигляді коментаря), і хай AI тільки реалізує їх.

Ілюзія якості і довіра без перевірки

F81BD5E9-B21F-4AB1-945A-A33320B18DD9.jpg

Код виглядає чисто. PR виглядає добре. Але це не значить, що він правильний. AI впевнений у своїх відповідях навіть коли помиляється, і ця впевненість дуже заразна. Ти читаєш гарний код і думаєш — ну тут все ок.

Ок — до першого edge case на проді.

Брайан Керніган — один з авторів C і співавтор Unix — колись написав те, що я вважаю найчеснішим спостереженням про програмування:

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

— Brian Kernighan

А тепер уяви, що «cleverly as possible» робить не ти, а AI. Ось тобі і проблема.

Перевіряй логіку в граничних умовах. Що відбувається коли список пустий? Коли рядок містить emoji? Коли таймаут? AI рідко думає про крайні випадки, якщо ти прямо про них не питаєш.

Drift між кодом і документацією

Швидкий вайбкодінг породжує одну специфічну проблему — документація і код починають розходитись. Ти оновив логіку, але CLAUDE.md ще описує стару архітектуру. AI читає старий контекст і генерує рішення на основі неактуальних даних. Це невидимий технічний борг.

Заведи собі за правило: якщо змінив щось суттєве — одразу оновлюй контекстний файл. Це займає хвилину і заощаджує години.

Секрети і доступи — окрема розмова

Ніколи, жодного разу, ні за яких умов — не вставляй production ключі, токени чи паролі в промпт. Навіть «просто подивитись». Навіть в локальний чат. Навіть якщо ти впевнений.

Використовуй environment variables, .env.example без реальних значень, і якщо треба показати AI структуру — показуй з замасками: `sk-***...`. Це не параноя — це елементарна безпека.

І ще один момент, який люди недооцінюють: на твоїх даних модель може навчатись. Є реальний ризик, що твій ключ випадково з’явиться у відповіді на чиєсь зовсім стороннє питання. Малоймовірно — але можливо. Воно тобі треба?

Маленькі коміти і git як страховка

Ще одна звичка, яка рятує: роби маленькі, атомарні коміти з зрозумілими повідомленнями. Не `wip`, не `fix stuff`, а щось конкретне. Коли AI загне щось не туди — ти зможеш легко відкотитись до чистого стану. Великий коміт з 40 зміненими файлами — це вже проблема.

Чеклист перед тим як починати нову сесію з AI

Перед кожною серйозною сесією вайбкодінгу я задаю собі кілька питань:

  • Чи можу я пояснити архітектуру сервісу своїми словами — без AI?
  • Чи попросив я AI спочатку скласти план, а не одразу писати код?
  • Чи актуальний `CLAUDE.md` / `AGENTS.md`?
  • Чи налаштований CI з лінтерами і тестами?
  • Чи є конкретна задача — не «поліпшити код», а чітке що і навіщо?
  • Чи сказав я AI не писати зайвих коментарів?
  • Чи перевірю я тести після змін, і чи вони справді тестують поведінку, а не проходять для галочки?
  • Чи немає в буфері обміну жодних секретів або ключів?
  • Чи є git checkpoint перед стартом?

Висновок

69792AF8-1FC4-4C8B-93C2-BCB087A29EDF.jpg

Вайбкодінг нікуди не піде. Навпаки, він буде ставати ще швидшим і ще потужнішим. Але чим потужніший інструмент — тим важливіше розуміти, коли і як ним користуватись.

Головне, що я виніс зі свого досвіду: AI це не автопілот, це підсилювач. Він підсилює і твої рішення, і твої помилки. Якщо ти знаєш, що будуєш і тримаєш процеси в порядку — він дає суперсилу. Якщо ні — він просто швидше доведе тебе до хаосу.

Тримай архітектуру в голові і в документах, пиши на мові яку знаєш, не довіряй коду якого не розумієш, і пам’ятай: відповідальний за проєкт все одно ти, а не чат.

👍ПодобаєтьсяСподобалось15
До обраногоВ обраному9
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Читаючи статтю я бачу в ній велику частину генерації тексту мовною моделлю, це помітно. Відповідно, «стаття проходить повз» мене, я не хочу її читати, бо не знаю, хто автор і до чиєї думки чи тези буду апелювати у випадку коментування такої статті.

Ми дирижери. В чому відмінність написання коду через LLM і форматування статті за допомогою LLM? Я як автор, задаю свій хід думок і направлення. Мовна моделлю допомагає з форматуванням тексту і цитатами. Я вважаю що зараз більшість авторів це використовую, адже це допомагає і пришвидшує роботу. Люди друкують книги за допомогою ШІ і це нормально. ЛЛМ по суті — це «Китайська кімната» вона не думає, а аналізує дані і дає максимально наближену відповідь, а ми вже вирішуємо використовувати це чи ні. Так що не бачу нічого поганого в використанні ллм в допомозі написанні статей.

То Стівен Кінг міг просто написати «Головний герой дуже сильно налякався» й цього буде достатньо? Адже він передав «хід думок і направлення». Чи формулювання власних думок є чимось більшим?

Ви серйозно вважаєте, що, скажімо, художні засоби висловлювання не мають жодного практичного сенсу та мають бути виключені з комунікації? Що гіперболи, порівняння, риторичні запитання нічого не варті та ніяк не допомагають донести думку, яка завжди буде однаковою, яку б форму її донесення не обирати?

Що те, як саме висловлюється людина, відображає його спосіб мислення та сприйняття світу? Що достатньо сказати «ніжно», бо «ніжно, як пелюстка першого проліску» висловлює абсолютно те саме?

Коли я бачу очевидно згенерований текст, то як я можу зрозуміти, що за ним стоїть думка людини, а не «думка ШІ»? Я маю просто вірити, що «основні» думки належать людини і у такому тексті? Чому? Як зрозуміти, що «хід думок та направлення» належать людині, якщо з тексту відверто стирчить генерований текст?

Гарна і актуальна стаття і поради

Нарешті допис на тему АІ без води і хайпу, все по ділу. Автору респект, гарне summary.

на одну строку коду припадає три строки пояснень

* один рядок коду, три рядки пояснень

кодінг — кодинг

Скоро буде так
«Писати сьогодні код на мовах високого рівня, це всеодно що писати код 10 років назад на ассемблері»))

який ти не зможеш підтримувати в подальшому

Просто происш AI привести код в порядок без хаосу))

Потім помірний хаос — код є, але ти вже не зовсім розумієш, як і навіщо половина з нього взагалі існує. І нарешті, якщо вчасно не зупинитись, — класичне болото, з якого важко вибратись.

ну так можна ж усе те болото назад у ші завантажити .. і попросити освіжити...

помірний хаос — код є, але ти вже не зовсім розумієш

у ші завантажити і попросити освіжити

і отримати іншу комбінацію того самого, або запросити помірний соах-док, з ненульовою але крихітною вірогідністю зрозуміти?

є таке поняття дедуплікація... видалення дублів...
Причому не тільки буквально однакового тексту...
А дублів по суті... це може тільки ші...
........
Можна налаштувати — скільки залишити ... 5... 10 ... 15 відсотків...
Ну і далі нормалізувати те що залишилося...

Я не пам’ятаю коли останній раз дебажив. Кажеш ШІ знайти проблему, і він знаходить. Якщо ні, просиш добавити тимчасові логи (старий добрий print, але з ШІ тепер це дешево — дешево добавляти і аналізувати. Ще чув про таку техніку як попросити перебрати всі можливі комбінації вхідних параметрів, які приводять до цього стану, і потім знайти причину де і як ці параметри змогли пролізти.

Вангую темні часи джетбрейнсу.

Також слід врахувати, що LLM свідомо генерують гірший код, ніж можуть, щоб користувачі змогли довше ними користуватися, а компанії — заробляти більше грошей.

Такої теорії змови я ще не чув, цікаво :)

Ну ще розкажіть, що знаєте, чому не роблять вогнетривкі лампочки.

Я колись прямо запитав ChatGPT про те, як він генерує код та реагує та команди про його виправлення. Тоді він мені сказав, що фіксить крок за кроком, не все разом і це тому, що саме так і працює людина, яку він імітує. А отже, для ефективної роботи потрібно вести з ним діалог та фіксити послідовно. Як раз те, про що Андрій сказав.

Так, можна зробити інакше та змушувати його працювати інакше, однак основне питання в іншому. Чи ми в курсі всіх отаких «правил», які зашиті у мовну модель та які варто враховувати при роботі з ними? Озираючися на вже довгу нашу практику з LLM можемо стверджувати, що більшість таких цікавих знахідок виявляються суто практично — розробники не сповіщають нам про новий «характер» чергової версії моделі. Для передбачуваної розробки це так собі механізм.

«Правила» зашиті в в конкретний чатбот або агента, а не в модель. Модель це як бекенд з API, вся обробка промптів і редактура відбувається на рівні «фронтенда», чатбота чи агента. Напишіть свій, підключіть до будь якої моделі на свій смак і будете повністю контролювати всі «правила».

Йдеться про «правила», що визначають принципи роботи/навчання генеративних мовних моделей трансформерів.

А, ну якщо про ці «правила» мова, тоді єдиний вихід це локальна модель, перенавчена згідно ваших вимог.

Тільки висновок, що вайб кодінг лише проміжний етап при переході на мови програмуаання над виского рівня. В 1957 Джон Бекус і команда створили Fortran, бо можливості компьютерів призводили до складності программ, підтримка яких людини на безпоспредньо ассемблері в пограмному коді, вже виходила за можливості людської психіки тримати такі об’єми программного коду в голлові на такому рівні абстракцій. Хоча перший Еniac програмувася ще методом прямої комутації каналів, дівочою командою які до цього були рахувальницями на арифмометрах, що замикали проводи із разйомами отримуючи потрібну программу таким чином, змінено Фон Нейманом на программний код в RAM для наступного EDVAC, коли «замикання» робив окремий електроний блок по командах з пам’яті.
За великим рахунком із часів Fortran, ми прийшли виключно до синтаксичного покращення, а також готових бібліотек та фреймверків, шаблонів проектування тощо. Але в цілому ви як в Fortran чи Algol 60 оперували базовими операторами, так це робе і Rust усе інше це просто кращі перевірки, діагностичні помилки компіляції і т.п. щоби допомогти програмісту із когнетивною складністю відносно низького рівня асбтракцій програми.
Ідея над високого рівня програмування, ви оперуєте на більш високому рівні абстракцій. Умовно описуєте користувацьку історію (user story), та крітерії прийомки якості (acceptance criteria), можливо ще щось типу діаграми мікросервісів і т.п. ШІ — геннерує програмний код, тести і т.д. Ви перевіряєте і вносите корективи при потребі.
Звісно це докорінно новий рівень абстракцій, коли з рештою можливості людскої психіки вище за когнетивний бар’єр згенерованого коду.
Чого не вистачає зараз — це можливості фіксувати високорівневі промпти, етапи розвитку ПЗ, в системах котролю версій, те що є на нижчому рівні. Тому ми приходимо до стану не підримуємості вайбкодінгу, бо по факту це те саме, що зберігати скажімо скомпільовані exe файли в git, або їх ассемблерний лістінг. Звісно пітримувати це буде не можливо з рештою, тим більше коли ассемблерних команд там мілліарди.

Ніхто не забороняє вам вести логи сессій, можна навіть зберігати їх зрізи разом з комітами коду в системі контролю версій. Я так і роблю, наприклад (але додаю все в гітігнор, бо над проектом працюють інші люди та їх агенти теж). Я майже весь час (і токени) витрачаю на планування роботи агента, генерація коду, тестів та тестування (особливо в асинхронному режимі з субагентами) займає мінімум часу. Всі архітектурні рішення, виявлені помилки, недокументована поведінка сторонніх API, розроблені мною safeguard protocols, тощо, фіксується в PROJECT.md, session.md, тощо. Ну і в memory самого агента. А як інакше?

Ті, хто жаліється на те, що сгенерований код виходить з під контролю, імовірно не зробили нічого, щоб керувати складністю проекту і фіксувати рішення, не вміють планувати. Агенти та моделі тут ніпричому. Схоже, що нити про technical debt та жонглювати іншими базвордами їм простіше, ніж вмикати власний мозок.

Це принципово не коректне порівняння. Рівні абстракції мов програмування всі були детерміновані. Умовно, якщо раніше треба було написати явно про звертання до певної адреси у пам’яті, резервування певного її обсягу, записування туди даних, то потім це все це просто приховали за просте визначення змінної типу «х = 2». Під капотом так само залишаються всі ті кроки по роботі з пам’яттю.

Те, що робить LLM працює абсолютно за іншим принципом вгадування наступного токену плюс варіативність цього процесу через ймовірність обрання різних токенів.

Отже, це ніяк не новий рівень абстракції, але щось інше. Порівняння з природою мов програмування високого рівня маніпулює свідомістю людей, вводячи їх в оману, що ми отримали так само точний рівень абстракції, як при переході з мови асемблера на джаваскрипт. Це абсолютно не так.

Підписатись на коментарі