Serhii Zabolotnii
← Усі статті
AI LLM архітектура агенти делегування schema RAG composition оркестрація

Коли одного агента замало: як Ayona/OpenClaw перейшла від оркестрації до композиції

Schema governance, API-first vs CLI-first субагенти, AutoResearch протокол, design-before-code gates та composable agent franchising. Частина 3.

Є момент у житті кожної AI-системи, коли один агент перестає справлятися. Не тому, що він поганий — а тому, що реальна робота вимагає спеціалізації. Потрібен дослідницький агент, здатний планувати пошук і синтезувати результат. Потрібен генератор артефактів, що працює з файловою системою автономно. Потрібні спеціалізовані агенти для різних доменів знань із різним рівнем доступу. І саме тут виявляється: масштабування агентності — це не «запусти ще один процес». Це зовсім інша проблема.

Ayona/OpenClaw — AI-native система для дослідницьких і операційних задач, яку я розвиваю вже кілька місяців. У попередніх статтях я описував, чому архітектура важливіша за силу моделі і як довіра виникає з pipeline, а не з одного компонента. Але обидві статті описували один контур виконання — одного агента. А тепер потрібно було зробити наступний крок: перейти від оркестрації до композиції.


Від одного агента до багатьох: чому це інша проблема

Коли працює один агент, головне питання — оркестрація: у якому порядку виконувати кроки, що подавати на вхід, як перевіряти вихід. Це складно, але це лінійна складність.

Коли агентів стає більше, виникає governance (керованість системи як цілого). Тобто набір питань, які для одного агента просто не існують:

Ізоляція контексту. Дослідницький агент не повинен бачити restricted дані юридичного кластера. Teaching bot не повинен мати доступу до внутрішніх operational notes. Якщо ізоляція не задана архітектурно, вона не виникне сама. Це урок, який ми вже засвоїли: у другій статті scoped access з’явився саме тому, що teaching bot випадково отримав research-дані, бо ніхто не налаштував фільтрацію.

Вибір моделі. Для одного агента model routing — це таблиця: цей тип задач → ця модель. Для кількох агентів з’являється додатковий вимір: тип субагента визначає не лише модель, а й патерн виконання. Автономний artifact generator і reasoning-агент із checkpoints вимагають принципово різних підходів до оркестрації.

Довіра до завершення. Delegation v1.1 навчив нас, що порожній output — не success. Але коли субагентів кілька і вони працюють асинхронно, перевірка завершення стає системною задачею, а не разовою перевіркою.

Enforcement scope. Хто вирішує, до чого має доступ новий агент? Хто визначає, які дії дозволені? Якщо відповідь «той, хто написав prompt» — це не governance, це надія.

Наївне рішення — «просто запусти subprocess із промптом» — ігнорує всі ці питання. Воно працює для демо, але ламається в production. Тому нам потрібен був фреймворк, а не скрипт.

І першим кроком до цього фреймворку стала не нова feature, а дисципліна.


Schema як governance: ontology SSoT

Попередні статті описували knowledge graph як структуру рішень. Але одне питання залишалось відкритим: хто визначає, що є валідним у цій структурі? Перш ніж будувати субагентний фреймворк чи AutoResearch, треба було відповісти саме на це — інакше кожен новий компонент додавав би ентропію замість порядку.

Відповідь: config/ontology.yaml як Single Source of Truth.

До формалізації онтології граф жив у режимі “кожен пише як вважає за потрібне”. Типи нод, кластери, зв’язки, теги — все це існувало в Python-коді, у frontmatter документів, у скриптах генерації. Нічого не перевірялось системно. Результат? Коли ми запустили graph audit на 176 нодах, він знайшов 75 схемних помилок і 367 попереджень. 20 варіацій кластерів замість 10 канонічних. 21 тип зв’язків замість 10. 349 унікальних тегів без жодної таксономії. 50% нод без summary.

Початковий health score: 0%.

Це ілюструє важливий закон: без enforcement schema — декорація. Можна мати найкрасивішу онтологію у світі, але якщо вона не валідується при створенні і не перевіряється при commit, вона деградує непомітно.

