Skip to content

З чого складається

Agentfy.ai 2.0 постачається як чотири речі, які можна задеплоїти. Це вся система — немає runner і немає окремого runtime-застосунку, бо ефемерний агент і є api.

ЧастинаПростими словамиРоль
apiМозок + центр керуванняCore і ефемерний мозок агента — одна кодова база/образ. Містить усі 8 шарів слайсів, включно з мозком (agent/orchestrator) і плейном керування воркерами (група слайсів runtime). «Рантайм» = образ api, запущений ефемерно.
appСайт клієнтаКабінет клієнта (Nuxt).
adminПанель керуванняАдмін-панель (Nuxt).
workerРукиПісочниця на вимогу, що виконує зобов’язання агента (bash, файли, браузер, важкі/довгі задачі), які мозок не може сам. Stateful на задачу; гасне при простої.

Три з них (api, app, admin) — звичайні постійно працюючі вебсервіси. worker — виняток: він з’являється лише коли є задача, потім завершується.

Кабінет на свіжому обліковому записі: вбудований агент-консьєрж, готовий налаштувати першого агента

У свіжому обліковому записі рівно один агент — вбудований Консьєрж, якого створює продукт, а не людина. Це єдиний агент без власних Soul, Heartbeat, секретів, навичок, сайту, MCP та підключень: його робота — налаштувати решту.

Список агентів команди в кабінеті

Чому немає окремого «runner»

«Ефемерний рантайм», який усі собі уявляють, — це просто образ api, запущений на вимогу. Запуск тієї ж кодової бази на один хід дає нам мозок — тому ми не тримаємо другий runner-образ із власним циклом агента. workerєдиний справді окремий виконуваний файл, бо йому потрібен інший, важкий образ: справжня ОС із bash + Chromium.

Межа api ↔ worker

Це найважливіша лінія:

  • api = мозок + менеджер. Цикл LLM, оркестрація та прямі (без інструментів) відповіді, плюс плейн, що керує воркерами (група слайсів runtime: черга, життєвий цикл сесії, k8s, події), і збереження виводів через system/file.
  • worker = руки. Контейнер із bash / файлами / Chromium (Playwright). Stateful на задачу (жива сесія браузера, робоча директорія). Не тримає довгоживучих секретів — отримує короткоживучий session-токен від api (user/auth), що спливає разом із сесією.

Одне ім'я в однієї речі

«Пісочниця» і «воркер» раніше називали одне й те саме в різних половинах коду. Більше ні: усюди worker — каталог, образ, перепустка, ці сторінки, слайси й об'єкти, які видно в kubectl. Два імені в одного поняття — це те, через що читач перестає розуміти, одна перед ним річ чи дві.

Слово ділять два слайси, і це навмисно, а не недороблено: runtime/worker — половина, яка піднімає й гасить воркери, а agent/worker — половина, яка вирішує, що ходу потрібні руки. На дроті слова «пісочниця» не було ніколи, тому контракт від усього цього не змінився.

Відкинуте ім'я одного разу повернулося — за три тижні, у коді тих, хто цю врізку не читав. Тому тепер це справа гейта, а не домовленості: make naming відхиляє його будь-де в дереві, в імені файлу так само, як у реченні, а scripts/naming-check.mjs — реєстр відкинутих імен і єдине місце, де відкинуте написання ще виписане повністю.

Конфігурація, яка відмовляє, а не розходиться

  • В адреси API рівно одне джерело. app і admin читають її з nuxt'івського runtimeConfig.public.apiBase, який наповнює NUXT_PUBLIC_API_BASE (за замовчуванням http://localhost:3333). Більше її не задає ніхто: import.meta.env не доїжджає до браузерного бандла, тому покладене туди значення читається як undefined, і мовчки виграє захардкоджена запасна адреса — причому лише на тих машинах, де адреса відрізняється від дефолтної.
  • api не підніметься на плейсхолдерному секреті. Поза development JWT_SECRET, який не заданий, усе ще дорівнює закоміченому плейсхолдеру або коротший за 32 символи, зупиняє старт і називає, що саме не так. Плейсхолдер, з яким застосунок піднімається, — це плейсхолдер, який поїде в прод, а знання JWT_SECRET дає токен за будь-якого користувача.

Один транспорт у браузері, і що на ньому їде

app і admin розмовляють з api через один клієнт, побудований на штатному fetch. Другого шляху немає: згенерований SDK, стріми і завантаження-вивантаження пакета йдуть однаково, тому продовження сесії та обробка помилок діють на кожен запит, а не на половину. Коли транспортів було два, петлю refresh лагодили на перехопленій половині, а на стрімах її не було зовсім.

На цьому єдиному клієнті їдуть три поведінки, і кожна стоїть там тому, що її відсутність одного разу обійшлася у вимірювану ціну:

  • Один повтор на запит, а не ланцюжок. Невиправний 401 раніше давав сотні пар запитів, доки не втручався рейт-лімітер.
  • Одне продовження на пачку. Кілька паралельних 401 продовжують сесію рівно один раз, і латчем слугує сама сесія, а не прапорець у модулі.
  • Повтор іде зі свіжим токеном, а термінальна відмова чистить сесію і веде на /loginз причиною: людина, викинута на екран входу без пояснення, вирішує, що продукт зламано.

Далі