fa
Feedback
Мамкін Архітектор

Мамкін Архітектор

رفتن به کانال در Telegram

Для звʼязку пишіть @ska_9000 Канал про айтішечку, автор якого трохи пожив життя і може пояснити за бекенд, веб, мобайл, автоматизацію, клауди або як раніше було краще.

نمایش بیشتر
3 015
مشترکین
+524 ساعت
+607 روز
+18430 روز
آرشیو پست ها
Disaster recovery це просто, особливо для тих, хто його ніколи не робив. Впав сервак, в тебе є другий. Впав дата-центр або availability zone, ти запускаєш резервний. Впав регіон, що буває дуже рідко, але provider має декілька регіонів, тому ми робимо мульти регіон. Ну а якщо впав вже провайдер, що майже ніколи не стається, тоді додаємо іншого провайдера. І такий сетап здається абсолютно bulletproof. Різні варіанти, ready standby, multi master і багато інших цікавих термінів з курсів про системний дизайн. Зробили і сидимо, скролимо твітер, та нічого не боїмось. От і Datadog так думали, пʼять регіонів по AWS, Azure і GCP. Аж поки ще у 2023-му вся ця краса не згасла одночасно. Не землетрус і не пожежа, а рутинний апдейт. Патч для systemd (програма, що керує сервісами на лінукс-серверах) рестартнув мережевий сервіс, а той має звичку викидати всі маршрути, які створив не він. Cilium (те, що будує мережу між контейнерами в кубернетесі) тримав свої правила маршрутизації подів просто в ядрі, systemd не впізнав їх як свої і повидаляв. Чому він це зробив? Тому що може, в лінуксі правила міняти дозволено будь-якому процесу. Звʼязок між нодами обірвався, і не в одному регіоні, а скрізь, бо апдейт викотився на всю гопотеку (40К серваків) в один і той самий момент. Про те, що прод лежить ти зазвичай дізнаєшся від Datadog, до того, як прибіжать юзери. А от коли падає сам Datadog, шо робити? Інженери діагностували і фіксили аварію як діди колись, через ручні SSH-сесії й консолі провайдерів. Розважались майже добу, поки воно не піднялось. І часом дуже добре, шо ти не Датадог. (деталі історії можна подивитись у цьому відео)

Писали ми тести для флоу, де користувач підписує документ через віджет id.gov.ua і атачить його у наш застосунок. Тест на Playwright генерував DeepSeek, він слухняно відкрив сторінку, потицяв кнопки, а підпис не пройшов. Далі він трохи поколупався, погуглив і зібрав красиву теорію, чому ні. Теорія така. Браузер не дає скриптам підробити довірену подію. Прапорець event.isTrusted стає true лише тоді, коли клік зробила жива людина, а не код. WebCrypto без цього прапорця підписувати відмовляється. Отже, поставити підпис автоматично неможливо в принципі, і це обмеження безпеки браузера, а не проблема Playwright. Звучить круто, у це легко повірити і наче час писати в тікет "автоматизувати не можна, кличте тестувальників". Я подумав, шо добре було б написати про це пост сюди, але вирішив трохи фактчекнути, шоб потім не розгрібати коменти. Закинув історію в Claude Code, і виявилось, шо DeepSeek трохи перебільшив. WebCrypto узагалі не вміє ДСТУ 4145, підпис накладається кастомним JS / WebAssembly. А isTrusted справжній, підробити його з коду дійсно не вийде, але тільки якщо кидати подію програмно, через dispatchEvent. А Playwright так не клікає. Його click іде через протокол керування браузером, на рівні самого движка, і для сторінки цей клік невідрізняний від людського, isTrusted у нього чесний true. Тобто та єдина стіна, об яку тест нібито вперся, Playwright спокійно проходить наскрізь. Я дав цей вердикт назад DeepSeek, той подивився, визнав свої помилки, зробив декілька спроб і у нього все вийшло. Виявилось, шо він пропустив десь селектор, куди тицькати чи ще щось таке. З ким не буває. Тому замість посту про обмеження тестування в браузері маємо цей, де обмежень майже немає. Навпаки, Playwright у парі з AI це дуже потужна зв'язка. І навіть не для автоматизації, а для exploratory тестування — треба щось потикати в браузері, використовуєте скіл playwright-cli і не паритесь. Наступного разу, коли агент скаже вам "це технічно неможливо", спитайте, чи він просто не знайшов селектор.

Чув колись анекдот про солдата який косив траву біля штабу. Офіцери виходили на перекур, бачили його і пропонували різні покращення, типу "позаду граблі причепимо, щоб одразу траву згрібав". Після чого зазвичай отримували підвищення. А останній ніяк не міг придумати, і йому сам солдат запропонував "ще ліхтарика мені на лоба почепіть, шоб я і вночі косив". Згадав я його, коли прочитав пост з дружнього каналу про /loop і /goal. Колись все починалось з контекстних підказок від copilot, потім чат, відповіді якого треба було копіпастити, потім агенти, шо все самі роблять. Але хто ми такі, шоб не хотіти більшого. Ось наприклад, агенти простоюють вночі, коли ми спимо, або ж постійно відволікають питаннями, на які відповідь "ага, роби як кажеш, мені ок". І тут як рез ці самі лупи і голи стають в пригоді. Можна запустити цикл "перевіряй CI кожні 10 хвилин, як щось задеплоїться, запускай тестування". Або ж "ось тобі мета — досягнути 100ms затримки на цьому ендпоінті. Роби шо хочеш, але треба 100ms". І усе — далі можна йти відпочивати, агент з усім розбереться. Зупинити його може або досягнення цілі, або витрачання лімітів. Такі інструменти змінюють модель від реактивної до проактивної взаємодії. Замість того, аби питати "ой, в мене тут помилки в логах, шо робити?", хай агент парсить ті логи і тригериться, коли бачить помилки. Заводить баги і фіксає. Користуєтесь таким? Накидайде ваших сценарієв в коменти.