Тепер ontology.yaml визначає:

  • 9 типів нод із алійасами для legacy імен (knowledge, insight, task, project, direction, process, decision, person, longterm)
  • 10 кластерів з ієрархією до 3 рівнів (ayona_ops → system_integration, clients → agentic_streamline, healthprecision, research, teaching, supreme_court, archive, ndi_zsu)
  • 10 типів зв’язків (IMPLEMENTS, EXTENDS, BUILDS_ON, PART_OF, DEPENDS_ON, COMPLEMENTS, VALIDATES, SUPERSEDES, CONTRADICTS, RELATED_TO)
  • Рівні чутливості (public, internal, restricted)
  • Agent scopes — маппінг доступу per agent

Усі скрипти — graph generation, frontmatter validation, graph-writer skill, audit — автоматично завантажують онтологію через ontology_loader.py. Це означає, що зміни в одному YAML-файлі каскадуються на весь pipeline. Додати новий тип ноди — це змінити один рядок у ontology.yaml, а не шукати всі місця в коді.

Pre-commit hook у pipeline автоматично перевіряє: чи кожна нода відповідає закритому словнику типів? Чи кожен кластер валідний? Чи немає “творчих” зв’язків, яких не існує в онтології?

Рис. 1. Ontology SSoT: один YAML-файл каскадується на весь pipeline. Без enforcement — 0% health на 176 нодах. Ontology SSoT: один YAML-файл каскадується на весь pipeline. Без enforcement — 0% health на 176 нодах.

Це і є schema as governance (схема як інструмент керованості): структура знань контролюється не конвенціями і не пам’яттю розробника, а автоматичною валідацією. І саме ця дисципліна дала змогу будувати все наступне — субагентний фреймворк, AutoResearch, agent franchising — на стабільному фундаменті, а не на конвенціях, які розпадаються під навантаженням.


Два типи субагентів: API-first і CLI-first

Маючи стабільну схему знань, можна було переходити до наступного питання: як саме організувати виконання задач кількома агентами?

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

Це розмежування виросло з практики, а не з теорії. Ми помітили, що задачі субагентів природно розпадаються на два класи, які вимагають принципово різних механізмів контролю.

API-first субагент потрібен тоді, коли main agent повинен бути присутній між кроками: приймати рішення, валідувати проміжний результат, направляти наступний крок. Це reasoning-intensive задачі з checkpoints і quality gates. Субагент генерує не фінальний артефакт, а набір промптів і даних, які main agent виконує через LLM-виклики. Контроль залишається у оркестратора.

CLI-first субагент потрібен, коли задача bounded і автономна: згенерувати презентацію, провести code review, виконати deployment check. Субагент запускається як самостійний процес із власним skill directory, працює до завершення, повертає результат. Main agent не втручається в проміжні кроки — лише отримує outcome.

Швидкий тест для маршрутизації простий: чи потрібен main agent між кроками субагента, щоб прийняти рішення або валідувати? Якщо так — API-first. Якщо ні — CLI-first.

Головний антипатерн — гібрид. Ми це з’ясували на практиці, коли спробували дати CLI-агенту для генерації презентацій проміжний checkpoint: нехай main agent перевірить outline перед тим, як agent згенерує слайди. Звучало розумно. На ділі — CLI-процес не мав механізму “зупинитися і почекати рішення зверху”, тому ми почали нашаровувати ad-hoc signaling через файлову систему, потім polling loop, потім timeout handling. За два дні прототип став крихким Rube Goldberg machine, який ламався на кожному edge case. Правильна відповідь виявилась простою: це два різних субагенти. CLI-agent генерує presentation за готовим brief. Якщо brief потрібно спершу перевірити — це окремий API-first крок перед ним.

На практиці це рішення заощаджує величезну кількість часу на debugging. Коли тип визначений заздалегідь, архітектура виконання однозначна. Немає «а може, тут додати ще один крок ззовні» або «а давайте дамо CLI-агенту state між кроками». Чистота патерну — це не педантизм, а захист від зростаючої складності.

