Агенти — смертельний ворог, чи зручний інструмент?
Вітаю, спільното. Мене звати Олександр. І я — розробник ПЗ. Принаймні я таким себе вважаю. Основний стек — .NET, але я люблю вивчати інші технології і через це страждаю.
Насправді, спочатку я хотів такий заголовок: «Агенти — страх хайп і ненависть в Лас-Вегасі розробці ПЗ». Але цей інтерфейс не дозволяє перекреслювати букви в заголовку. Не дуже люблю хайп (може, трошки прибрехую), але якщо він вже виник, глупо ним не скористатися.
Преамбула
Інколи люди кажуть, що в ШІ-агентів завжди занадто короткий контекст. Після кількох тижнів активної роботи з GitHub Copilot (саме з промптами) мене особисто ця думка смішить. Бо я завжди згадую, наскільки зазвичай короткий контекст у людей. В мене особисто контекст НАБАГАТО коротший, ніж у Claude Sonnet 4.6. А це ж навіть далеко не найпотужніший агент, розроблений для вирішення «середніх» задач.
Мотивація
Тут я спробую пояснити (і собі теж), нахіба я почав робити проєкт, про який тут пишу. Є такий старий анекдот: «Насправді, всі люди — євреї, просто не всі мають сміливість це визнати». Я згадав його зранку, і мене вдарила молнія: насправді будь-яке життя — це стартап, просто не всі однаково вміють знаходити спонсорів, генерувати класні ідеї, заводити стосунки з найкращими професіоналами у власному оточенні і перетворювати власне хобі на спосіб заробітку. Але час від часу виникають обставини, і треба навчитися бачити в них не лише загрози, а й можливості.
Агенти лякають і мене також. Бо вони геть розумні (хоча дехто досі «не вірить»), але найстрашніше те, що вже є володарі бізнесів, які повірили, що агенти вже зовсім скоро нас замінять. І це ускладнює життя, пошук роботи та погіршує психологічний стан. I лякає, лякає, лякає... З мого досвіду, найкращий засіб від страху — експеримент. Коли ти розумієш, як воно працює, вже не так лячно. Попереджений — озброєний.
Тому в певний момент в мене виникла ідея зробити псевдостартап. Тобто, написати просту, але повнофункціональну веб-апку, щоб перевірити деякі забобони. Наприклад — «Агенти не здатні писати якісний, читабельний код. Код, написаний агентами, працює суттєво повільніше і гірше, ніж написаний досвідченим розробником. Апку, написану агентом, складно супроводжувати і змінювати у майбутньому.» Чому я вважаю ці твердження забобонами? Ну, я курс прослухав, і там дядька (Tom Phillips) дуже послідовно і зрозуміло пояснює, як за допомогою агентів створити повноцінний додаток. Але там технології зовсім не мої. Я той код не дуже розумію (або мені психологічно некомфортно його читати), тому щось більш-менш складне я поревʼювати навряд чи зміг би. Тому я вирішив взяти не мої основні, а «близькі» технології. Те, що вже вивчав і з чим вже працював, принаймні «понарошку». Головна ціль проєкту — зʼясувати, чи можливо виключно за допомогою агентів (тобто не написавши жодного рядка коду руками) розробити повноцінну трьохрівневу аплікацію середнього рівня складності і підтримувати її. І друге — чи дійсно це економить час та сили і дозволяє швидше вчитися, чи є «особливості» роботи агентів, які забирають більше часу, ніж економлять. А якщо є, наскільки складно їх обійти і чи воно того варте?
Імплементація
Початок
Спочатку був документ. А ні. Ніфіга, звісно, не було, просто в якийсь момент я зацікавився, чи можна і саме як використовувати для розробки моделі з відкритою вагою (open-weight models) і встановив собі Ollama, та ще й веб-інтерфейс до неї. Це окрема історія, про яку я, можливо, якось напишу, але пізніше і не точно. Але оскільки просто базікати з моделями нудно, я спробував використати одну з версій Gemma, яку встановив в Ollama, щоб розробити план власного стартапу. Стартап не вийшов, бо Gemma була застаріла, а звʼязку з інтернетом той сетап, що я використовував, не мав, тож я розробив план псевдостартапу. Я його потім багато разів змінював за допомогою Claude Sonnet 4.6, але якщо кому цікаво, оригінальну версію можна знайти в першому коміті.
Для тих, кому ліньки, або некомфортно читати англійською, TL;DR: це — аплікація, яка дозволяє зареєструватися/залогінитися через зовнішнього security provider (поки що реалізований тільки Google), а потім створювати скорочені варіанти довгих посилань, які передресують вас на довгу адресу. Як Bitly, тільки на мінімалках.
Технології
TL;DR: PostgreSQL, Golang, Vue.js
Я обрав PostgreSQL, тому що ШІ сказав, що він одночасно круто масштабується за потреби (про це я і сам знав) і його можна налаштувати так, щоб він не їв більше 2 ГБ оперативної памʼяті, що для псевдостартапу з нульовим бюджетом є вирішальною характеристикою. Я обрав Golang для бека, тому що, по-перше, він легкий і компілюється під будь-яку OS, а крім того, я його дещо знаю і можу ревʼювати код. Я обрав Vue.js для фронтенду, тому що його я теж трошечки знаю і він також доволі легкий. Всі бібліотеки я ретельно обговорив з ШІ (спочатку це була Gemma, а потім Claude Sonnet) і потім декілька разів дещо змінював, намагаючись підлаштуватися під вимоги до аплікації, які я сам собі придумав.
Підхід до розробки
Вся розробка ведеться англійською мовою, бо її краще розуміють агенти і взагалі міжнародне комʼюніті. Інші мови до аплікації завжди можна додати пізніше, якщо виникне необхідність. Перший етап розробки — створення першого файлу інструкцій для агентів. Саме такий формат обраний тому, що його добре розуміє не лише GitHub Copilot, а ще й силенна купа інших інструментів. В мене платна підписка на GitHub Copilot, яка коштує $100 за рік, але там геть обмежена кількість токенів на місяць, тому варто завжди мати можливість перемкнутися на щось інше. Першу версію цього файлу, я, здається, зробив, попросивши агента перетворити мій план розробки на вимоги до стилю кодування. А потім неодноразово змінював.
Далі робиться агент для розробки інструкцій для агентів (цю інформацію я з курсу взяв). За допомогою цього агента робляться додаткові інструкції, специфічні для application tiers та/або певної функціональності. Інструкції треба ревʼювати особливо ретельно, бо баги і неоднозначності в інструкціях призводять до дивної поведінки під час генерації коду. В мене (принаймні поки що) немає чіткого рецепту, як і в який момент краще генерувати інструкції. Я дотримувався такої послідовності: перед тим, як дати агенту промпт згенерити ту чи іншу частину коду, я намагався зрозуміти, чи покрита вже ця частина інструкціями, тобто, чи впевнений я, що під час розробки в агента не виникне жодних моментів, де він вважатиме себе вільним приймати рішення на власний розсуд. Якщо впевненості не було, я починав з планування етапу розробки і інколи з плану ставало очевидно, якої інструкції не вистачає. А інколи я просто бачив, що код написаний не так, як я хочу, тоді я додавав відповідний файл чи розділ, а потім або переробляв етап з початку, або просто давав агенту ще одне завдання — переконатися, що щойно додані вимоги виконуються.
Чому не зберігати всі інструкції в одному файлі? TL;DR: для економії часу і токенів. Інакше кажучи, головний файл інструкцій є невідʼємною частиною кожного промпту. Тож він «жере контекст» у будь-якому випадку. Проте якщо поточний промпт ніяк не стосується, наприклад, аутентикації користувача, то відповідний файл з інструкціями агент читати не буде, і так само з усіма іншими «специфічними» інструкціями. І це дозволить вам зекономити час, а зрештою, напевно, і гроші.
Логування дій агента
В цьому проєкті було б дуже мало сенсу, якби неможливо було відстежити, що саме робив агент у відповідь на той чи інший промпт, яка саме модель використовувалася, який режим та інші деталі. Тому я з самого початку вирішив логувати всі дії агентів, використовуючи хук для логування. Як я його зробив? Ви, напевно, будете сміятися, але я попросив агента його зробити, і той просто зробив. Спочатку він тупо логував все, причому в два формати одночасно: JSON та формат, зручний для читання людиною.
Потім я зрозумів, що в мене час від часу виникає необхідність просто обговорити подальші кроки з агентом (режим Ask у GitHub Copilot), а він всі ці обговорення логує, і мені потім доводиться або обережно прибирати зайве (щоб не втратити власне промпти на розробку), або комітити більше нецікаві обговорення. Тому дав завдання агенту переробити логування таким чином, щоб сесії, де використовується виключно режим Ask, не логувати. А логувати тільки сесії, де є хоча б один запит в режимі Plan або Agent. І коли він це зробив, я не зрозумів, як воно працює від слова «взагалі». Тоді я попросив агента пояснити алгоритм і врешті-решт вирішив зберегти це пояснення у вигляді документу, бо, по-перше, красиво пояснив, а по-друге, якщо мені знадобиться згадати, як працює логування дій агентів, я знаю, куди дивитися.
Коротше, в цьому каталозі ви можете знайти повний лог всього, що ми з агентами робили в цьому проєкті. Там же є посилання на останній коміт кожного логу, тобто нескладно знайти, на що, власне, кожен промпт перетворився у коді.
Вразливості.
Не можна виставляти свою апку голою сракою в інтернет, не зробивши перед цим аудит вразливостей. У великих компаніях для цього є спеціально навчені люди, а інколи навіть спеціально навчені компанії. Оскільки бюджет в мене нульовий, я використовував той самий ШІ. Для цього я зробив окремий промпт, ідею якого так само взяв із курсу. Єдиний недолік: оскільки він працює в режимі Ask, табличку з вразливостями доводиться зберігати руцями, а так працює цілком притомно. Завдяки цьому промпту я пофіксав аж шість вразливостей в коді, які він знайшов. Ну, як, я... Ми з Claude Sonnet. Ідея експерименту була в тому, що все мають робити агенти, то вони все і робили. Я тільки намагався більш-менш зрозуміти, в чому саме полягала кожна вразливість і який воно пропонує фікс. Інколи відповідати на питання агента було доволі непросто, але, здається, я більш-менш впорався. Ще була щонайменш одна вразливість, яку за інших обставин я також пофіксав би, але тут в мене почали закінчуватися токени, і я вирішив перейти до наступного етапу.
Деплой
Оскільки іншого сервера, крім найдешевшого дроплету на DigitalOcean, в мене все одно немає, я вирішив сильно не паритися з деплоєм і попросив ШІ написати мені документ, як це робити руцями, а також підготувати всі необхідні артефакти. Причому я поставив умови, що оскільки в мене вже встановлені PostgreSQL і Caddy Server, я не хочу ніяких Nginx-ів, а хочу використовувати те, що є. І хочу просто копіювати артефакти на сервер через SSH, а не паритися з налаштуванням CI/CD. Також попросив мінімізувати кількість кроків. В принципі, він з усім цим більш-менш впорався, і за підсумком я отримав ось такий документ. Ну, тобто, не зовсім такий: спочатку він трошки відрізнявся, але про це — далі.
Спочатку я був налаштований геть серйозно і вирішив перед деплоєм перевірити все на тестовому інстансі, який зробив у multipass. Воно трошки допомогло, але повноцінно протестити все не вийшло, оскільки Caddy, як зʼясувалося, може підняти SSL тільки якщо піднімати все на реальному домені. Тож, за великим рахунком, вдалося зʼясувати лише те, що все скопіювалося і піднялося, а як воно працює — ні.
Врешті-решт, довелося (як завжди) дебажити все і розбиратися на живому проді. Проте світлий бік історії в тому, що я сам майже нічого не робив, лише давав агенту інформацію і виконував його вказівки. А ні, ще підчищав за ним, коли він змінював файли, які я його змінювати не просив. Коли користуєшся агентом при роботі з живим енвом, треба чітко слідкувати, якому моді працює агент. Здебільшого він має бути в моді Ask, і лише коли зʼявилося чітке розуміння, що саме треба виправити і як саме, треба перейти у мод Agent, виправити і одразу повернутися в Ask. Це мій головний висновок з деплоя з агентом. Під час його зʼясувалося, що callback path для аутентикації однаковий у фронта і бека. При розробці це ніяк не заважало, бо локально вони піднімаються на різних портах, а правити це довелося під час деплоя на прод, але ми з агентом впоралися. Довелося трошечки підправити код і трошечки документ.
Коротше, ось посилання на працюючу апку. Логінитися поки що можна тільки в Google. Чи буду я доробляти інші два провайдери — я поки що не впевнений. Але, здається, що принаймні редирект працює непогано, принаймні для одного юзера. І дизайн, як на мене, агенти зробили притомним.
Пост-амбула (чи як там воно правильно?)
Навіщо воно вам?
Який зиск ви можете отримати від цього допису? Якщо ви — вже досвідчений користувач ШІ і все знаєте про інструкції, агентів, промпти і таке інше на власному досвіді, мабуть, ніякого. Або, можливо, ви знайдете у моєму підході щось для себе цікаве або корисне. Якщо ви поки що мало користувалися ШІ і раніше не використовували інструкції для агентів, ви можете:
— Використовувати мої інструкції або робити свої, кращі за прикладом моїх. Агенти дуже добре аналізують та змінюють документи, принаймні якщо є хист дотепно і точно пояснити агенту, чого саме ти від нього хочеш.
— Використовувати мої промпти. Хоча б у якості прикладів.
— Проаналізувати мій підхід і взяти його на озброєння або випрацювати на його основі свій, ще кращий.
— Облаяти мене в коментарях і довести мені із залізобетонною аргументацією, що проєкт занадто маленький у порівнянні з реальними проєктами, ШІ працює «добре» лише у тепличних умовах, а я — шарлатан і займаюся саморекламою. До речі, де-в-чому ви будете праві. Я дійсно трошки займаюся саморекламою.
Навіщо воно мені?
Як ви вже зрозуміли, я не отримував за цю роботу ніяких грошей. І, напевно, не отримаю, бо конкурувати з Bitly — така собі ідея. Проте я теж можу з цього щось отримати.
— Якщо вам ДІЙСНО сподобався цей текст та/або ви чомусь навчилися чи в вас виникли під час читання якісь важливі думки, ідеї тощо, будь ласка, поставте вподобайку (зірочку) цьому репозиторію. Звісно, я робив це, в першу чергу, для себе, але якщо вам стало у нагоді, чому не віддячити?
— Якщо ви знаєте Golang і вам кинулися у очі якісь недоліки в нашому з агентами коді, ви можете написати про це в коментарях. Я обіцяю подумати над тим, як це можна виправити, не торкаючись коду руками, і чи варто взагалі виправляти.
— Те саме стосується тих, хто знає Vue.js.
— Якщо ви не знаєте ані Go, ані Vue, але все одно бачите недоліки в апці, пишіть в коментарях (якщо не ліньки, звісно). Можливо, я побачу або зрозумію щось цікаве або корисне.
— Якщо ви хотіли б працювати в комерційному або опенсорсному проєкті, де використовується такий підхід, напишіть про це. І обовʼязково напишіть, чому. Якщо не хотіли б — те саме. Мені цікаво.
— Якщо ви знаєте кращий підхід для роботи з агентами, тим більше напишіть. Мені цікаво.
Мої висновки
Підхід з використанням файлів-інструкцій дозволяє доволі щільно контролювати агентів і отримувати від них цілком притомний код, як з точки зору якості, так і з точки зору продуктивності. Такий підхід зʼїдає дещо більше токенів, але за рахунок цього можна отримати більше контрольованості, принаймні на невеликому чи середньому проєкті. Вони також можуть наштовхнути на ідею, допомогти прийняти рішення. Агент не побудує за вас готову архітектуру, але може суттєво допомогти навіть з цим. І головне — вони все це можуть доволі притомно змінювати та покращувати. Головне — щільно за ними наглядати і не давати робити відвертої дурні. Агенти вже зараз виглядають як цілком корисний інструмент розробки, а враховуючи те, що вони дуже швидко покращуються, а ми, хоч і дуже повільно, але все ж вчимося ними користуватися, світ розробки ПЗ вже ніколи не буде таким, яким він був пару років тому. Амен.
Ваші висновки
Пишіть в коментарях. Дякую, що прочитали.
Найкращі коментарі пропустити