Багато розробників живуть в IDE і не скаржаться. Проте щойно треба щось зробити з іншого компа, виникає питання із серії "а как какать". Як підключитись, AnyDesk? TeamViewer? Обидві схеми працюють, але однаково незручні, вибагливі до якості мережі і зазвичай лагають. А поціновувачі консолі цим не паряться. Підключаєшся по SSH і одразу опиняєшся в знайомому терміналі. Усе, що треба, або вже є, або можна доставити однією командою. Якщо дуже треба і хочеться, можна сінканути свої dotfiles і тоді взагалі все буде як вдома. Vim виглядає так само, як і на локальному компі, а ви спробуйте таке з vscode чи повноцінною студією / ідеєю. Дисконект теж не вбиває сесії, робота спокійно чекає на тому боці, і про це я вже писав тут (TL;DR: tmux / herdr). Чого знову про це пишу? Справа в тому, що для розробки на базі AI агентів цей сетап ще більш прикольний. На старому Intel-маку, що завжди увімкнений вдома, крутиться пачка агентів Claude Code. Закриваю ноут, іду у справах, воно молотить саме, повертаюсь, а задачі вже зроблені. Заходжу і з телефона, через клод-апку, тож замість залипати в тікток, або паралельно з ним, можна надиктувати агенту фронт робіт, щоб токени не простоювали. Все це залізо сидить у мене в tailnet, тож назовні нічого не стирчить, жодних відкритих портів, а доступ є звідусіль. Бонусом основний ноут майже не гріється, бо вся робота йде деінде, тож на ньому спокійно можна дивитись ютубшортс і читати твітер. Хай GUI-фанати далі воюють з лагами AnyDesk, а я поки закрию ноут, воно й без мене все доробить.

Пост про довіру здається зачепив: купа коментів, репости з обговореннями на інших каналах. Тож піддамо жару. Одне з питань було таке: нагнав пурги, а шо робити конкретно не сказав. Зараз скажу (в той пост не влізло б все одно). Почну з того, щоб заохочувати часті коміти й пуші. Як мінімум раз на день розробник має щось запушити в репу, і якщо цілий день нема нічого, це привід спитати. Бо це ж вісім годин, і що могло настільки зайняти час, що не знайшлося хвилини на рядок коду. Може, були суцільні мітинги, де ту саму фічу й обговорювали, радились зі старшими чи розбирали вимоги, і тоді це вже ознака, що задача непропрацьована. А може, людина в щось вперлась і ніяк не могла зрушити, і тоді краще було б попросити допомоги раніше, розблокуватись і спокійно все доробити. Далі гігієна роботи з інструментами. У трекері задача має бути призначена на того, від кого чекаються наступні дії. А то таска висить на Миколі, а він насправді чекає відповіді від Наталки, і про це не знає ніхто крім них, та й вони вже забули. Статус має відповідати дійсності: двадцять задач "в прогресі" означають, що фокусу нема, а по факту в роботі може не бути жодної. І будь-які зміни, домовленості, обговорення мають бути в описі чи коментах, а не в чиїхось головах. Якщо вже ставите оцінки, відстежуйте, наскільки в них попадаєте: регулярний розбір показує, що ви оцінюєте надто оптимістично чи навпаки, і допомагає відкалібрувати лінійку, щоб естімейти бодай нагадували правду. А поверх цього важливі метрики: скільки разів перевідкривали задачі, скільки багів зловили ми, а скільки вже замовник, скільки часу проходить від ідеї до задеплоєної фічі. Плюс дашборди здоровʼя проєкту й команди, щоб це було видно саме собою, а не збиралось руками раз на квартал. Усе це має жити в атмосфері no blame. Не атакуємо конкретних людей, будь-яка проблема піднімається до процесу й до проєкту, де доречне слово "ми". Якщо ж під час розбору виявляється, що корінь таки в конкретній людині, це вже переходить у площину HR і роботи з людьми, а це поза скоупом цього поста. І ось так складається система, яка сама себе регулює й контролює та працює майже незалежно від того, наскільки ми одне одному довіряємо. Повторю тезу з першого поста: довіра це чудово, добре коли вона є, тільки вона не має бути необхідною умовою роботи. Ми будуємо все на даних, і саме дані міряємо й контролюємо. Звісно, будь-яку метрику можна підкрутити, будь-яку систему хакнути. Можна. Тільки такі спроби так само видно, і одразу виникає питання: а нахіба. І ми знову впираємось у площину людей, бо за цим зазвичай або саботаж, або бажання щось приховати, тобто саме те, що здоровою взаємодією не назвеш. І ще: робота це не приватний простір, і так було завжди. Ваші чати можуть прочитати, ваш код перевірять, ваш перфоманс поміряють, і це стосується всіх однаково, від джуна до тімліда. Причому прозорість працює в обидві сторони: ту саму метрику, якою міряють вас, ви першими й бачите. Питання лише в тому, чи ви від цього ховаєтесь, чи витягуєте з нього користь. Ви ж не думаєте, шо ви ідеальні і покращувати нема чого? Чи думаєте.