Рис. 2. API-first vs CLI-first: ключова різниця — де знаходиться main agent: між кроками (ліворуч) чи лише на вході й виході (праворуч). API-first vs CLI-first: ключова різниця — де знаходиться main agent: між кроками (ліворуч) чи лише на вході й виході (праворуч).


AutoResearch як модель API-first субагента

AutoResearch — перший повний API-first субагент у системі, і його дизайн став шаблоном для всіх наступних.

Два інтелектуальних джерела визначили архітектуру. Andrej Karpathy запропонував ідею autoresearch як universal skill — автоматизованого дослідницького loop. Одна з реалізацій цієї концепції (репозиторій balukosuri/Andrej-Karpathy-s-Autoresearch-As-a-Universal-Skill) дала нам не код для копіювання, а research-grade специфікацію: 5-фазна структура, binary evaluation, sacred validation set, mutation operators. Рінат Абдулін розвинув підхід Schema-Guided Reasoning (SGR) — reasoning через наперед визначену структурну схему замість вільного промпту — який ми вже використовували в LLM StructCore (CL4Health) і знали з production (sgr-agent-core від vamplabAI).

Що змінилось при адаптації під наш стек? Karpathy’s loop — це prompt optimization для одного агента. Нам потрібен був multi-step research pipeline для мульти-агентного середовища, де main agent контролює кожен крок. SGR у чистому вигляді — це reasoning framework. Нам потрібен був structured output pipeline з quality gates перед записом у knowledge graph. Тому ми взяли loop discipline від Karpathy і schema-guided structure від Абдуліна, але перебудували їх навколо іншого принципу: субагент не приймає фінальних рішень, а генерує дані й промпти для оркестратора.

Протокол складається з трьох кроків.

Крок 1 — Plan. Main agent передає дослідницький запит. Субагент повертає не результат, а PlanRequest: system prompt і user prompt для LLM-виклику, який має створити структурований дослідницький план. Main agent виконує цей виклик і отримує JSON із brief і search plan.

Крок 2 — Gather. Main agent передає JSON від першого кроку. Субагент парсить план, запускає збір даних із п’яти провайдерів — keyword search по knowledge graph, BM25 full-text, web search через Tavily API, vector search через E5 embeddings, Notion databases — і повертає GatherResult: промпти для synthesis LLM-виклику, статистику джерел і checkpoint.

Крок 3 — Finalize. Main agent передає JSON-синтез. Субагент валідує, оцінює якість, генерує knowledge cards і, якщо якість проходить gate, записує їх у граф.

Ключова деталь: між кроками main agent приймає рішення. Він може зупинити дослідження після першого кроку, якщо план незадовільний. Він може відредагувати brief перед збором. Він бачить статистику джерел і може вирішити, що потрібно більше web-результатів. Він бачить quality score і може відхилити запис у граф.

Саме тому це API-first: субагент не приймає фінальних рішень сам. Він генерує дані й промпти, а рішення залишаються за оркестратором.

Рис. 3. AutoResearch 3-step API: синтез loop discipline Karpathy + SGR Абдуліна. Ромби — decision points оркестратора. AutoResearch 3-step API: субагент генерує дані, рішення приймає оркестратор. Ромби (◆) — quality gates між кроками.

Окрема дисципліна — explicit trigger. AutoResearch не активується на будь-який дослідницький запит. Soft triggers (“дослідж”, “проаналізуй”, “порівняй”) вимагають підтвердження від користувача. Тільки ключове слово autosearch запускає повний flow без додаткового запиту. Це не UX-рішення — це safety-рішення: автономний research-агент із п’ятьма провайдерами не повинен стартувати випадково.


Design-before-code: якісний бар’єр перед реалізацією

Із зростанням кількості компонентів і субагентів з’явилася ще одна проблема: занадто багато нових features починалися з коду замість дизайну. Результат — переробки, неузгодженість з існуючими патернами, пропущені edge cases, які можна було б побачити на етапі проектування.

Відповідь — skill design-architect, який формалізує design-before-code як обов’язкову дисципліну.

