У спільноті AI‑інженерів ім’я Майкла Арнальді добре відоме завдяки бібліотеці Effect для TypeScript та експериментам із кодовими агентами. В одному з недавніх воркшопів на каналі AI Engineer він демонструє радикально практичний підхід: почати з абсолютно порожнього репозиторію й разом із LLM крок за кроком зібрати робочий Effect‑додаток, тестову інфраструктуру та середовище, в якому модель змушена писати коректний, типобезпечний код.

Цей матеріал зосереджується саме на стартовому етапі: як із чистого репозиторію побудувати суворо типізований Effect v4‑проєкт на Bun, налаштувати тестування й діагностику TypeScript так, щоб кодові агенти не могли «протягнути» жодного попередження, а також чому врешті відбувається перехід на нативний компілятор TypeScript Go (tsgo) та LSP.
Порожній репозиторій як принцип: чому «нічого не підготовлено» — це фіча
Воркшоп починається з демонстративно порожнього стану. Немає шаблону, стартового коду чи заздалегідь налаштованого tsconfig. Є лише порожня директорія, у якій ініціалізується новий Git‑репозиторій.
Такий підхід не просто створює «ефект шоу» — він показує, як на практиці виглядає реалістичний сценарій для кодового агента. У реальних командах часто немає ідеально підготовлених boilerplate‑проєктів під кожну задачу. Натомість є:
- чистий або майже чистий репозиторій;
- вимоги до стеку (Effect, TypeScript, Bun);
- очікування щодо якості (тести, типобезпека, відсутність попереджень).
Саме в такому середовищі й має працювати LLM‑агент, якщо його планують використовувати не як іграшку, а як інструмент розробки.
Арнальді підкреслює, що вже щонайменше шість–вісім місяців не пише код «руками» — ні в TypeScript, ні в Rust. Усе робить через моделі. При цьому він працює переважно на бібліотечному рівні, з низькорівневими абстракціями та складною типосистемою. Це важливий контекст: якщо агент здатен впоратися з таким рівнем складності, то питання вже не в «магії» LLM, а в тому, як саме налаштоване середовище, в якому вона працює.
Порожній репозиторій у цьому сенсі — це лабораторія. У ній видно, які саме кроки потрібні, щоб перетворити «чисту папку» на надійний майданчик для спільної роботи людини й моделі.
Bun, Vitest і Effect v4 beta: вибір рантайму та бібліотек
Перший технічний крок — вибір рантайму й тестового фреймворку. У воркшопі як основу беруть Bun. Це означає, що:
- рантайм, пакетний менеджер і тестовий раннер зосереджені в одному інструменті;
- тести запускаються через
bun test; - додаткові скрипти типу
bun run type-checkінтегруються в єдину командну поверхню.
Для тестування використовується Vitest, але через обгортку bun test. Така зв’язка дозволяє зберегти знайомий для фронтенд‑та Node‑розробників досвід (синтаксис і підхід Vitest) і водночас скористатися продуктивністю та інтеграцією Bun.
На цьому фундаменті додається головний герой — Effect. Важливий нюанс: використовується Effect v4 beta. Формально ця версія ще не оголошена стабільною для продакшену, однак уже є користувачі, які запускають її в бойових середовищах. Це створює подвійний контекст:
- з одного боку, бібліотека ще в русі, можливі зміни API та поведінки;
- з іншого — вона вже достатньо зріла, щоб її тестували на реальних навантаженнях.
Для кодових агентів це означає, що покладатися на «знання з інтернету» особливо ризиковано: документація може відставати, приклади в мережі — стосуватися попередніх версій, а внутрішні патерни використання — ще не усталені. Саме тому в інших частинах воркшопу Арнальді робить ставку на прямий доступ агентів до вихідного коду Effect, але в стартовому сетапі важливо інше: створити базову структуру проєкту, де Effect v4 beta є повноцінним, типобезпечним учасником.
Після додавання бібліотеки й ініціалізації структури директорій (src, test) виконується базовий «smoke test»: bun run test і bun run type-check. Це не просто перевірка, що все збирається. Це перший контракт із агентом: будь-які наступні зміни мають проходити ці команди без помилок.
Суворі діагностики TypeScript: коли попередження — це теж помилка
Ключовий елемент усього сетапу — конфігурація TypeScript. Вона не обмежується стандартним strict: true. У воркшопі діагностика налаштована так, щоб будь-яке попередження сприймалося як помилка.
Ідея проста, але радикальна: LLM не має права вважати «достатньо хорошим» код, який компілятор позначає як потенційно проблемний. Якщо TypeScript щось підсвічує, агент повинен це виправити.
У типовому людському робочому процесі попередження часто ігнорують: «потім розберемося», «це не критично», «головне, що збирається». Для моделі такий підхід фатальний. Вона не має інтуїції щодо того, які попередження можна тимчасово відкласти, а які призведуть до помилок у рантаймі. Якщо дозволити їй працювати в режимі «warning‑ok», вона швидко навчиться стабільно генерувати «майже правильний» код, який формально проходить збірку, але накопичує технічний борг.
Перетворення всіх діагностик на помилки змінює гру:
- агент змушений повертатися до коду й доводити його до стану, коли компілятор повністю задоволений;
- будь-які «сірі зони» типу
any, неявних перетворень або пропущених гілок уswitchстають блокерами; - з’являється чітка, машинно перевірювана метрика якості: «усі перевірки проходять, отже, код прийнятний».
Це особливо важливо в поєднанні з Effect, який сам по собі сильно спирається на типову систему для моделювання ефектів, помилок і залежностей. Якщо дати агенту можливість «розмити» типи, вся цінність Effect як інструменту безпеки й передбачуваності зникає.
Перехід на tsgo та LSP: чому важливо, як саме перевіряються типи
Ще один технічний, але принциповий крок — перехід на нативний компілятор TypeScript Go (tsgo) та відповідний Language Server Protocol (LSP).
На перший погляд це може виглядати як деталь реалізації: головне, щоб TypeScript перевірявся, а який саме бінарій це робить — другорядне питання. Однак у контексті роботи з кодовими агентами й суворих діагностик вибір інструмента тип‑чекінгу має значення.
Перехід на tsgo дає кілька ефектів.
По‑перше, це продуктивність. Швидший компілятор означає, що агент може частіше запускати перевірки, не «платячи» за це великими затримками. У сценарії, де модель генерує код, запускає type-check, отримує помилки, виправляє й повторює цикл, час зворотного зв’язку критичний. Якщо перевірка триває занадто довго, агенту доводиться рідше її викликати, а отже, він більше покладається на «інтуїцію» замість формальної валідації.
По‑друге, це узгодженість між компілятором і LSP. Коли той самий стек відповідає і за перевірку типів, і за підказки в редакторі, зменшується ризик розбіжностей між тим, що «бачить» агент у середовищі розробки, і тим, що фактично компілюється. Для людини невеликі розбіжності між LSP і компілятором — неприємність, але не катастрофа. Для моделі це може стати джерелом систематичних помилок.
По‑третє, tsgo вписується в загальну логіку «суворого середовища»: інструменти мають бути передбачуваними, швидкими й однозначними. Якщо агенту сказано, що будь-яка діагностика — це помилка, то й сам механізм діагностики повинен бути стабільним.
У підсумку перехід на tsgo і відповідний LSP — це не просто оптимізація, а частина архітектури, яка перетворює кодового агента з «помічника, якому можна пробачити неточності», на учасника пайплайну, що зобов’язаний дотримуватися тих самих стандартів, що й людина.
Архітектура навколо «дурної» машини: чому суворий сетап важливіший за «розум» моделі
У воркшопі багато уваги приділяється тому, як влаштовані самі LLM. Важливий висновок: моделі не вчаться безперервно. Вони проходять етапи попереднього навчання, спеціалізації, пост‑тренування (зокрема з підкріпленням на кодових базах), після чого їхні параметри фіксуються.
Кодові моделі, з якими працює Арнальді, спеціально тренувалися на задачах:
- читати кодові бази;
- вносити зміни;
- оцінюватися за тим, чи компілюється код після змін.
Але після завершення цього процесу вони не накопичують нові знання з користувацьких сесій. Якщо сьогодні пояснити моделі, як саме в конкретному проєкті потрібно використовувати Effect, завтра вона цього не «згадає».
Це означає, що надії на «самонавчання» агента в межах одного репозиторію — ілюзія. Замість цього потрібно будувати архітектуру, яка:
- дає моделі доступ до актуального коду (а не лише до застарілих знань із тренувального датасету);
- обмежує й структурує контекст, щоб не перевантажувати мережу зайвою інформацією;
- примушує модель дотримуватися формальних критеріїв якості (типобезпека, тести).
Суворий TypeScript‑сетап із усіма діагностиками як помилками — один із таких архітектурних елементів. Він компенсує «дурість» машини, яка не пам’ятає минулий досвід, тим, що кожна нова ітерація коду проходить через жорсткий фільтр.
Арнальді прямо говорить про обмеження великих контекстних вікон. Моделі з мільйоном токенів контексту не обов’язково кращі: якщо в один контекст змішати кілька задач, є великий ризик заплутати мережу. У такій ситуації суворий, але вузький цикл «згенерував — перевірив — виправив» виявляється ефективнішим, ніж спроба «згодувати» моделі весь проєкт одразу.
Від порожнього репозиторію до надійного середовища для агентів
Якщо звести воркшоп до кількох ключових кроків, картина виглядає так. Спочатку створюється абсолютно порожній Git‑репозиторій. Далі:
- обирається Bun як рантайм і тестовий раннер;
- налаштовуються базові скрипти для запуску тестів і перевірки типів;
- додається Effect v4 beta як основна бібліотека для роботи з ефектами;
- конфігурація TypeScript ускладнюється до рівня, де будь-яка діагностика вважається помилкою;
- для перевірки типів і підтримки редактора використовується нативний компілятор tsgo та відповідний LSP.
На цьому фундаменті вже можна будувати складніші речі: HTTP‑API, OpenAPI‑документацію, типобезпечних клієнтів, інтеграцію з SQL і, головне, робочий цикл для кодових агентів. Але критично, що все це спирається на початковий вибір: не спрощувати середовище заради «комфорту» моделі, а навпаки — зробити його максимально суворим і формалізованим.
У такій конфігурації LLM перестає бути «чарівною паличкою», яка «якось» пише код, і стає учасником інженерного процесу, підпорядкованого тим самим правилам, що й людські розробники. І саме це, судячи з досвіду Арнальді, дозволяє йому місяцями не писати жодного рядка коду вручну — навіть у складних бібліотечних проєктах на TypeScript і Rust.
Висновок
Побудова Effect‑додатка з порожнього репозиторію — це не просто демонстрація можливостей Bun чи черговий приклад конфігурації TypeScript. Це показовий кейс того, як має виглядати сучасне середовище для роботи кодових агентів.
Суворі діагностики, Effect v4 beta як серце функціонального стеку, Bun як універсальний рантайм і перехід на tsgo для тип‑чекінгу створюють рамки, у яких LLM не може «списати» помилки на недосконалість інструментів. Вона змушена грати за правилами, які задає компілятор і тести.
У світі, де моделі не вчаться від наших сесій і не пам’ятають учорашніх інструкцій, саме така архітектура середовища — а не «розум» самої моделі — стає головним фактором надійності.
Джерело
YouTube: Vibe Engineering Effect Apps — Michael Arnaldi, Effectful