Хто купував квитки на поїзд, той в цирку не сміється. Ви мабуть знаєте цей ритуал. Продаж відкривається за N днів до відправлення, о восьмій ранку, ти оновлюєш застосунок, і він закономірно підвисає, бо в цю саму секунду те саме роблять ще тисячі людей. Далі обираєш поїзд, бачиш список вагонів і вільних місць, тицяєш потрібні, і десь тут може вискочити "місце вже викупили". Якщо пощастило і не вискочило, вводиш пасажирів на кожне місце, добре хоч дані запамʼятовуються. А потім зʼявляється банер про бронювання (пікрілейтед в коментах), і ти чекаєш. Мінімум пʼять хвилин. Наприкінці цих пʼяти хвилин буде або успіх і оплата, або сухе "квитки викупили", і все починається спочатку: знову поїзд, знову місця, знову пасажири, звісно, з ризиком ресету прогресу на початок квеста. Трохи підкумарює. На всякий випадок дисклеймер: я поважаю людей, які це робили. Стало явно краще, тепер не треба займати чергу о пʼятій ранку в касу. Плюс всієї правди ми не знаємо, і взагалі з дивану завжди краще видно. І от я дивлюсь з дивану і бачу цілком впізнавану архітектуру, заточену на виживання під піковим навантаженням, обумовленим бізнес-специфікою. Швидше за все попереду стоїть якийсь фасад, такий собі кеш наявності, який оновлюється не миттєво, а за розкладом. Уся движуха до банера про бронювання крутиться на ньому, тому вибір місць швидкий і дешевий. А коли ти підтверджуєш, твій запит лягає повідомленням у чергу, яка опрацьовується... по черзі. Поки до тебе дійде, місце могли зайняти везунчики, чиє повідомлення було попереду, і тоді "всьо фігня Міша, давай по новой". Або фасад просто не встиг оновитись, ти бронював давно продане, і дізнаєшся про це аж за пʼять хвилин, за які розберуть і решту. Є в мене підозра, що це довге очікування зробили навмисне (може взагалі додали штучний таймер), та й весь цей незручний UX з купою повторюваних дій тут не випадково. Поки людина шукає кнопки і друкує паспортні дані, вона не довбить бекенд запитами, тобто повільний UX працює як природний тротлінг. Звучить розумно, але не сходиться: уся ця метушня все одно генерує запити, і замість умовних пʼяти на одне замовлення виходить пʼятдесят, більшість з яких ще й тягне неактуальні дані з фасаду. Виходить lose-lose, де і користувачі бісяться, і бекенд стогне. Проблеми зрозумілі, але шо з ними робити? Чи можна спроектувати зручніше та ефективніше рішення? Думаю, варіанти можна буде почитати в коментах, а згодом я напишу свою версію.

Буває таке: розробник ставить оцінку на тиждень, зникає на чотири дні, і повертається з пул-ріквестом, де коду на три години з перекурами. Потім дуже ображається, коли у нього запитують пояснення, розказує, шо там було складно, він багато думав, і взагалі "ви не зрозумієте". Лишається відчуття, що тебе трошки намахали, але казати це вголос не можна, бо це не екологічно. Перша реакція тут завжди про довіру: збудуй здорові стосунки, психологічну безпеку, і все станеться саме собою. Те саме підносить і аджайл-маніфест, де люди і взаємодія важливіші за процеси та інструменти. Звучить гарно, тільки довіра як фундамент не просто крихка, вона ще й неефективна: ти закладаєш результат на те, що команда спрацьована і всі як один, а так буває далеко не завжди. Добре побудований процес навпаки знижує вимоги до команди і витягує той самий результат, а часом і кращий. Ідея проста: зробити неправильно має бути тупо незручно, а зробити нормально найлегшим шляхом. Тоді нікому не треба вірити на слово, ти просто бачиш, що відбувається, бо процес сам нагадує учасникам, що від них треба, не покладаючись на чиюсь сумлінність у поганий день. Гарна аналогія тут шахи, де на дошці видно все. Ніхто не ховає фігури від суперника і не сподівається, що той чогось не помітить. У безпеці цю ідею назвали zero trust: дефолтної довіри нема, кожен запит верифікується наново, і від цього індустрія чомусь не вмерла, а стала надійнішою. На роботі так само, "Trust Me, Bro" варто прибирати скрізь, де є чим замінити, а де перевірити поки нема як, спершу будувати спосіб перевірки. Заважає тут не технологія, а культура, бо "ти мені не довіряєш?" звучить як докір, на який ніяково виправдовуватись. Насправді має бути: ні, не довіряю, і не повинен, я просто хочу, щоб усе працювало незалежно від довіри. Та сама історія зі звичкою ображатись на самі питання. Якщо тебе питають по роботі, у тебе просто має бути відповідь. А всі оці "та там складна система, ви не зрозумієте, треба погружатись в контекст" здебільшого відмовки, бо хто реально володіє темою, пояснить її навіть п'ятирічному. Здоровий флоу тут як request-response з SLA: є запит, є відповідь, і ніхто не ображається, що його смикнули. А ще краще, щоб відповідь завжди була доступною, на дашборді чи в метриках: на перший запит даєш посилання на джерело, на другий на інструкцію, а на третій вже законне WTF. Знаю, половина читачів вже закочує очі і пише про токсичність і вигоряння. Останніми роками вигоранням стало геть усе: не завезли печиво, тімлід попросив показати прогрес, спитали "а нашо тут кубернетес". Час помацати траву. А у вас на проекті вся дошка на видноті, чи добра половина фігур тусується під столом та по курилках?

Algorithms in Practice — курс-лонгселлер камерної школи компʼютерних наук CS Osvita. Цю програму завершили вже 200+ розробник
Algorithms in Practice — курс-лонгселлер камерної школи компʼютерних наук CS Osvita. Цю програму завершили вже 200+ розробників, які навчилися застосовувати алгоритми як інженерний інструмент, а не академічну теорію. Про що курс? Це інтенсивний курс, який поєднує алгоритми, системне мислення та реальні задачі з інженерної практики. Сучасні системи вимагають розуміння, що відбувається під капотом — як працюють структури даних, чому певний підхід швидший, як мислять автори великих бібліотек і чому алгоритмічні рішення визначають якість продакшн-коду. Результат після курсу: :: Глибоке розуміння алгоритмів на рівні продакшну. :: Уміння проєктувати рішення та оптимізувати код під реальні обмеження. :: Готовність проходити алгоритмічні інтерв’ю в FAANG і Big Tech компаніях. :: Практичні підходи, якими вже користуються наші випускники в міжнародних компаніях. Викладач та автор програми: Іван Петрушенко, Engineering Lead at SQUAD, засновник CS Osvita. 14 років інженерного досвіду та 8+ років викладання для middle та senior-розробників. Старт: 23 липня Тривалість: 4 місяці >_ Реєструйтеся на курс, щоб нестандартно вирішувати складні робочі завдання https://cutt.ly/Pt46Pvvc