Протокол починається з класифікації. Кожна нетривіальна задача маршрутизується на один із чотирьох треків:

TrackКолиАртефакт
ExecPlan>4 години, multi-moduleЖивий PLANS.md з progress tracking
RFCCross-project, інфра, нове APIСтруктурований RFC у 99_process/
RunbookBounded задача для субагентаRunbook з delegation envelope
Brief<2 години, помірна складністьInline brief (не зберігається)

Після класифікації — scaffolding обов’язкових секцій: problem statement, scope (in/out), definition of done, safety/rollback.

Далі — hard gate. Design-артефакт представляється користувачу, і без явного підтвердження (“дій”, “greenlight”, “approved”) реалізація не починається. Агент не може сам себе approve.

Для нових code-компонентів існуючих skills додається ще один шар: contract-first протокол. Спочатку design draft, потім schema (dataclasses, types, API contract), потім eval criteria, і лише тоді — код. Цей порядок не випадковий: він гарантує, що код пишеться під специфікацію, а не навпаки.

Практичний ефект: кількість “серйозних переробок через пропущені вимоги” впала драматично. Не тому, що дизайн магічно вирішує всі проблеми, а тому, що він змушує подумати перед тим, як почати робити.


Composability: template, franchising, remote execution

Найважливіший архітектурний зсув цього етапу — перехід від working system до composable system: системи, компоненти якої можна перекомбіновувати і розгортати незалежно. Три рішення визначають цей перехід.

Public template. Ayona/OpenClaw workspace було sanitized і опубліковано як replicable template. Це не fork і не documentation — це повноцінний workspace зі своїм knowledge graph pipeline (markdown cards → JSON → D3.js), 10 cross-linked knowledge cards, інтерактивним setup script, pre-commit hook із 9-фазною валідацією, параметризованою agent identity і GitHub Actions CI.

Ключовий дизайн-принцип: template має механізм sync із основним репозиторієм. Зміни в архітектурних патернах каскадуються, але knowledge content залишається ізольованим. Це не просто “скопіюй і живи своїм життям”. Це composable building block із гарантією архітектурної відповідності.

Agent franchising. Tag-based graph projection дозволяє проектувати підмножину knowledge graph на ізольований workspace субагента. Bidirectional sync означає, що оновлення у franchised space повертаються в основний граф, проходячи через ontology validation. Agent scopes з ontology.yaml визначають, що саме кожен франчайзований агент може бачити і змінювати.

Це вирішує проблему, яка неминуче виникає при масштабуванні: як дати спеціалізованому агенту доступ лише до його домену, не дублюючи знання і не ламаючи цілісність графу. Конкретний приклад: teaching bot для кластера supreme_court бачить лише ноди з відповідним scope — це десятки карток із сотень у загальному графі. Коли він створює нову картку, вона проходить через ontology validation і з’являється в основному графі вже консистентною. Без franchising цей агент або бачив би все (порушення ізоляції), або працював би на копії, що розходиться за тиждень.

SubagentExecutor bridge до VPS. CLI-first субагентам потрібна інфраструктура для виконання. SubagentExecutor побудував міст між локальною оркестрацією й remote execution: субагент може запускатися не лише як локальний subprocess, а й через SSH на VPS, де працює claude-agent wrapper із OAuth-авторизацією. Main agent формує delegation envelope, executor відправляє його на VPS, Claude Code на віддаленій машині виконує задачу з доступом до skill directories, і результат повертається через system event notification.

Це розв’язує практичну проблему: не всі задачі можна виконувати локально. Генерація артефактів, робота з великими файлами, доступ до production-інфраструктури — все це вимагає remote execution. SubagentExecutor перетворює одну машину на distributed agent runtime без втрати audit trail і completion verification.

Рис. 4. Composition layer: три механізми масштабування, об'єднані спільним governance через ontology SSoT. Composition layer: три механізми масштабування, об’єднані спільним governance через ontology SSoT.


Уроки та failure modes

У перших двох статтях я описував failure modes одного агента: крихка пам’ять, роздутий контекст, брехлива семантика завершення. При масштабуванні на кілька агентів ці проблеми не зникають — вони мутують.

