tgindex
У Льоні сьогодні

У Льоні сьогодні

Статистика

🪓🧩💡 Нотатки архітектора систем та майстра на всі руки. Що я зробив, що з того вийшло, і що це все значить. Сторінка автора: https://leonid.shevtsov.me Компанія, де він працює: https://railsware.com

Последний пост
14 авг.
Последнее чтение
13 авг.
Постов за неделю
5
Всего постов
87
Тип
открытый
Язык
украинский
Категория
Технологии (по похожим)
В каталоге с
13 авг.
Подписчики
549
−1 за 1 дн.
Сутки
0
0,00%
Неделя
 
Месяц
 
Просмотров на пост
503
40 постов
Вовлечённость
91,6%
к подписчикам
Постов в день
0,7
всего 87
Упоминаний
1
каналов
Охват размещения
оценка
1/24сутки в ленте
261
1/48двое суток
299
1/72трое суток
322

Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.

Посты

  • видео или голосовое, без подписи

  • видео или голосовое, без подписи

  • _id в OpenSearch - не так ефективно, як можна подумати В продовження теми того, що розуміння однієї бази даних не завжди переноситься на іншу. В #OpenSearch (чи ElasticSearch, бо одно й те саме) в кожного документа є ідентифікатор - _id. Наче зрозуміле явище, за ним ми швидко знаходимо та змінюємо документи. Так саме як в PostgreSQL, наприклад. Але. Якщо вам раптом захочеться відсортувати за _id, то виявиться, що прямої можливості це зробити в OpenSearch немає. Словник того не підтримує. Та тому для виконання запиту з "sort": "_id" база завантажить всі ID в памʼять. Цей маневр називається field data. З мільйонами документів в індексі ця fielddata займатиме гігабайт RAM, а то й більше — саме так я про неї й дізнався. Та дуже дивно було, що саме _id, з усіх полів, спричиняє такі витрати. Що робити натомість? Можна дублювати _id всередині документу. Можна сортувати за якимсь іншим полем. Зокрема, якщо задачею сортування є стабільність видачі (бо навіщо ще сортувати за ID?) - то в пошуку є спеціальне поле _shard_doc як раз для такої потреби. Власне, в останніх версіях OpenSearch навіть є налаштування indices.id_field_data.enabled: false - воно примусово заборонить створення fielddata з _id. Тож то й таке. 👑 Patreon ︙ ☕ BuyMeACoffee

  • Вірний вибір каналу для сповіщень Уявимо собі що ми робимо сповіщення про вибіг терміну TLS сертифікату. (А знаєте, краще не уявляти, а таке сповіщення мати точно — якщо так сталося що сертифікат не оновлюється автоматично.) Ми розробники, звикли працювати з кодом та кидати помилки в Sentry. Тож робимо цикл-монітор, який перевіряє стан сертифіката та, якщо він наближається терміну, надсилаємо відповідну помилку. Перші рази все працює. Минають місяці... як от прокидаємося вночі від тривоги на брак сертифіката. Йой, не подивилися вчасно в #Sentry. А річ у тім, що Sentry це взагалі не місце для тривожних сповіщень! Так, певні помилки ми там побачимо. Але зазвичай в Sentry дивляться вже тоді, коли іншим чином виявили проблему — хтось поскаржився, наприклад. Тому як ти не фразуй сповіщення, а ставлення до нього буде недостатньо відповідальним. Добре, тоді може направити повідомлення в канал #Slack? Це краще для помітності, навіть надто гарно. Бо монітор, щоб бути помітним, почне бомбити канал постійно. Він же ж не знає, що ми побачили. А нам взагалі-то треба побачити одне сповіщення, відреагувати та зробити сертифікат — на що піде не один день. Ну таке. (Робити власну складнішу систему, звісно, теж не хочеться.) Можна зайти з іншого боку — дата вибігу сертифіката відома. Тож можна створити тікет в Jira з терміном. Це просто, але покладається на те, що хтось буде відповідальним та побачить той тікет. Що — для задачі, яка відбувається раз на три місяці та потребує неухильного виконання — мені не подобається. Потрібний механізм, що буде смикати за руку, і робити це надійно. На цих думках я згадую про PagerDuty. Оце воно! А щоб сповіщення зʼявилося там, сервіс надсилає в #CloudWatch метрику "залишок терміну дії сертифіката". І як тільки я бачу задачу у вигляді метрики, картинка складається. Бо тоді є чітка історія стану. Є вбудована у Cloudwatch обробка випадку "монітор зламався та нічого не надсилає". Є готовий механізм сповіщень, та впевненість, що хтось побачить та підтвердить попередження. А головне, що це лягає в систему інших критичних сповіщень, тобто стає зрозумілим для команди. (Нарешті, маленька порада про #PagerDuty: в нас в описі кожної тривоги є посилання на посібник по її виправленню. Чудово допомагає, коли тривога будить тебе о третій ранку.) 👑 Patreon ︙ ☕ BuyMeACoffee

  • 9 авг.334142

    Як я робив плейлист на гулянку разом з Claude 💃🪩🕺 Стала задача зібрати девʼятигодинний плейлист для суботньої гулянки невеликою компанією бачатерос. В мене такий досвід вперше, тож ніякого заготованого матеріалу не було. Збирати 160 пісень вручну — та навіщо, якщо є Claude? По структурі. Ну можна, звісно, накидати просто 160 пісень, зробити shuffle і закінчити. Втім. День не є однорідним. Музика має відповідати потребам. Ми перевірили погоду та розбили на такі стадії: збір-розігрів; передобідній блок танців; сієста; післяобідній блок танців; та блок танців під заграву. Погода підманула та замість спеки півдня був мінливий дощ — тож частково ця підготовка була хибною. Але загалом допомогло те, що в мене були різні частини. Наприклад, на розігрів йшли не дуже відомі треки, а в танцювальний блок — хіти. Тут зробив відкриття. Танцювати лише хіти виснажує, бо хочеться навалити кожну пісню. Пʼять хітів поспіль — і вже втомився. Треба перемежати чимсь простішим-скромнішим. Вечірній блок починався не з бачати, а з Tití Me Preguntó. Клод підказав, що це розкачає настрій люду, і так воно і було! Також в мене були сумніви про меренгу Suavemente, проте вона стала одним з яскравих моментів запальних танців. 🌇 Окремою задачею в мене стояло підготувати плейлист на захід сонця. Щоб там були гарні романтичні треки та було красиво. Клод нафантазував, що можна привʼязати плейлист по часу... але ж точний час заходу в певному місці неможливо передбачити, ми ж не в чистому полі. Тож зійшлися на тому, що просто був момент, куди перейти, як сонце почне заходити. (На жаль, погода не сприяла зовсім, тож дослухали романтичні треки в машині.) По наповненню. Звісно, перелічив улюблені треки — свої та інших учасників. Та улюблених виконавців. Решту змісту Клод успішно заповнив різною музикою, багато такої що я й не знав. О, я йому нагадав, що є ремікси українських пісень — та й не тільки українських — які можна знайти тільки на YouTube. Також Клод чудово фільтрує по чорному списку виконавців. Тут найбільше буде допомоги в наступний раз, бо вже не доведеться будувати все з нуля. Взагалі стає очевидним, що необхідно мати базу музики. (Мабуть, будь-який ді-джей це підтвердить.) Наприкінці помітив, що Клод не має уявлення про пісню поза її назвою і загальних відомостей. Він не знає тривалість пісень, наприклад. (І при тому Клод думав, що точно підгадає пісні під час заходу. Ага!) (Заради справедливості зазначу, що загалом тривалість плейлиста статистично зійшлася.) Тому планую зробити навичку чи навіть MCP для впровадження пісні як сутності — з URL, тривалістю, темпом тощо. Може, як раз в контексті бази пісень. Бо ще гірше — плейлист лише з назв важко надійно перенести в будь-який музичний майданчик. (А я обрав YouTube, щоб точно можна було передати список іншій людині — і це знадобилося!) Є сервіси, втім, з непопулярною музикою вони дають багато хибних результатів — помиляється з виконавцем тощо. Розвʼязав задачу інженерно. Спочатку попросив той же ж Клод згенерувати скрипт, який за допомогою yt-dlp дав по пʼять результатів пошуку по назві з YouTube та — головне — зробив сторінку HTML, на якій було легко передивитися по кожній пісні варіанти та обрати підхожий. Так я за розумний час переклав свої назви у справжні ID треків з YouTube. Але... список ID треків це ще не плейлист! І засобів закачати такий список на YouTube я не знайшов. Отже — згенерував іще один скрипт, який бере список та через YouTube Data API пхає його мені в акаунт. Довелося кілька хвилин провозитися з налаштуваннями Google Dev Console, бо куди без неї — і успіх. Нарешті — грати музику зі свого телефону це дуже незручно. Якщо вже готуватися серйозно, то взяти ще один телефон, налаштувати суто під відтворення музики, та використовувати його. Або... зробити хмарну платформу і бота... але до цих фантазій ми ще доберемось! 👑 Patreon ︙ ☕ BuyMeACoffee

  • 8 авг.315182

    Ключовий фактор в роботі з LLM: уява #ПомічникШІ 🎂📢🛫 Та в мене черговий збіг! Рівно чотири роки тому я почав цей канал, і сьогодні відновлюю щоденні пости. Досвід проситься назовні! Спостерігаючи, як люди навколо використовують LLM, мені здається, що загалом це використання достатньо прозаїчне. Згенерувати текст — чи код. Або ж зробити конспект тексту — чи коду. Звісно, все, що LLM вміє — це генерувати текст. Але текстом може бути що завгодно. Не код, а план реалізації.Чи план всього проєкту? Рецензія на код? Історія змін? Журнали? Метрики? Чати з менеджером? Чати з самою LLM? Команди для адміністративних операцій? Наприклад. Сидимо ми на відеодзвінку з Данилом, аж як помічаю, що дзвінок гальмує, бо CPU зашкалює. Починаю дивитися, що до чого - Activity Monitor, htop тощо. І тут Данило пропонує — а доручи це агенту. Доручив! Агент виконав кілька команд та відразу запримітив, що справа навіть не в CPU, а в RAM. Недостача памʼяті призвела до жорсткого використання свопу. До того ж він відразу запропонував, які застосунки варто зупинити — та навіть міг сам це й зробити, не виходячи з чату. Тобто достатньо було уявити, що LLM допоможе — і це відкрило нові можливості. Ну або помітити, можна й так сказати. Інший приклад. Шукаємо причину активної помилки в продакшні. Ситуація горить. Можна шукати логи та скидати потроху LLMці. Або питати її, де в коді є релевантні місця. Але можна прямо сказати: в мене така-то ситуація, нумо розв'язувати. Та вона дуже компетентно почне це робити! Особливо якщо ти навісиш достатньо корисних MCP - можливо, згенерованих під власні потреби. Це теж потребує уяви. Отже. На сьогодні закликаю дивитися на власні задачі ширше та сміливіше віддавати LLMці. Звісно, з надійними запобіжниками, про що я ще напишу. 👑 Patreon ︙ ☕ BuyMeACoffee

  • Channel name was changed to «У Льоні сьогодні»

  • Заміна пісні на відео на чистий трек Дружина поділилася відео, де вона чудово танцює. Але: гучніше музики було чутно як хтось розмовляє. От би залишити тільки музику... Виглядає як задача для інженера! - Визначив пісню. Для того в Mac вбудований Shazam, відкриваєш Control Center -> Recognize Music, запускаєш відео, готово. Так, це працює не тільки з тим що десь грає ззовні, а й з компʼютерним аудіо — дуже корисно. - Завантажив MP3. Тут в нас є, хто не знає, yt-dlp. Просто золотий інструмент. - Знайшов приблизно позицію. Легше за все це було зробити за текстом. Підслухав, що там співають у відео. А далі в Apple Music відкрив відтворення з текстом, клацнув на потрібний рядок та отримав таймкод. - І, нарешті, залучив агента, щоб він мені зібрав все до купи. Ну не хочу я памʼятати ключі ffmpeg - та, на щастя, вже не знадобиться. За кілька спроб підібрали точний зсув — та й готово! Справа вийшла хвилин на 10. ...Звісно, тепер залишилося питання: чи не може агент зробити все це зовсім автоматично? Виявилося, може! Зрозуміло, що з Shazam та yt-dlp в агента проблем ніяких. Хоча в першу спробу агент завантажував лише демку треку — довелося уточнити, що нам потрібна саме вся пісня. Залишався рівно один складний (як на мене) етап: визначити зсув. Але тут виявилося, що в агента більше знань, ніж в мене. Він і вокал ізолював, і аналіз хроми зробив. І здогадався звіряти тільки ті частини відео, де нема гучної розмови (а саме, ті, де Shazam давав збіги.) Щоправда, агент трішечки розгубився, бо відео починалося десь з середини пісні — не повірив. Поперевіряв ще та сам переконався. З першої спроби той же ж результат, якого я досягнув вручну. Власне, от вам навичка, якщо цікаво принаймні ознайомитися. PS: потужна практика роботи з агентами: після того, як той виконає певну складну задачу, попроси створити навичку. Це закарбує набутий підхід та зробить наступну спробу значно прямолінійніше. PPS: чи я почав публікувати навички? Так! 👑 Patreon ︙ ☕ BuyMeACoffee

  • GTD: розібратися з поточними справами, а не набрати нових Ось хиба, яку я в себе знайшов. Я не раз писав про наслідки, але нарешті вдалося вхопити першопричину. Отже: в систему #GTD (та й в будь-який інший самоменеджмент) можна запхати дві категорії задач. Дійсні та бажані. Дійсні — це ті, які в тебе є без усякого самоменеджменту. Та ти їх зробиш так чи інакше, бо вони ну дійсно потрібні. Я зараз не про рутину — то інше. А про неординарні життєві справи, які все одно робиш. Будь-яка людина замінить бойлер, підготує звіт, забронює готель для майбутньої подорожі без схем обробки вхідних та інших ритуалів. Та бажані задачі — їх ми хочемо, але не робимо... на що класично кажемо "бо часу не вистачає". Та я не про шалені мрії (переїхати жити у гори та відкрити там ресторан), а про близькі справи. Може це те, чим ти збираєшся зайнятися, як тільки "буде час" (у відпустці, разом з десятьма іншими планами). Чи певні обовʼязки, які трохи почекають (поки півник не підкрадеться та не клюне — тоді задача переходить в категорію гарячих та "дійсних".) Моя хиба в тому, що я дивився на GTD як на засіб досягнути саме бажаних задач. А не тільки дійсних. Власне, дійсні "і так робляться", тому я не завжди звертав на них достатньо уваги. Головна проблема з цим така, що бажані задачі — категорія не обмежена. Тож список проєктів розростається. Зʼявляється потреба розрізняти більш та менш важливі. Бо часу на все не вистачить, тож як впоратися? Та чому ж в GTD не те що не заклали пріоритети, а відверто від них відмовилися? Для мене тут важливо було зрозуміти, що мій список проєктів мусить бути розміром з мене. Та в нього йдуть тільки дійсні задачі. Тоді їх не фізично буде більше, ніж я можу зробити. Якщо ставитися чесно, звісно. Тоді й чистити список простіше: не торкнувся задачі за тиждень — то й не така вона й потрібна, значить. То й пріоритетів з таким списком не потрібно — належність до нього вже найвищий пріоритет. Тобто на GTD краще дивитися як на засіб робити дійсні задачі з меншим стресом, без відкладань та зайвого обмірковування. А потім, в міру того як зросте продуктивність, додавати щось бажане, яке зʼявиться, бо я вже маю на це змогу, а не лише бажання. 👑 Patreon ︙ ☕ BuyMeACoffee

  • Аудіо у фоні це ще складніше Отже, на минулому пості мої пригоди з базовими потребами застосунку не закінчилися. Помітив, що у фоні застосунок грає музику недовго, та зупиняється. А складно не помітити — бо я відразу почав використовувати його для власних тренувань. В застосунку є можливість зациклити певну частину пісні, що мені дуже спрощує життя. Тож вмикаю пісню, вмикаю камеру та практикую... от тільки недовго. Отже, промучився трохи, та почав спостерігати. Заміряв, що застосунок виживає у фоні рівно одну хвилину. Це завело мене на стежку хибних гіпотез, які починалися із "є певний період, який iOS дозволяє тримати застосунок у фоні". Вирішив, що то мій застосунок недостатньо зрозуміло пояснює iOS, що він є програвачем музики та потребує тривалого існування у фоні. Нацькував на цю тему Cursor, він вже і так, і сяк пробує — а результат однаковий — 60 секунд і кінець. (До речі: що LLM вміє робити дійсно потужно — так це читати та навіть змінювати код залежностей. Я сам майже ніколи так не робив, бо було складно та ризиковано. А LLM ставить patch-package та успішно патчить навіть код на Swift.) Прориву ми досягли, коли нарешті здогадалися додати вичерпне журналювання. Причому відразу! З першої же ж спроби. (Тут теж LLM здатна прорватися туди, де я не знаюся: пояснила, де читати журнали застосунку з iPhone та власне потім сама ці журнали й проаналізувала.) І що знайшли? Та досить очевидну в ретроспективі річ. Застосунок споживав надто багато CPU. Виявляється, в iOS є правило: якщо застосунок у фоні споживає понад 80% CPU, його зупиняють. (А 60 секунд - це вікно оцінювання.) Мій застосунок безтурботно ганяв анімацію React Native Animation - яка й керувала відтворенням аудіо. Зокрема, в режимі зациклювання я додав fade in/out - от він і був головною причиною. Поки що вистачило зупиняти анімацію та трохи збільшити інтервал зміни гучності. Але також дізнався, що є готові API для автоматичного fade in/out - це було б ідеально. Загалом бачу що в майбутньому треба весь рушій аудіо переписати на нативний, щоб React Native туди не лазив аж зовсім. Втім, для MVP піде й так. Яка тут мораль: та класична. Спочатку зрозумій, у чому проблема, та доведи це, а потім вже починай виправляти. Це залишається правдою з LLM чи без. 👑 Patreon ︙ ☕ BuyMeACoffee

  • 9 июн.530153

    Аудіо — дуже складно, насправді Сьогодні пост не про LLM! Я теж радий. Я тут роблю застосунок для розбору пісень для танців. Кілька місяців тому зробив онлайн варіант, але зараз переробляю у вигляді мобільного застосунку. Традиційно, 80% зусиль пішло на аспект, який здавався мені тривіальною базою, яка сама по собі нікому й не потрібна. Отже, в серці застосунку лежить те, що інтерфейс рухається в такт пісні. Насамперед рахує удари — як метроном. Для того ми визначаємо BPM - удари на хвилину, привʼязуємо перший удар, і потім в момент часу T нескладна математика каже нам, що грає удар N вісімки M, ну з цим проблем ніяких. Але виявилося несподівано складно відтворити це в інтерфейсі. Здавалося б, будь-який програвач таке вміє. Не зовсім. Біт на екрані розповзався від звуків пісні. Я довгий час думав, що то в мене нема хисту визначити BPM та оскільки помітити десинхронізацію треба на око (та вухо), це було дуже важко підтвердити. Але без нормальної привʼязки до аудіо решту функцій можна було не будувати. Першим чином я думав, що гальмує React Native? (Ну бо це те, з чим знайомий.) Трішечки такого ефекту було, але насправді біт в пісні це близько 500 мс, та ніякий RN настільки не гальмує. Звісно, оптимізувати було що, бо екран пісні, як бачите, жирний та весь його перемальовувати не гарно. Тут нічого особливого. Друге — затримка аудіовиходу. Така затримка є, особливо якщо програвати через Bluetooth вона сягає 200 мс та більше... Але то теж навіть не один удар. Втім, дізнався, що принаймні в iOS є вбудована можливість дізнатися тривалість затримки поточного виходу. (Та звісно — в кожного виходу власна затримка.) Що й потрібно для того, щоб відповідно затримувати оновлення інтерфейсу. На щастя, це одноразове та автоматичне покращення, та хоч я зробив інтерфейс для редагування цієї затримки, базових налаштувань достатньо. Справжні цікавинки почалися, як закопався у формат файлів. Власне, помітив, що на відміну від моєї замученої піддослідної пісні, інша грає та перемотується без жодних проблем. Між піснями знайшлася важлива технічна різниця. Отже: для точної перемотки потрібне кодування з CBR, тобто сталим бітрейтом, (а не VBR - змінним). Оскільки не бачу сенсу вимагати CBR від користувачів, впровадив перекодування в CBR на вході. Зберігав я у формат AAC. (Змінний бітрейт суттєво ефективніше, я памʼятаю ще як перекодовував власну колекцію MP3, щоб більше влізло в плеєр. Суть його в тому, що простіші місця пісні будуть стиснуті більше.) Перехід до CBR відразу зробив перемотку стабільною. Це був очевидний успіх. Але зʼявилася нова дивна річ: певні місця в пісні завжди перемотувалися неправильно. Ну, наприклад, в той час, як перемотуєш на другий удар, грає ще перший. Причому, тільки після певної перемотки! Якщо грати з початку пісні, такого не було. Тут я дізнався ще один нюанс: файл AAC не "проіндексований", це плаский потік даних. Тому, хоч перемотка і працювала стабільно, але не завжди вона була точною. (А мені, на відміну від типового програвача, потрібна ідеально точна перемотка.) Виявилося, що залишається загортати потік AAC в контейнер M4A. M4A як раз додає індекс, метадані тощо. От ніколи не думав про медіакодеки та медіаконтейнери, а довелося. Та, о щастя, пісні в CBR M4A відтворюються так, як треба! База, про яку ніхто й не подумає, закріплена надійно. 👑 Patreon ︙ ☕ BuyMeACoffee

  • Як застосунок виглядає зараз.

  • Не сперечайся з LLM - вчи її #ПомічникШІ Коли людина робить щось не так, як тобі хотілося б, ти просиш її робити інакше, та людина запамʼятає це на наступний раз. (Ну, як правило.) От з LLM надважливо не запозичити цей підхід та не виправляти LLM, бо ти марнуєш час (та гроші) на покращення тільки поточного результату. В LLM антероградна амнезія, та інший раз вона зробить по-старому. (Звісно, це ламає звички, бо ми ж наче спілкуємося з LLM як з колегою в чаті, привіт - будь ласка - дякую, імена їм вигадуємо. Тому і звертаю увагу. Називай молоток як хочеш, тільки не забивай ним шурупи.) Отже. Коли LLM робить щось не так, як тобі хотілося б, найкраще це повернутися до початку та виправити інструкції. Взагалі тут два варіанти є. Або ми погано поставили задачу. Треба прийняти, що це нормальна ситуація, ставити задачі - складно. Так, інколи можна вийти на правильне рішення продовженням діалогу: згенерували сайт - давай тепер задеплоїмо. А в інших випадках ти вже виправляєш помилки: я хотів окрему табличку, а ти додала стовпчик в ту, що існує. Легше зрозуміти на чомусь побутовому. Якщо ти попросиш в LLM джинси та вона пошиє модні продрані, то вже пізно просити її зашити дірки. З кодом все так само - виправлення коду, що існує, залишає артефакти та зайві ускладнення. Це і без LLM завжди було так - звідки знайома мрія "переписати все з нуля". Проте з LLM переписати з нуля легко - принаймні в межах однієї задачі точно. Та, між іншим, це ще й може бути дешевше за виправлення, бо продовження діалогу здорожчує роботу з LLM - ще одна "нелюдська" особливість. Тож, покращуємо початковий запит - чи план - та починаємо наново. Або LLM не знає про наші загальні вподобання. Я хотів логіку в сервісному шарі, а ти написала все в моделях. Чи я завжди роблю стилі з shadcn/ui. Чи процедурні питання: запускай тести після кожної зміни. Чи по стилю: я полюбляю функції до 20 рядків та винесення літералів у константи. Коли до згенерованого коду зʼявляються такі претензії, ще більше варто не виправляти на ходу, а відкрити SKILL.md та написати, як любиш. Мене особисто така зміна рамки відновлює інтерес до роботи. Замість нескінченних виправлень одних та тих самих дрібних негараздів я розробляю комплект навичок. А це вже моя улюблена аналітична задача: помітити, що не так, узагальнити, знайти рішення. Ще й свої вподобання починаєш краще розуміти. 👑 Patreon ︙ ☕ BuyMeACoffee

  • 23 мая642141

    Код має значення — навіть коли його пише LLM #ПомічникШІ Та звісно ж, питання було риторичним. Тільки чому? Не тому же ж, що нам за нього платять, та страшно, що буде, коли LLM здатна видавати тисячі рядків коду на будь-яку примху. (Втім, сподіваюся, тобі насправді платять не за код, а за розуміння. Але про те не сьогодні.) Отже, код. Поки ми працюємо з чистого аркуша та задача "щоб працювало", дійсно, будь-який зміст коду нас влаштовує. Та це потужне місце для використання LLM! Знаєш, багато задач вкладаються саме в одноразову генерацію коду. Від команд та скриптів до цілих утиліт. Я от тільки вчора згенерував з телеграм-каналу інформаційний сайт. За пів години. Код взагалі не бачив. Причому тут два шари згенерованого коду: спочатку скрипти для збору та впорядкування змісту, а потім вже власне сам сайт. Оце для мене чудовий — чарівний навіть — результат LLM. Проте як тільки ми закриємо сеанс LLM, код стає джерелом істини. Ваш найдетальніший план не містить всіх подробиць. Код є остаточною специфікацією всіх подробиць реалізації. Всіх функцій, розгалужень, змінних та констант. Так саме як і люди, LLM читає код, щоб зрозуміти, що ж він робить. Та так саме LLM потрібно, щоб код був зрозумілим. Тільки LLM зовсім не зорієнтовані на генерацію зрозумілого коду. Це за досвідом. Ну тобто я не кажу, що вони завжди пишуть поганий код — навпаки, здебільшого цілком прийнятний. Але задачі писати якісний код в LLM немає. Що можна помітити, коли щось йде не за її планом. Ось тоді починаються зміни характеру "тут підправимо, там посунемо", а зовсім не про помірковані зміни. Бо LLM більше "грає в хорошого розробника", це буквально, що воно робить, бо це ж семантична папуга, розумієте? Вона не знає, як правильно, в неї немає сенсу смаку. Тому у сталих, не одноразових проєктах я завжди читаю код, згенерований LLM. Та зазвичай вношу виправлення. Нудні виправлення, як-от "чому ця умова така довга" та "як ми можемо робити менше повторень" та "не насипай 100 рядків в цей модуль, зроби окремий". Без цього я просто не можу підписувати продукт LLM власним іменем. Я не вірю, в широкому сенсі, що можна обмежити власну увагу планами та специфікаціями та залишити шар коду суто для ШІ. Не виключаю, що певним чином можна переконати LLM писати гарний код, але для цього потрібно принаймні її для того інструктувати. Та якщо у тебе виходить, напиши, будь ласка, i am trapped in an LLM prompt please send help. 👑 Patreon ︙ ☕ BuyMeACoffee

  • 22 мая602203

    Чи має значення код, коли його пише LLM? #ПомічникШІ Знаєте трикутник "дешево, швидко, якісно: обери два"? Я спостерігаю, що із використанням LLM вершина "швидко" роздулася безмежно та затьмила дві інші. Та ні, гірше, бо "дешево" ж теж стало так, як ніколи - які б ті токени не були дорогі, але праця розробника завжди ще дорожча. От і виходить, що ми колективно обрали "дуже дешево" та "дуже швидко"... та пояснили собі, що на "якісно" можна не дивитися. Або, наприклад, що "воно працює" - це показник якості. Пʼять років тому теж траплялося, що "ось зробив за ніч величезну фічу, все працює... в код не дивись". Я знаю людей, які здатні за вихідні переписати проєкт на іншу мову. Та й сам таке робив. Але. Ніхто такі зміни не брав в продукт на віру! Яким би визнаним та досвідченим інженером ти не був, нормальна практика була почитати той код, та якщо він виявився погано структурованим та незрозумілим - попросити доробити, впорядкувати, і таке інше. До речі. Раніше взагалі тільки круті інженери могли видавати код, що працює, з такою швидкістю. Тому, гадаю, раз LLM пише код ну настільки швидко, ми опиняємося під впливом гало-ефекту та високо ставимося до її розуміння теж. Втім, за досвідом, результат більше нагадує зграю мало оплачуваних, зате завзятих кодерів з прямим підключенням до Stack Overflow. (От вам щеплення від гало-ефекту - ставтеся до агента не як до rockstar 100x developer, а як до найманої команди фрілансерів з біржі. Бо воно, бляха, так і є, якщо подумати.) 👑 Patreon ︙ ☕ BuyMeACoffee

  • 9 апр.690194

    LLM для дослідження В моїй роботі найбільше користі від LLM навіть не в написанні коду, а в дослідженні та операціях. Ну тобто код воно генерує — проте тут зміни кількісні, не якісні. Ну швидше генерує, ніж я пишу. Ну можна через це згенерувати більше коду, як всі ми знаємо. Але в цілому, цінність коду відʼємна, та впровадження LLM ніяк це не змінило. Зате із дослідженням... Якщо дати агенту достатньо інструментів - CLI, API, MCP - байдуже — то він настільки вправно збирає дані та аналізує, як я по-людськи ніколи не зможу. Наприклад, я не зможу витягнути з CloudWatch метрики різної роздільної здатності, за різні проміжки, зробити кореляцію та видати табличку. Точно не за розумний час! Я не зможу формулювати запити до OpenSearch, включаючи до адміністративних джерел, так швидко, щоб зводити результати з різних серверів у відповідь до одного запитання. Я не зможу прочитати купу логів та знайти в них визначні місця — особливо коли я ще й не знаю, що саме шукаю, та в яких логах до яких сервісів. (Теж, може й зможу, якщо мені дати день тільки на це, та я не вигорю ментально від такого навантаження.) А потім, все це зібрати до купи, скорелювати, підсвітити важливі місця, ще й зробити звіт відразу. В межах робочого дня. Звісно, агент не розуміє всіх подробиць та нюансів, але на то є я та є діалог. Я направляю дослідження, а агент робить. І так я отримую доступ до стількох джерел інформації, які до LLM й уявити не міг. 👑 Patreon ︙ ☕ BuyMeACoffee

  • 8 апр.6001910

    Приготування їжі наперед 🌮 Я сину щоранку на сніданок роблю кесаділью в паніні-пресі. Та от, нарешті спало на думку, що цей рецепт можна легко робити наперед: заморожувати вже складені кесадільї, щоб залишилося тільки розігріти та підсмажити. Отже, що я дізнався. Коли готуєш страву "пакетом", наперед, то можна вкласти в приготування значно більше нюансів. Щодня я клав сирий перець — тут можна його протушкувати. Додати спецій (дізнався, що сушений часник + копчена паприка це чисто ароматизатор ковбаси!) Можна покласти щось особливе, таке що кожний день возитися не будеш. Звісно, також воно й швидше виходить. Хоча поки готуєш, так не виглядає! Бо замість звичних двох кесаділь доводиться готувати всі десять. Але то лише перше враження. Тепер приготувати сніданок — це дістати кесаділью з морозилки, покласти в холодний прес, увімкнути та... піти займатися власними справами. Вона спочатку повільно розігріється, а потім там же ж і підсмажиться.Отут дуже відчуваю, як багато часу звільнилося. Справжня якісна зміна життя! І зовсім для мене неочевидний приємний бонус: пакетне приготування значить пакетна підготовка та пакетне прибирання. Про ці етапи я мало думав, але ж дивись скільки часу економить: діставати інгредієнти щоранку вже не треба. Працювати руками — не треба. Посуд мити — теж не треба! А до того ще й не стає проблеми, що раптом в четвер якогось з інгредієнтів немає та потрібно щось терміново вигадувати на заміну. Отже... Якщо в тебе є улюблений рецепт приготування наперед — поділись, будь ласка. А якщо ні - раджу теж спробувати. 👑 Patreon ︙ ☕ BuyMeACoffee

  • 7 апр.524143

    15 хвилин про bike shedding В мене, якщо не писати щодня, прокидається бажання писати серйозніше, але не зараз, а коли буде час. (Ніколи.) Тож спробую нову тактику: нехай пост займає не довше 15 хвилин; є що сказати — ділюся. Bike Shedding - це відоме явище в плануванні, при якому певній неважливій частині приділяється неадекватно багато часу. Назва походить від байки, де під час планування електростанції комісія захопилася подробицями гаража для велосипедів. Чи щось таке. Звісно, в програмуванні нас чекає особлива пастка. Часто наперед не зрозуміло, де в нас "електростанція", а де "сарайчик". Або погляди на це розходяться. Одним словом, в програмних проєктах (не)важливість аспекту не так легко побачити. От, проєктуєте ви JSON API. І все з ним зрозуміло. Але. Чи повертати поля результату на верхньому рівні {"foo": "bar"}, а може, загорнути в {"data": {"foo": "bar"}}, чи response, чи entity, чи все ж за назвою сутності {"fooser": {"foo": "bar"}}? На жаль, чіткої відповіді немає. Тому є шанс застрягнути на цьому питанні. (Це гарна ознака "сарайчика" - чим більше варіантів, тим менша важливість.) Кожен поділиться власною думкою. Може, навіть прийде ідея розшукати стандарти. Дослідження зробити... Стандарти різні — є, та їх багато, але дотримуються їх бозна-хто та бозна-як. Якщо ви бачили багато різних API, то там завжди по-своєму. І за моїм досвідом, такий аспект API аж ніяк ні на що не впливає. Тож можна було й не починати весь цей процес, а відразу взяти будь-який підхід та піти далі. А от що дійсно важливо — то дбати про узгодженість в межах власного API. 👑 Patreon ︙ ☕ BuyMeACoffee

  • Як не бути рабом ШІ #ПомічникШІ Коли я починав користуватися Курсором, в оточенні агенту не запускався Ruby. Тому кожний тест чи іншу команду я власноруч запускав в терміналі, а потім копіював в чат. (Ну, ще раніше я ще й команди сам писав та обирав, що саме скопіювати.) Звісно, потім я це полагодив. Проте, оскільки я остерігався дозволити агенту запускати все підряд, то сидів та погоджував кожний rspec. А ще нагадував агентам проганяти rubocop - зазвичай вже після того, як на CI впало. В такому режимі роботи виходить, що агент робить все цікаве, а на мене залишається брудна робота.Причому що більше використовуєш агентів, то це відчуття підсилюється. Проводити дні за запуском тестів — дико вимотує. Щоб такого уникнути, вдався до кількох мір. Ні, я досі не збираюся дозволяти агентам повну свободу. Натомість опановую allowlist. Це перелік команд, які дозволено запускати автоматично, без погодження. Цікаво, що allowlist містить префікси кожної команди, тож можна туди додати комбінації на кшталт bundle exec rspec. В allowlist критично важливо запхати всі команди, які не потребують справжнього рішення з мого боку. От, якщо будемо видаляти базу в продакшні — тут я краще подивлюся. А тести, лінтер, дрібні команди збірки та організації по типу git - усі роблю дозволеними. (До речі, саме Ruby в мене не працює в sandbox, бо доступу до зовнішніх файлів. Тож це не вихід) Як виявилося, в Cursor цей allowlist сидить в базі SQLite, тож його не так легко відредагувати напряму. А хотілося саме напряму, тому навайбкодив скрипт, який переганяє allowlist з простого текстового переліку в налаштування. Та друга важлива міра — доповнювати скіли інструкціями про те, що повинно відбуватися завжди. Так я навчив Cursor проганяти й rspec, і rubocop для кожної зміни. Дехто хапає готові кілометрові скіли — мені вистачає прицільно описувати те, що потрібно саме мені. І останнє тепер — увімкнути сповіщення від Cursor. Може, в когось завжди увімкнені всі сповіщення — а я до нових джерел відношуся максимально скептично та майже нічого не вмикаю.Втім тут той виняток, коли сповіщення спрощують життя — так саме, як і з довгим запуском тестів. Тепер я можу залишати Cursor на довгі проміжки часу та отримувати вагомі результати. (Звісно, це після фази планування — про яку теж можна окремо.) 👑 Patreon ︙ ☕ BuyMeACoffee

  • ШІ-вигоряння #ПомічникШІ Як почав використовувати агентів постійно, то в певний момент опинився в неприємному стані. Наче і працював весь тиждень, наче було продуктивно, але обʼєктивного просування по задачах не бачив. Зʼясував, що перша причина в розпиленні зусиль. Широко відомий факт, що повільна збірка змусить інженерів відвертатися та втрачати контекст тут множиться на інший — агент дозволяє почати щось нове з мінімумом зусиль. Виходить, поки агент для однієї задачі думає, я можу почати іншу... Ну навіть не робити, а планувати чи досліджувати. А потім — третю... А як не в одному проєкті — то в кількох... Таким чином швидко приходить стан, де я вже не памʼятаю, чим займався. Бо увага розсіяна! Та замість впевненого прогресу однієї задачі отримую трішки змін там, відкритий ПР тут, незавершений план ще десь — та головне, що потім навіть зібрати до купи всі початі задачі стає складно, не те що довести до кінця. Отже, що я придумав з цим робити. Чітко визначати для себе задачі, над якими сьогодні працюю, та доводити їх до кінця, перш ніж починати нові. Якщо доводиться чекати на агента — краще я в цей час перевірю повідомлення, зроблю кави чи розімнуся. Це веде до наступного пункту. Критично важливо дозволити агенту достатньо операцій, щоб він міг завершувати вагому частину роботи без втручання. Ну як мінімум — це запускати тести! Але про це я ще окремо напишу. 👑 Patreon ︙ ☕ BuyMeACoffee

У Льоні сьогодні — tgindex