В пості пана Сіпласпластика майнула думка про магію в Java, і це трохи мене зачепило. Бо магію в коді взагалі прийнято недолюблювати, а мені зазвичай воно подобається. Проте магія буває різна, і різниця не в тому скільки її, а в тому, шо ти бачиш своїми очима, коли відкриваєш файл. Ось наприклад Rails. has_many :posts, validates :email, presence: true, а в тестах RSpec щось типу expect(user.name).to eq("Bob"). Під капотом там купа метапрограмування, method_missing, перевизначені класи, і це справжнісінька магія. Але вона лежить прямо перед тобою і читається майже як звичайне речення. Тіло класу в Ruby це не декларація, а звичайний код, шо виконується зверху вниз, тому has_many це не синтаксис мови, а виклик методу, який на льоту дописує свій клас. DSL побудований повністю засобами самої мови, і ти можеш залізти всередину, перевизначити, розширити, бо це твій код, шо працює тут і зараз. А тепер "магія" в Java. Реалізується здебільшого через анотації, наприклад @Transactional, @Autowired, @Entity. Виглядає компактно, навіть охайно, але анотація сама по собі не робить нічого, вона лише маркер, порожня метадата. Шоб вона запрацювала, Spring на старті обгортає твій бін у проксі, який перехоплює виклик, читає анотацію через рефлексію і вже тоді робить справжню роботу. Те, шо написано, і те, шо відбувається, розділені прірвою абстракцій. Це абстракція, яка дуже швидко може почати протікати. Класична пастка: викликаєш @Transactional метод зсередини того ж класу, через this.method(), і транзакція чомусь не застосовується. Бо проксі перехоплює тільки виклики ззовні, а внутрішній іде повз нього. Анотація на місці, виглядає правильно, а магія щезла, і шоб це зрозуміти, треба тримати в голові не свій код, а механіку Spring-проксі. Ось це і є пласкість, коли поведінка прив'язана не до того, шо ти написав, а до того, як фреймворк це десь там інтерпретує. Але в пласкості є й зворотний бік, який багатьом саме й подобається, це передбачуваність. @OneToMany прямо каже "тут спрацює хтось збоку, іди читай Hibernate", і ти хоча б знаєш, куди дивитись. Ruby-магію ж легко писати, але важко читати, бо у великому Rails-проєкті, шоб зрозуміти шо нагенерував один has_many, треба знати фреймворк майже напам'ять. Метапрограмування завжди розмінює зрозумілість на виразність, і кожен сам вирішує, шо йому важливіше. До речі, це не вирок усій платформі, а саме мові, Java, бо той же Kotlin з extension functions вміє в людські DSL на тій самій платформі. Я жодну з них не знаю настільки глибоко, шоб сперечатись про продуктивність. Сподіваюсь, в коментах це зроблять профі. Для мене це більше естетика і субʼєктивність. Одне викликає захват, а інше просто "ну, анотації. Окей". А де у вашому стеку є магія, яку реально приємно читати?

Хто давно на каналі, той знає мою слабкість до редіса. Я цілком серйозно вважаю його однією з найнедооціненіших баз даних, а не просто кешем, і коли в чаті хтось питає "редіс чи memcache", мені завжди здавалось, шо тут і думати нема над чим. Редіс вміє все, шо вміє memcache, плюс ще десяток структур даних, персистентність, pub/sub, скрипти, та купу всього зверху. Очевидний вибір, по очках виграє з розгромним рахунком. І ось я натрапив на текст, який поставив цей аргумент догори дриґом. Бо вся ця універсальність, через яку я редіс і люблю, для опсів перетворюється на проблему. Спочатку воно залітає як кеш, але редіс це повноцінна база, і рано чи пізно якийсь розробник кладе туди дані, без яких сервіс уже не запуститься. Свідомо такого ніхто не вирішував, воно просто наросло само, і тепер у вас є тиха залежність, якої нема в жодній документації. А далі апгрейд версії або міграція на новий інстанс, і кеш стартує порожнім. Справжній кеш на це б навіть не зморгнув, прогрівся б наново з бази і поїхав далі. Але цих даних у базі нема, вони жили тільки в редісі, тому сервіс не піднімається. Опси про цю залежність не знали, моніторингу на неї не було, бо хто ж моніторить, шо кеш не загубив дані. memcache такого не дозволяє by design. Він не вміє в персистентність, тому план покластись на нього як на сховище зафейлиться на старті. Клієнтські бібліотеки за замовчуванням ігнорують помилки з'єднання, тобто інстанс впав, get повернув дефолтне значення, сервіс пішов у базу і живе далі. Шардінг теж на клієнті, ніякого кластера піднімати не треба (бо кластеризація не підтримується, лол), відвалився вузол, клієнт викинув його з ротації і потім сам тихенько перепідключиться. І все це настільки легке, шо можна тримати десятки інстансів не думаючи про них взагалі. Виходить, те, шо робить редіс кращим продуктом, робить його гіршим кешем. Не тому шо він повільніший чи дірявіший, а тому шо він дозволяє забагато, а можливість зробити дурницю рано чи пізно хтось та використає. Я свою думку про редіс не міняю, він прекрасний там, де вам справді потрібна база зі швидким доступом. Але якщо команді треба саме кеш і нічого більше, то простота memcache це не обмеження, а фіча. А у вас прод колись лягав через те, шо хтось тихенько перетворив кеш на базу? Натхнення для посту я брав тут: https://jchri.st/blog/in-praise-of-memcached/