Делегування без envelope: від “спробуй щось зробити” до “N агентів пробують щось зробити одночасно”. У delegation v1.1 ми навчили одного агента не брехати про завершення. Але коли делегувань стає п’ять паралельно, проблема множиться нелінійно: кожне потребує свій scope, свій model routing, свій verification plan. Тепер кожне делегування — обов’язковий envelope: objective, scope (in/out), runbook path, model selection із rationale, context route, expected artifacts, verification, stop points. Субагент повертає completion contract: що зроблено, де артефакти, proof, що не зроблено, ризики ескалації.

Schema без enforcement: деградація, яку ніхто не помітив. Ми мали неформальну онтологію з першого дня — і вірили, що вона працює. Graph audit сказав інше (цифри вище). Тільки коли schema стала machine-enforced (Pydantic validation, pre-commit hooks, ontology_loader у всіх скриптах), вона перестала бути декорацією і стала governance.

Composability без governance: тиражування проблем, а не рішень. Перша спроба “просто скопіювати workspace” для іншого проекту привела до розходження патернів за тиждень. Template sync і ontology validation вирішують це — але тільки разом.

Більше агентів без routing discipline: хаос росте експоненційно. Без розмежування API-first/CLI-first ми отримували субагентів, які “вміли все, але ніщо добре”. Strict routing — не обмеження, а умова якості.

Design-before-code не працює як “рекомендація”. Тільки як hard gate з explicit human approval. Без примусової зупинки перед реалізацією агент (як і людина) завжди знаходить привід “просто швидко написати”. Це завжди коштує дорожче.

Remote execution ≠ “cron + Telegram bot”. Існує спокуса вирішити проблему remote execution простим способом: cron job, що запускає скрипт на VPS, а результат надсилає в Telegram. Це працює для рутини. Але коли субагенту потрібен доступ до skill directories, delegation envelope, OAuth-авторизація і completion verification — простий cron стає ненадійним ланцюжком ad-hoc рішень. SubagentExecutor вирішує це як архітектурний компонент, а не як DevOps hack.


Від “AI що працює” до “AI що тиражується”

Якщо подивитись на траєкторію трьох статей, видно чітку еволюцію.

Перша стаття відповіла на запитання: чому потрібна архітектура? Бо без неї модель, якою б сильною не була, не здатна працювати повторювано.

Друга стаття відповіла на запитання: як виникає довіра? Не з одного компонента, а з pipeline, де кожен шар верифікує попередній.

Ця стаття відповідає на наступне запитання: як масштабувати, не масштабуючи хаос?

Відповідь, на мою думку, зводиться до п’яти принципів:

  1. Type discipline. Визнач патерн виконання (API-first чи CLI-first) до реалізації. Не змішуй.
  2. Schema governance. Якщо структура знань не валідується автоматично, вона деградує. Ontology як SSoT із machine enforcement.
  3. Design-before-code. Hard gate перед реалізацією з explicit human approval. Не рекомендація — примус.
  4. Bounded delegation. Кожне делегування — envelope з objective, scope, routing, artifacts, verification, stop points.
  5. Composition over accumulation. Не “додай ще одну feature”, а “створи building block, який можна використати повторно з гарантіями”.

Зрілість AI-системи вимірюється не кількістю features і не кількістю підключених моделей. Вона вимірюється тим, наскільки надійно можна створити нового спеціалізованого агента, дати йому scope, підключити до knowledge graph, забезпечити делегування з verification — і бути впевненим, що він не зламає те, що вже працює.

Це і є перехід від оркестрації до композиції. Не “один агент, що робить усе”, а архітектура, що дозволяє множити агентів із дисципліною.

І, можливо, саме це є наступною межею зрілості для AI-систем загалом: не те, наскільки потужний один агент, а те, наскільки передбачувано система створює і контролює нових.


Сергій Заболотній — DSc, NLP/LLM Researcher, Professor, AI Systems Architect. Будую Ayona — AI-native систему для дослідження та операцій.