Експеримент із вайбкодингом можна вважати завершеним. Мета експерименту — зрозуміти, наскільки це життєздатний метод розробки, наскільки він ефективний і які його обмеження.

Як задачу я обрав розробку iOS застосунку. По-перше, я взагалі не цікавився цим останні 10 років, а по-друге, мені його бракувало. Суть застосунку — автоматизувати рутинні операції за допомогою LLM. У моєму випадку це виправлення моїх кострубатих текстів англійською та українською, переклад на англійську і болгарську та саммарі веб-сторінок. Розробка подібного для Raycast зайняла в мене один вечір. Тобто проблема була саме в розробці під iOS. І цю частину мала повністю на себе взяти LLM. А моє завдання було в тому, щоб LLM мінімально допомагати.

Підсумок такий: застосунок вдалося створити за 60 годин. Він працює і виконує свої функції. Це 6 екранів, кастомний зовнішній вигляд і 6500 ncloc swift-коду. У нього з десяток незакритих проблем, але з ними можна жити. Він завантажений у TestFlight, звідки я можу його роздавати. І він, швидше за все, не пройде модерацію через невідповідність гайдлайнам 🙂

Висновки:

  • Я точно не зміг би самостійно розробити такий застосунок за 60 годин. Занадто багато всього довелося б вивчати.
  • Я втратив годин 15 на боротьбу з xcodegen, вибудовування обв’язки навколо нього, swiftlint, swiftformat тощо. Якби я відразу взяв tuist, то, скоріш за все, не втратив би по парі годин на елементарні задачі, типу “застосунку немає в діалозі share через неправильну вкладеність у YAML” або “іконка застосунку не з’являється через помилку в назві”.
  • З іншого боку, якби я не намагався одразу зробити середовище, де все можна зробити через CLI, то я б досі за інструкціями тикав кнопки в Xcode.
  • З цього випливає важливість побудови максимально швидкого для LLM циклу change/test. Через CLI або MCP, можливо. Чим він буде швидший і чим кращими будуть повідомлення про помилки, тим швидше йтиме розробка.
  • Знайомство з базовими концепціями, скоріш за все, значно прискорило б розробку, за рахунок уникнення помилок і “костилів”.
  • Модель зовсім не вміє узагальнювати за наявним кодом. Досвідчений програміст зазвичай заднім розумом відчуває місця, де краще закласти абстракцію під майбутні зміни (так званий “технічний зазор під майбутні костилі”). У мене в базових інструкціях була вимога пропонувати 2 методи поліпшення коду наприкінці кожного завдання. І там жодного разу не було нічого путнього на рівні всієї архітектури. Через це доводилося іноді просити її робити рев’ю архітектури, і там уже були цілком корисні поради.
  • Потрібно постійно допрацьовувати інструкції, додаючи туди часті помилки, нові вимоги тощо. І навіть це не допомагає при довгих сесіях, коли модель починає “забувати” початок. Наприклад, у мене це були постійні спроби імпортувати код із модуля Common, хоча він був видимий і без імпортів.
  • Потрібно постійно підтримувати проєкт у правильному стані з точки зору лінтера і тестів.
  • Іноді простіше почати виконання задачі спочатку, ніж намагатися розібратися, що не так у поточному рішенні.
  • Підтримка картинок у cursor — це приголомшлива фіча для пояснення проблем. Цілком можна вирішувати навіть питання вирівнювання та інших GUI-проблем. Робиш скріншот, обводиш проблемне місце, завантажуєш в IDE. Якщо LLM не заплутається з тим, з чого складається відступ, то може й виправити 😉
  • Наступного разу, якщо я вирішу розробляти з нуля в незнайомій інфраструктурі, це буде:
    • дуже ретельний вибір тулінгу з максимальною валідацією та чіткими повідомленнями про помилки
    • максимально детальне ТЗ, яке буде постійно актуалізуватися (можливо, варто відмовитися від architecture.md та implementation.md із memory bank)
    • короткий і зрозумілий для моделі цикл change/test із зрозумілими повідомленнями про помилки

Але попри все застосунок написано і:

  • працює з указаним ключем OpenAI
  • перекладає, спрощує, сумаризує, виправляє помилки
  • уміє перекладати клингонською і синдариною