Рік тому Cloudflare активно борола ШІ ботів, а цього тижня зробила для них тимчасові акаунти (https://blog.cloudflare.com/temporary-accounts/), де агент деплоїть код в один рядок. Пише wrangler deploy --temporary і все вже в інтернеті, без sms та реєстрації. На льоту створюється акаунт, видається токен, код деплоїться. Живе воно 60 хвилин, за цей час можна забрати акаунт собі по claim-лінку, а як забив, воно само зникає. Штука цікава сама по собі, але якшо відмотати цю історію назад, картинка стає геть інша. Спочатку була війна. Влітку 2025 вони врубили блок AI-краулерів (https://developers.cloudflare.com/bots/additional-configurations/block-ai-bots/) за замовчуванням, кожен новий сайт одразу під захистом, ботів просто не пускають. Придумали AI labyrinth (https://developers.cloudflare.com/bots/additional-configurations/ai-labyrinth/), аби боти там губились і витрачали усі токени в намаганнях вибратись. Потім запустили pay-per-crawl (https://developers.cloudflare.com/ai-crawl-control/features/pay-per-crawl/what-is-pay-per-crawl/). Логіка проста, не хочеш блочити, то бери гроші. Бот стукає на урлу, а йому замість контенту прилітає 402 і цінник в хедері. Платить, тоді отримує. Тобто від "забирайтесь геть" швидко перейшли до "ну добре, але платіть на вході". Далі зробили Web Bot Auth (https://developers.cloudflare.com/bots/reference/bot-verification/web-bot-auth/), це коли агент підписує свої запити криптографією, а сайт по підпису розуміє, шо це за бот і чи можна йому довіряти. Замість гадати по IP і user-agent, агенти тепер можуть чесно представитись. Туди ж підтягнули Visa, Mastercard і Amex, бо якшо агент іде шось купувати, треба розуміти, хто він і чий гаманець. Разом з Coinbase підняли x402 (https://blog.cloudflare.com/x402/), протокол, шоб оплати між агентами і сайтами стали загальним стандартом. А тепер от тимчасові акаунти, де агенту дають вже не дані купити, а прямо задеплоїти свій код. Десь тут навіть закрадається думка, а чи не агент цей функціонал написав в перервах під час очікування апруву чергового плану від людини. А потім і запостив анонс 🙂 Ось так за рік Cloudflare крутнула на всі триста шістдесят: вчора агентів блокувала на вході, а сьогодні робить їх клієнтами. І це, схоже, лише початок. Все більше рутини перекладається на агентів, а сьогодні купа їхніх сил іде на те, шоб прикидатись людьми і обходити заточені під людей перепони. Капчі, логіни, перевірки. Хто перший допре, шо простіше не воювати з агентами, а дати їм зручний вхід, той і збере новий тип клієнта. Питання тільки, шо буде далі. Зараз двері відчиняють для наших агентів, а ми з головних користувачів тихо переїжджаємо в категорію тих, хто стоїть під дверима і чекає. Хіба шо AI-бульбашка таки лусне, агентів відключать за несплату рахунків, і нам знову доведеться руками писати код, вчити python і читати мануали. Чи ні?

Велика проблема штучного інтелекту в тому, що LLM щоразу генерує різне. Один і той самий промпт кожного разу згенерує різні відповіді. Цю тезу я регулярно чую в різних дискусіях про AI, і звучить вона найчастіше саме від програмістів. Вони скептично ставляться до генерованого коду, бо він непередбачуваний. Ми ж звикли до детермінізму: шось пишеш, воно компілюється або інтерпретується і кожного разу результат той самий. А тут пишеш і хз шо вийде в результаті. Не подобається. Тільки нічого нового тут немає, та сама проблема жила в індустрії завжди. Бізнес-аналітик пише вимоги, вони проходять через голову розробника, через його трактування і його код, який цілком може бути кривим. Людина-перекладач з "де ТЗ?" в "works on my machine" ніколи не була детермінованою: даєш двом інженерам одні вимоги, отримуєш два різних рішення. Але це не проблема, бо перевіряється не код, а поведінка на виході: тести, QA, метрики в проді. Тоді чому в агента це сприймається як біда? Підозрюю, причина не технічна. Він забирає наш хлібчик і робить це часто краще, ми трошки переживаємо, що далі забере і лавандовий раф, тому стаємо в позу захисту "хм, а ти впевнений, що наступного разу воно напише правильно?". Звісно шо ні. Але ми й не повинні, бо те, що згенерував агент, треба перевірити, і це не нова вимога. Ми завжди брали з замовника гроші не лише за value, а ще й за те, що хтось окремо переконався, що цей value правильний. В інших сферах це звучало б абсурдно. Уявіть, замовили поклейку шпалер, а в кошторисі дві статті — "поклейка 100", "перевірка шо поклеєно правильно, інакше переклейка 150". А в айтішці воно нікого не дивує. І ця перевірка теж делегується агентам, причому вони і тут часто кращі за людину. Гляньте новини за останні місяці: скільки критичних вразливостей познаходили в дуже старому коді, написаному людьми, у компонентах, які вважаються еталоном інженерії. Ці діри жили там десятиліттями, і їх не бачив ніхто, поки той самий "тупий" агент не пройшовся по коду і не витягнув їх на світло. Тому так, агенти емулюють нас, і роблять це дуже добре. А з часом будуть вміти робити це краще і краще. І от мені цікаво, коли вже робота піде не шляхом імітації людини, а на рівні, який нам у принципі недоступний через фізіологічні обмеження, яких у машини немає. І який код почнуть писати агенти, коли зникне потреба, аби його взагалі читала людина, на що він буде схожий?

Git це одна зі сфер, де я вважаю себе експертом, але про worktrees почув відносно недавно, пару років назад від одного популярного ютубера. І почав використовувати, бо це зручно — мати окрему "робочу" гілку під аналітику чи якийсь інвестигейт, шоб не чіпати поточну роботу щоразу, як треба швидко глянути зовсім інше. Одна репа, кілька папок, у кожній свій бранч, і ти стрибаєш між ними без танців із git stash. А з агентами worktrees перетворились на справжній мастхев, бо коли пʼять сесій клода пиляють пʼять фічей одночасно, кожна має сидіти у своїй пісочниці, інакше вони товчуться ліктями в одній гілці і псують одне одному роботу, та й токени так палити куди ефективніше. В роботі з ними є певні нюанси, які агент може провтикати. Наприклад, залежності. В кожному worktree вони свої, бо node_modules чи venv ставляться в кожну папку окремо, тож пʼять фічей це пʼять npm install, і диск пухне на очах. Також треба прибирати за собою, бо покинуті папки самі нікуди не зникають, а якшо ти створив worktree всередині основної репи і забув про .gitignore, git ще й спробує його затрекати. Можна зловити ляща від тімліда. Або такий прикол. Запускаєш агента, він пиляє собі фічу, ти відкриваєш редактор у тій папці, де його стартував, шось там правиш руками, а агент твоїх змін не бачить геть. Бо він працює в іншій директорії, у своєму worktree, і твій корінь з мейном для нього паралельна реальність. Уся ця механіка цілком може тобі й не знадобитись напряму, бо навіть з коробки агенти вміють з цим працювати, і також є скіли, які можуть підкрутити правила і процеси (де створювати, коли видаляти тощо). Але завжди краще знати, шо там під капотом, або хоча б розуміти шо треба гуглити (чи клодити, як зараз стали казати), коли шось піде не за планом. А якщо ви дочитали до цього місця, але так і не зрозуміли, про що йде мова, чи у вас закінчились токени, фічу треба доробити, а ви не бачите, де агент наробив змін, то ось корисний пост від github, який дає відповіді на всі питання.

Коли я писав про свій ШІ-стек, в коментах запитали: чому tmux, а не Warp чи якийсь інший красивий термінал з ШІ всередині? TL;DR;: tmux я вивчив один раз і відтоді просто перевикористовую його всюди. tmux працює будь-де, незалежно від операційки, він однаково крутиться на моєму маці й на лінукс-серверах, куди я заходжу по ssh. Я налаштував його раз, навчився працювати з ним раз, і тепер це не "тул, який стоїть на цьому компі", а скіл, який їде зі мною на будь-яку машину. Сервер, чужий ноут, віддалений мак, різниці нема. Юзаю я його насамперед для організації роботи. Сесії, вікна, пейни, які розбиваєш на зручні зони так само, як в редакторі: десь редагуєш код, поруч ганяєш тести, у третьому пейні висить консоль. Тут мені скажуть, шо будь-який сучасний термінал теж то все вміє, той самий iTerm чудово ділиться. То правда, проте кожен такий інструмент хоче своїх клавіш і свого підходу, і коли ти пересідаєш на іншу машину, ти знову вчишся жити заново. З tmux я всюди як дома. Зверху на це накручуються плагіни, під будь-який смак. Я, наприклад, інтегрував його з neovim так, шо переходи між секціями відбуваються нативно, ніби tmux це просто продовження редактора (або навпаки). Також кастомний статусний рядок, в який можна вивести будь-що, включаючи відповідь "який ви хлєбушок". Є ще одна фішка, яку термінальні апки не закривають — це живучі віддалені сесії. Коли ти зайшов по ssh, запустив шось довге і тебе відрубало, сесія вмирає разом з усім, шо в ній крутилось. Натомість мій патерн: заходиш на сервер, піднімаєш там tmux і працюєш уже всередині нього, бо тепер дисконект не вбиває нічого, сесія живе на тому боці й спокійно чекає, поки ти повернешся. Так у мене на віддаленому маку крутяться агенти, поки робочий ноут лежить у сумці десь по дорозі в офіс. Для самих агентів є й заточені під них штуки, той же herdr, де вони живуть як first-class citizen і між ними зручно перемикатись, але філософія там та сама, шо й у мультиплексера, тож зараз я просто комбіную обидва підходи. Чому ж олдскул, а не cmux чи інші новинки, яких щодня виходить ціла пачка? Просто, щоб перепробувати їх усі, треба купа часу, а його трохи шкода. Я свідомо обираю контрольовану незручність: мені комфортніше працювати з тим, шо не до кінця вилизане, ніж нескінченно щось налаштовувати й полювати на ідеальну альтернативу. Може, хтось молодший і завзятіший зробить нормальний бенчмарк, поділиться, і тоді я пересяду. А поки в мене є дефолти, хай вони дідівські, але вони працюють і мене це влаштовує. А ви на чому сидите роками просто тому, шо воно вже вросло в руки і його лінь міняти?

51 зі 100 останніх пайплайнів на проекті скасовані на льоту. Один MR за ніч запустив 15 пайплайнів: один зелений, дванадцять скасованих, три червоних. Джоба на 28 секунд, яка перевіряє назву MR регекспом, чілила в черзі чверть години. Звичайний вечір, коли в репозиторії одночасно працюють пʼять AI-агентів. Сетап: Go-бекенд, пара Flutter-клієнтів, GitLab, пайплайн на 15-20 хвилин (лінт, тести, білди: все в окремих джобах). Лінійна історія через ff-merge, повна перевірка усього шо можна, і правило для агентів "мержимо лише зелене". Все, як книжка пише, тупо ідеальний CI/CD сетап. Проблеми починають лізти, коли MR-ів (Merge Request, так у gitlab звуть пулріквести) багато, а з агентами вони плодяться дуже швидко. Мержиться MR A, решта одразу відстають від main, бо ff вимагає ребейзу, тож агенти кидаються ребейзитись, а ребейз це push, тобто новий пайплайн, і всі ці пайплайни з купою окремих джобів шикуються в чергу на один ранер з паралельністю 2. Потім мержиться MR B. І все по новій: пайплайни, шо не добігли, скасовуються, агенти ребейзяться ще раз. Задача трьох тіл. У підсумку батч з 15 MR-ів мержився 8-10 годин, добре хоч вночі, ліміти підписки все одно згорають, тож хай агенти порозважаються. Формально все працювало як треба (тут має бути мем "unit tests pass, integration ones do not"): auto-cancel скасовував застаріле, кеш теплий, джоби не падали. Просто правило "кожен пуш закінчується зеленим" писалось для команди з людей. Люди роблять два MR в день і три дні чекають ревʼю. А агенти пушають кожні пару хвилин, і для них чужий мерж означає "всьо фігня, Міша, давай по новой". Шо я з цим роблю. Перед мержем лишив тільки швидке, fmt з лінтом і юніт-тести, gate стиснувся з 15 хвилин до двох. Все важке поїхало в пост-merge, тому main тепер може стати червоним, але його відкотить auto-revert бот. Ще поміняв merge_method з ff на rebase_merge, шоб GitLab ребейзив сам на сервері, а агент просто казав glab mr merge --auto-merge і йшов собі замість того, шоб годинами опитувати пайплайн. Кожен з цих кроків окремо вже дав помітний буст. CI, який був налаштований під людей, рою агентів з їхнім ентузіазмом не витримує, і просто "докинути ранерів" тут не допоможе. Треба переглядати правила: шо реально мусить блокувати мерж, а шо можна ловити вже після. А може, і саме призначення CI/CD: його ж придумали страхуватись від human factor, тільки тепер замість людей пушать агенти. А як ви вирішуєте такі проблеми? Крім того, що не використовуєте CI 🙂

Зранку я, попиваючи кавусю, накидав агентам тасок, а поки доїхав, пʼятигодинний ліміт клода вже зʼїло. Тепер маю пару годин вільного часу розказати, на чому це все тримається, коротко і з лінками. Крутиться це все на старенькому макбуку на інтелі, що завжди увімкнений. На ньому запущені паралельні сесії Claude Code, а заходжу я туди через Tailscale по ssh або через мобільний клод. Те, шо це мак, а не якийсь лінукс-сервер, виявилось плюсом, бо агенти мають доступ до маківських штук на кшталт Нотаток чи Нагадувань. Агентами диригує herdr, а git worktrees дозволяють пиляти декілька фічей одночасно і не товктись ліктями в одній гілці. Hermes Agent живе в телеграмі на тому ж маку і тягне щоденні справи та задачі. Я про нього вже писав, і з того часу він тільки приріс обовʼязками. Інтеграція з Obsidian дає йому всю мою базу знань, а синхронізується вона через iCloud, тобто нашару і доволі швидко: бот поміняв нотатку, і за пару секунд я бачу зміни у себе. Wispr Flow для надиктовування: воно реально розуміє і розбирає все, розпізнає мову, терміни і деколи навіть суржик, тож друкую я все рідше. Сайд бонус — тренується вміння зрозуміло висловлювати свої думки, бо говорити це не те саме, що писати. Зі скілів найбільше працює grill-me: він влаштовує допит по задачі, поки не стане ясно, шо я насправді хочу, а не шо написав у промпті. Через plannotator переглядаю і затверджую плани, бо тицяти коменти в браузері приємніше, ніж писати простирадла в термінал. А playwright-cli клацає по сайтах, коли треба перевірити фікс, відловити баг чи просто подивитись, шо там відбувається. А що у вас є прикольного?

Уявіть картину: чувак десь в черзі за шаурмою дістає телефон, відкриває термінал, заходить по ssh прямо на прод-сервер, де живе його продукт з тисячами платних користувачів, запускає там Claude Code і навалює нову фічу. Без гіта, без стейджингу, без CI, без код-рев'ю, без локального оточення. Зміни летять одразу в прод, з телефону, поки сьорбається лавандовий раф. Це Пітер Левелс, він же @levelsio в твітері, я стежу за ним уже не один рік і для мене це топ-вайбкодер планети, в хорошому сенсі. Його стек звучить як знущання з усього, чого нас учили: php, трохи jQuery, sqlite, і все це крутиться на одній-двох віртуалках у Hetzner. Ніякого клауда, ніякого кубернетеса, ніяких контейнерів. Код лежить прямо на прод-серверах, він підключається і редагує його на місці, а віднедавна там само живе ще й Claude Code, прямо в бойовому середовищі. Звучить як портрет бумера-самоучки, який проспав останні пʼятнадцять років індустрії, і ти такий: а шо тут взагалі прикольного?! А прикольне те, що він робить на своїх продуктах близько двохсот тисяч доларів на місяць. Не на раунді інвестицій, не на обіцянках борди директорів, а на живих юзерах, які платять за PhotoAI, Nomad List і решту його зоопарку. І отут стає трохи невдобно. Адже є git flow, pull request з трьома апруверами, CI який ганяє тести по пів години, стейджинг ідентичний проду, інфра в терраформі, мікросервіси під навантаження три користувача в годину. І шо це тепер, кому? Левелс прибрав усе, що стоїть між ідеєю і живим юзером, і лишив тільки те, без чого не обійтись, щоб за день викотити фічу і подивитись, чи за неї платять. І поки ми вилизуємо пайплайн для продукту, якого ще ніхто не просив, він деливерить з телефону. Навіть не деплоїть — править прямо на серваку, як заповідали творці php. Не те шоб я закликав всіх зносити гіт і їхати кодити на пляж (хоча а чом би і ні). Але щоразу як я втретє за тиждень підкручую ідеальний пайплайн, на фоні свербить думка, що користувачу глибоко пофіг, є в мене стейджинг чи нема, він просто хоче щоб фіча працювала. Люди типу Левелса це зрозуміли давно і відтоді спокійно рахують гроші. Поки "досвідчені інженери" сміються над їхнім сетапом.

Натрапив на пост про DBOS і трохи підвис: durable workflows прямо на Postgres, без Temporal, без окремого кластера, без команди, що його доглядає. Зачепило не новизною, а дежавю, бо це ж було вже в мене. Років з двадцять тому в дотнет завезли штуку під назвою Windows Workflow Foundation, рушій для довгих процесів з паузами між кроками. Це був розрив шаблону: візуальний редактор, малюєш квадратики і стрілочки, зʼєднуєш мишкою, і ось твій процес, наче й коду писати не треба. На демо це виглядало дуже круто і ми вирішили його спробувати. Але магія швидко закінчувалась. Весь цей красивий граф зберігався у лютому згенерованому XML, і щойно воркфлоу ставало кілька, а в них треба було щось додати чи відрефакторити, то виявилось, шо треба то все вручну проклікувати. Бо поміняти це в тексті було нереально, а ШІ агентів тоді ще не було. Тоді я вперше задумався, що треба працювати з кодом і текстом, бо його легко версіонувати і опрацьовувати наявними інструментами. І ці думки були не лише в мене: індустрія розвивалась в сторону винесення таких довготривалих процесів в код. Тепер в нас є Celery, Temporal, Airflow, Step Functions тощо. З ними приємно працювати, все в коді — чого ще треба? Проте в більшості випадків можна обійтись простішим рішенням, і може навіть шось напиляти самим на колінці. В тому ж самому проекті, шо я згадував вище, в нас був workflow процесор, що працював з SQL Server. Все зберігалось в табличках, транзакції, блокування та інші знайомі штуки дозволяли закрити наші потреби. В іншому проекті аби зменшити цінник AWS ми реалізували процеси на базі dynamodb і лямбд, зекономивши на step functions. Вийшло ефективне рішення, яке ще й було цікаво реалізувати і ним було зручно користуватись. Але наступного разу коли треба буде durable workflows, я мабуть спробую DBOS. Під капотом там та сама табличка зі станом, чекпойнт кожного кроку і SELECT ... FOR UPDATE SKIP LOCKED щоб воркери розбирали чергу не наступаючи один одному на ноги, тільки вже як готова бібліотека. Гарний компроміс між легкістю і необхідністю кастомної розробки. Бо своє пилити то звісно прикольно, проте не завжди ефективно. Єдиний недолік, шо я бачу — це не Redis :) А ви на чому крутите свої довгі процеси, на готових продуктах чи на самопалі?

Півроку назад ми сміялись над людьми, які втрачали гроші та дані через Clawbot, а зараз його додають у Windows, щоб керувати
Півроку назад ми сміялись над людьми, які втрачали гроші та дані через Clawbot, а зараз його додають у Windows, щоб керувати вашим ентерпрайзом

В твітері прочитав історію про програміста з 50х років на імʼя Мел. Його можна було б назвати бумером тих часів. Він не довіряв прогресу і визнавав лише машинний код, це коли все записано у шістнадцятиричних числах. Асемблер, компілятор чи не приведи боже Fortran — воно все от лукавого, адже хто його знає, який код воно нагенерить. Той твіт написаний у відповідь на інший, де обговорюється питання, наскільки треба довіряти коду, шо пише AI. Навіть не так, обговорюється теза, що код, написаний AI, варто сприймати як результат компіляції. А ми здебільшого не дивимось на результат компіляції програми, правда ж? І вдогонку те питання, яке я вже піднімав на каналі. Чи треба робити ревью коду, що генерить агент? Я в цілому вважаю, що класичне ревью коду це рудимент, який уповільнює розробку, і не буду тут повторювати всю аргументацію. Але з агентом фокус трохи інший. Він не людина, тож інтуїтивно здається, що десь має стояти human gate, жива людина, яка гляне у код і скаже окей. Уявіть себе архітектором, який спланував систему, описав вимоги, нарізав епіків і віддав це все в розробку. Чи має він ревьювити кожен коміт? Якщо так, то він швидко стане ботлнеком. Натомість краще мати процес, який забезпечує, щоб код працював правильно. В цьому процесі можуть бути тести, CICD, лінтери і навіть код ревью, яке робить не сам архітектор, а ліди чи інші розробники, і тому воно нормально скейлиться. Цілком реально отримати працюючу систему без того, аби архітектор хоч раз глянув у код. З агентами розробник опиняється сам в ролі архітектора. Human gate, без якого нам некомфортно, це той самий архітектор, що ревьює кожен коміт. Чим автономніший агент, тим краще він скейлиться, і тим менше сенсу садити людину перевіряти кожен його крок. Якість забезпечується тими самими механізмами, що і для людей, включно з ревью результату іншим агентом. Агент сам підніме тестове середовище, прожене які завгодно тести, виконає які завгодно перевірки. Чесно кажучи, доволі важко уявити, що такого унікального зробить тут людина, чого не зробить агент. А щодо якості коду, мовляв, AI пише поганий код — ну камон. Наче люди пишуть ідеальний код. Зі свого досвіду можу доволі авторитетно сказати, що код від AI стабільно кращий за те, що видає середньостатистичний кнопкодав. Агента реально навчити працювати з великими кодовими базами, структурувати рішення, дотримуватись патернів, KISS та інших YAGNI. Все це описується в інструкціях, до них додається механізм оцінки, і далі воно котиться само. Мел так і не навчився довіряти компілятору, хоча той давно переграв його і в швидкості, і в надійності. Перечитуючи кожен рядок коду від агента, ми ризикуємо опинитись у ролі Мела: вручну перевіряти те, що інструмент уже робить надійніше за нас. Воно звісно круто і викликає захоплення, але до продуктивності є питання. То ви все ще Мел, чи вже ні?