Розширення та система знань
Власний оркестратор: архітектура надійного агентного виконання
Уявіть, що агент має прийняти задачу з Jira, дослідити репозиторій, змінити код, запустити перевірки, передати результат незалежному рецензенту й…
Уявіть, що агент має прийняти задачу з Jira, дослідити репозиторій, змінити код, запустити перевірки, передати результат незалежному рецензенту й підготувати запит на злиття. Якщо все відбувається в одному процесі й безпомилковій мережі, це може бути кілька функцій і викликів моделі. Але що має статися, якщо процес перезапустився після створення запиту на злиття, вимога змінилася посеред роботи або дві копії працівника взяли те саме завдання?
Оркестратор — це система, яка зберігає намір роботи, визначає наступну дозволену дію, призначає її виконавцю й перевіряє результат. У системі з агентами частину рішень можна доручити моделі, але стан, права, ліміти та умови приймання мають залишатися зрозумілими й перевірними. Набір промптів не створює надійності автоматично.
Після цієї глави читач зможе оцінити, чи потрібен власний оркестратор, з яких відповідальностей його скласти, що записувати для відновлення після збою та як не допустити, щоб повтор, застарілий виконавець або невдале узгодження створили побічну дію. Глава спирається на поняття агентного циклу з [глави 72](72-agent-sdks-and-apis.md), контрактів завдання з [глави 46](46-agent-task-contracts.md), паралельної роботи з [глави 42](42-parallelism.md) та спостережуваності з [глави 71](71-agent-observability.md). Вона описує систему керування, а не пропонує будувати чи розгортати конкретний framework.
73.1. Спершу вирішіть, чи варто будувати
Власний оркестратор має сенс, коли є конкретна повторювана потреба, яку наявний продукт або бібліотека не покриває: незвичні інтеграції, процеси тривалістю години чи дні, вимоги до власного зберігання стану, контроль меж дозволів, окремі правила відновлення або потреба поєднати детерміновані бізнес-кроки з модельними рішеннями. Він може бути виправданий, якщо вартість ручного повторення й помилок більша за вартість його розробки та експлуатації.
Початкова альтернатива часто простіша:
| Варіант | Що вже дає | Що лишається відповідальністю команди |
|---|---|---|
| Готовий продукт для розробки з агентом | Інтерфейс роботи, цикл інструментів і відомі правила запуску | Інтеграція з власним процесом, джерело істини й межі дозволів |
| Агентний комплект розробника програмного забезпечення (software development kit, SDK) | Бібліотеку або середовище виконання (runtime) для циклу моделі, інструментів, переходів і подекуди стану | Предметний процес, зовнішні побічні дії, повне відновлення й політики продукту |
| Керований інтерфейс програмування застосунків (application programming interface, API) агента | Хостований цикл агента, сесії та події за конкретним контрактом сервісу | Власні інструменти, дані, зв’язок із продуктом, перевірка результату й обмеження сервісу |
| Детермінована послідовність робіт (workflow) | Наперед визначені кроки, умови, повтори й помилки | Лише ті невизначені рішення, які справді потребують моделі |
| Власний оркестратор | Точний контроль над специфічним процесом і його станом | Проєктування, безпека, сховище, черги, спостереження, чергування й підтримка сумісності |
Стан продуктів змінюється; приклади, перевірені 10 жовтня 2026 року, показують, як розподілено відповідальність між продуктом і застосунком, а не рекомендують конкретного постачальника. Документація OpenAI Agents API описує керований Codex harness зі станом сесії, оркестрацією та відновленням; застосунок усе ще має надати інструменти й обрати середовище виконання. Responses API лишає цикл застосунку його власнику, а Codex SDK запускає harness у його інфраструктурі. Документація Anthropic Managed Agents окремо описує бета-сервіс із подіями та сесіями. Жодна така назва не означає, що постачальник автоматично розуміє ваші критерії приймання, права на бізнес-дію чи канонічний стан зовнішнього завдання. Дивіться не на слово «агент», а на таблицю: що сервіс зберігає, що може відновити, які дії запускає і що залишається вашій програмі.
Повністю розібраний приклад 1: щоденний звіт і десять агентів. Команда щоранку підраховує відкриті запити підтримки за чергою, групує їх за пріоритетом і надсилає один звіт у внутрішній канал. Для цієї роботи пропонують десять агентів: окремого планувальника, п’ять аналітиків, трьох перевіряльників і координатора.
Спершу фіксуємо результат: один звіт до дев’ятої ранку, зіставний підрахунок за однаковими фільтрами, посилання на джерело й повідомлення про недоступність системи підтримки. Запит до API системи підтримки повертає точні записи; кілька звичайних функцій підраховують показники; шаблон формує текст; один крок публікує його. Додатковий модельний виклик може стисло пояснити незвичну зміну, але його текст не змінює кількість записів.
Результат можна спостерігати: один звіт, зафіксований проміжок даних, лічильники й статус доставки. До публікації система зберігає ключ звіту з дати й каналу. Якщо процес упав після надсилання, повтор шукає повідомлення за цим ключем або використовує задокументований ключ ідемпотентності цільового API. Знайшовши один збіг, оркестратор записує посилання на нього й не надсилає дублікат. Якщо цільова система не дає надійно перевірити чи дедуплікувати результат, невизначений стан блокує повтор до узгодження. Десять агентів додали б складність планування, узгодження розбіжних підрахунків, витрат на модель і розслідування збоїв, але не зробили б джерело даних точнішим. Для щоденного звіту детермінований процес має кращу перевірність і менші витрати підтримки. Якщо ж команда щодня отримує різні складні питання, яким потрібна інтерпретація тексту, модель можна додати лише до пояснювального кроку та виміряти користь. Цей вибір не забороняє майбутнє розширення: він відкладає його до появи виміряної потреби.
Власну систему не варто починати з універсального фреймворку «на всі майбутні випадки». Почніть із одного процесу, домовтеся про доказ завершення й опишіть ціну помилки. Якщо готовий агентний продукт не дозволяє потрібної інтеграції або не зберігає потрібний бізнес-стан, тоді визначена прогалина стає аргументом для власного керування.
73.2. Компоненти — це відповідальності, а не мікросервіси
Оркестратор може бути однією програмою з модульними функціями або кількома сервісами. Розділяти його на сервіси варто лише тоді, коли є окрема вимога до масштабування, ізоляції, власника чи життєвого циклу. Важливі межі відповідальності:
| Відповідальність | Запитання, на яке має відповісти | Типовий результат |
|---|---|---|
| Приймач задачі | Хто створив роботу й де її канонічний запис? | Ідентифікатор завдання й початковий контракт |
| Перевірка контракту | Чи повні вимоги, база, область і критерії? | Валідований або заблокований запит із причиною |
| Планувальник | Який дозволений крок готовий і які його залежності? | Наступне завдання для виконання |
| Черга | Як робота чекає виконавця й повертається після збою? | Повідомлення із ключем роботи, а не весь єдиний запис стану |
| Працівник (worker) | Як виконати делегований крок у його межах? | Артефакт, результат інструмента або явна помилка |
| Реєстр інструментів | Які аргументи, ресурси та дії доступні? | Перевірений виклик із визначеним рівнем доступу |
| Рецензент | За якими незалежними критеріями прийняти артефакт? | Висновок із посиланням на докази та відкриті питання |
| Сховище стану | Що є поточним фактом про роботу? | Версія стану, журнал подій, ключі узгодження й посилання |
| Контроль витрат і доступу | Коли зупинитися й чи дозволено цей ефект? | Рішення про межу, ліміт або паузу для людини |
| Спостереження | Як оператор довідається про збій, затримку чи результат? | Події, метрики й сповіщення без зайвого приватного вмісту |
Оркестратор — власник порядку та умов переходів; worker виконує призначену дію. Планувальник може бути детермінованим кодом: він перевіряє, чи є залежності, ліміт і дозвіл, а потім видає роботу. Модель може запропонувати план або пояснити компроміс; її план треба нормалізувати до перевірених кроків, а не напряму перетворювати на право записувати будь-куди.
Для власних агентів потрібно зберігати відмінність між «модель запропонувала інструмент», «інструмент почав виконання», «зовнішня система підтвердила запис» та «оркестратор перевірив бажаний стан». Текст фінальної відповіді не замінює підтвердження від цільової системи. Наприклад, рядок «запит на злиття змін (pull request, PR) відкрито» не доводить, що PR доступний у потрібному репозиторії, має правильну базу або містить очікувану ревізію.
73.3. Контракт задачі задає незмінну рамку
Контракт задачі — версійований запис домовленості про конкретну роботу. Він містить мету, межі, джерела істини, критерії приймання, базову ревізію (наприклад, commit, версію документа або snapshot даних), дозволені дії, власника, строк чи бюджет і очікувані докази результату.
Контракт відрізняється від промпту тим, що ним керує система. Перед запуском валідатор перевіряє обов’язкові поля та межі. Кожен крок зберігає номер версії контракту, з яким працював. Якщо вимогу змінили, створюється наступна версія; оркестратор позначає які виконання застаріли, зупиняє нові записи за старою версією й оцінює вже створені артефакти. Він не перезаписує заднім числом історію завдання.
Ось приклад структури, а не схема конкретного API:
PSEUDOCODE
contract = {
task_id: "review-481",
version: 3,
goal: "Перевірити зміну обробки рахунків",
sources: ["repository@commit-abc", "ticket-481"],
acceptance: ["required checks green", "review evidence attached"],
allowed_actions: ["read repository", "edit isolated branch", "run approved checks"],
forbidden_actions: ["merge", "publish", "change permissions"],
budget: { max_model_calls: 12, deadline: "<task-specific timestamp>" }
}
Схема перевіряє типи й обов’язкові значення; авторизація окремо перевіряє, чи цей користувач і цей запуск можуть прочитати саме цей репозиторій. Контракт — не вічна гарантія: права можуть відкликати, джерело може стати недоступним, а гілка — змінитися. Перед кожною зовнішньою дією повторно перевіряються її ресурс і чинність дозволу.
73.4. Стан має переходити за правилами й доказами
Машина станів — перелік допустимих станів і правил, за якими робота переходить між ними. У наступній таблиці наведено навчальну модель. Реальний процес може бути коротшим або мати додаткові стани, якщо команда визначила, що вони означають.
| Стан | Подія для переходу | Умова | Відповідальний | Доказ переходу |
|---|---|---|---|---|
| created | контракт подано | ідентифікатор унікальний, мінімальні поля присутні | приймач задачі | запис запиту та його джерело |
| planned | план запропоновано | кроки перевірені проти області й лімітів | планувальник; за потреби — модель | версія контракту та список кроків |
| ready | залежності виконані | запланований крок дозволений і має виконавця | планувальник | ключ кроку, аргументи й призначення |
| running | worker взяв оренду | актуальна версія завдання й оренди | диспетчер і worker | власник оренди, номер покоління, початок |
| blocked | бракує залежності або рішення | причина записана, повтор не приховує невідомий стан | оркестратор; людина розв’язує доменне питання | причина, власник і наступна умова відновлення |
| review | артефакт готовий | версія джерела й перевірки зафіксовані | worker передає; рецензент перевіряє | посилання на diff, commit, звіт перевірок |
| accepted | критерії підтверджено | незалежна перевірка відповідає контракту | визначений власник приймання | ідентифікатори доказів і версія контракту |
| failed | межа спроб/помилка завершення | відновлення не відбувається автоматично | оркестратор; оператор розбирає | тип помилки, спроби й причина зупинки |
| cancelled | скасування запиту | нові дії заблоковано; активні роботи перевірено | власник задачі й оркестратор | подія скасування та результат припинення |
Перехід має перевіряти умову атомарно з оновленням версії стану. Наприклад, два workers не повинні одночасно записати «я власник» лише тому, що обидва щойно побачили ready. Стан accepted не означає, що «модель сказала, що готово»: він вимагає визначених доказів. Для коду це можуть бути успішні перевірки на конкретному commit і висновок рецензента; для звіту — вибірка з визначеного періоду та успішна доставка.
Не кожна система мусить зберігати всі перелічені стани як окремі рядки в базі. Важливо, щоб було ясно, чи робота очікує, виконується, зупинена, перевіряється або завершена — і хто може це підтвердити.
73.5. Довговічний стан допомагає відновитися, історія діалогу сама цього не робить
Довговічний стан — запис, який переживає завершення процесу й доступний для продовження. Журнал подій — впорядкований перелік фактів про роботу: контракт створено, крок призначено, дію надіслано, артефакт отримано, перевірку завершено. Контрольна точка (checkpoint) — збережений знімок корисного прогресу, який дає змогу продовжити без повторного обчислення попередніх кроків.
До зовнішнього ефекту збережіть намір: яке завдання, яка цільова система, який ключ ідемпотентності та яка версія контракту. Після відповіді збережіть спостережуваний результат: ідентифікатор створеного об’єкта, уніфікований локатор ресурсу (Uniform Resource Locator, URL), версію або квитанцію від системи. Якщо відповідь загубилася, наявність наміру дає точку для узгодження, але не говорить, чи дія сталася. Тоді стан треба перевірити у власника ресурсу.
Черга не обов’язково є джерелом істини. Наприклад, Amazon Simple Queue Service (SQS) для стандартних черг документує доставку щонайменше один раз: у рідкісному випадку копію повідомлення можуть віддати повторно, тому обробник має бути безпечним для повтору. Visibility timeout — час, упродовж якого отримане повідомлення зазвичай не показується іншим споживачам; він не гарантує відсутності дубля, як окремо пояснює довідник SQS. Отже, запис у черзі каже «спробуй обробити», а не «ця дія сталася рівно один раз». У іншого постачальника або типу черги контракт буде інший — його треба читати окремо.
Ідемпотентність означає, що повторення тієї самої логічної операції з тим самим ключем не створює небажаного додаткового ефекту. Стабільний ключ можна сформувати з ідентифікатора задачі, номера кроку й версії контракту. Він не допоможе, якщо цільова система ігнорує його, строк його дії минув або параметри запиту під ним змінили. Якщо API призначення підтримує ідемпотентні ключі, використовуйте його точну семантику; якщо ні, перевіряйте фактичний стан перед повтором або передавайте невідомий результат на ручне узгодження.
Жоден окремий журнал не робить розподілений процес атомарним від кінця до кінця. Локальний запис і зовнішній мережевий запит не стають однією транзакцією від того, що обидва згадані в коді. Система може доставляти повідомлення щонайменше один раз, а застосунок будувати ідемпотентне споживання. Назва «exactly-once» в сервісному описі потребує читання меж гарантії: де саме вона діє, на який ресурс і в якому часовому вікні.
73.6. Повністю розібраний процес і його часткові відмови
Повністю розібраний приклад 2: завдання від постановки до запиту на злиття змін. Команда просить виправити помилку в одному модулі, зберегти сумісність із чинним API й показати, що регресію перевірено. Автоматизований процес має пройти етапи: задача → дослідження лише для читання → реалізація → перевірки → рецензування → запит на злиття змін (pull request, PR). Кожний перехід має власника, умову, дозвіл і доказ.
| Перехід | Що відбувається | Дозвіл | Доказ для наступного кроку |
|---|---|---|---|
| task → research | Валідатор фіксує контракт, базовий commit і критерії | Читання лише названого репозиторію та пов’язаного завдання | Версія контракту, commit і список критеріїв |
| research → implementation | Worker узагальнює релевантні файли й пропонує обмежений план | Та сама область читання; дозволено запис лише в ізольовану гілку | План, посилання на джерела й перелік файлів |
| implementation → tests | Змінений код збережено як commit або diff | Запис у виділену робочу гілку; команди з білого списку | Commit, назви змінених файлів і стан робочого дерева |
| tests → review | Запущено вимагані перевірки на зафіксованій ревізії | Лише дозволені тести; заборона змінювати тест для приховування збою | Лог із commit-ідентифікатором і кодом завершення |
| review → PR | Незалежна перевірка порівнює diff із контрактом | Створення PR у дозволеному репозиторії; без злиття | Reviewer result, URL PR, head і base revisions |
| PR → accepted | Перевірено існування PR, його актуальні перевірки й незалежне рецензування за контрактом | Права читання; злиття — окрема дія, якщо його не включено в критерій приймання | Посилання, head і base commits, результати перевірок та висновок рецензента |
Кожен рядок — окрема дія, результат якої треба зберегти. Якщо під час тесту змінився commit, попередній звіт більше не підтверджує новий diff. Якщо перевірки пройшли, але перевірка PR ще виконується, стан залишається review або blocked; не називайте це прийманням. Модель може запропонувати текст опису PR, але правило про допустимі гілки й права на створення PR має бути кодом і серверною авторизацією. У цьому прикладі процес завершується одним підтвердженим PR із доказами на тій самій head-ревізії; якщо перевірка або дозвіл відсутні, він лишається заблокованим. Це розділяє етапи тому, що переходи й доступи мають бути відтворюваними умовами, а не висновком моделі. Таблиця описує створення й перевірку PR; злиття потребує окремої умови приймання та власного доказу.
Повністю розібраний приклад 3: процес упав після створення запиту на злиття змін (pull request, PR). Оркестратор записав намір create_pr(task=481, contract_version=3, repo=org/course, owner=org, head_ref=task-481-fix, head_commit_id=abc123…, base_ref=main, base_commit_id=def456…, key=481:3:create-pr) і викликав GitHub API. head_ref — назва гілки, а head_commit_id — очікуваний ідентифікатор commit у цій гілці; це різні значення. GitHub створив PR №72, але процес аварійно завершився до запису URL та успіху в сховищі. Повторний запуск бачить незавершений намір із тим самим ключем. Він не вважає помилку тайм-ауту доказом невиконання: спершу читає PR у цільовому репозиторії, шукаючи за дозволеними ознаками — репозиторієм, гілкою head_ref=task-481-fix, базою base_ref=main і станом (open або closed). Для закритого PR поле merged_at показує час злиття; порожнє значення означає, що PR закрито без злиття. Далі перевіряє, що PR має очікувані ідентифікатори комітів head_commit_id=abc123… і base_commit_id=def456…. Пошук охоплює всі сторінки результатів. Для прикладу гілка унікальна для цієї задачі, а планувальник серіалізує створення PR за її ключем, тож два відновлені workers не мають виконувати запис паралельно.
Якщо знайдено один PR і його гілка, база та ідентифікатори комітів збігаються з наміром, оркестратор записує №72, посилання, ревізії й подію відновлення. Відкритий PR відновлюється як наявний результат; для закритого окремо перевіряється merged_at, і автоматичне створення дубля не виконується. Якщо збігів немає, це ще не доказ, що перший запит точно не спрацював: повтор дозволено лише після того, як оркестратор дочекався завершення попереднього запиту, перевірив актуальне джерело й виконав умови узгодженості, визначені для конкретного GitHub API, з ексклюзивним правом створення для цієї гілки. Якщо API не дає надійно встановити відсутність результату, система зупиняється в blocked замість ризику дубля. Якщо знайдено два можливі PR або head уже інший, оператор отримує обидва посилання для розв’язання неоднозначності. Спостережуваний результат — один підтверджений зв’язок задачі з правильним PR або явний блокер, а не впевнене повідомлення агента. Для зовнішньої системи без ключа й надійного пошуку автоматичний повтор може бути небезпечним; тоді невизначеність має бути розв’язана іншим способом.
Нижче наведений короткий псевдокод. Він показує порядок перевірок, не є справжнім методом GitHub чи конкретною бібліотекою черги. Офіційний API GitHub для списку запитів на злиття фільтрує за головною гілкою у форматі власник:гілка, базовою гілкою та станом; для відновлення перевіряються PR у будь-якому стані, а результат треба дочитати до кінця всіх сторінок. Після пошуку окремо порівнюються ідентифікатори комітів з об’єкта PR. У відповіді GitHub поле sha у head і base містить ідентифікатор відповідного коміту:
PSEUDOCODE
intent = store.get_pending("481:3:create-pr")
if intent:
matches = github.find_prs( # метод дочитує всі сторінки результатів
repo=intent.repo,
head=f"{intent.owner}:{intent.head_ref}", # формат GitHub: власник:гілка
state="all",
base=intent.base_ref,
)
if exactly_one(matches):
pr = matches[0] # стабільна ідентичність: репозиторій і пари head/base ref
if pr.head.sha != intent.head_commit_id or pr.base.sha != intent.base_commit_id:
mark_blocked("PR знайдено, але його ревізії змінилися; перевірити наявний PR", pr)
elif pr.state == "open" and pr.base.ref == intent.base_ref:
store.record_success(intent.key, pr.html_url, pr.head.sha)
elif pr.state == "closed" and pr.merged_at != null:
mark_blocked("PR уже злитий; узгодити завершення, не створювати дублікат", pr)
elif pr.state == "closed":
mark_blocked("PR закритий без злиття; потрібне узгодження", pr)
else:
mark_blocked("стан PR потребує перевірки", pr)
elif none(matches): # лише після успішного пошуку за всіма сторінками
retry_or_escalate_using_target_api_contract(intent)
else:
mark_blocked("неоднозначний зовнішній результат", matches)
73.7. Паралельні працівники потребують власника й перевірки актуальності
Конкурентність — одночасна робота кількох процесів над завданнями, які можуть торкатися спільних даних. Окремий контекст розмови не ізолює файлову систему, базу даних або API. Два workers можуть мати різні промпти й усе одно перезаписати один рядок, створити два PR або використати один ресурс одночасно.
Для кожної одиниці роботи зафіксуйте власника, вхідну версію, область запису та залежності. Оренда (lease) — обмежене в часі право обробляти завдання; після закінчення її можна видати знову. Оренда не вимикає застряглий процес магічно. Старий worker може ожити після паузи й продовжити дію, коли його оренду вже отримав новий. Номер покоління або токен захисту від застарілого власника (fencing token) допомагає цільовому сховищу відхилити запис старого власника, якщо це сховище перевіряє номер перед кожною зміною.
Не всі зовнішні API підтримують fencing token. У такому разі оркестратор має обмежити небезпечні конкурентні записи, використовувати умовні оновлення за ревізією, повторно перевірити актуальний стан і не дозволяти worker-у самому вирішувати, чи його дозвіл ще чинний. Паралельте незалежне читання або роботи в різних файлах, але серіалізуйте кроки, що залежать від спільного ресурсу. Глава 47 розглядає робочі дерева для ізоляції змін у коді; оркестратор також мусить захищати інші спільні ресурси.
Повністю розібраний приклад 4: worker має застарілу версію контракту. Початкова задача версії 3 вимагає змінити лише сторінку звіту; worker прочитав її й створив готовий diff. До початку рецензування власник додає вимогу валідувати нове поле й підвищує контракт до версії 4. Старий worker продовжує виконання, бо його модель ще бачить попередню історію.
Коли він надсилає запит на перехід implementation → tests, оркестратор порівнює contract_version=3 у повідомленні з поточною версією 4. Умова переходу не виконана. Worker не отримує нову оренду для запису, а його завершений diff залишається артефактом зі штампом версії 3. Планувальник визначає, що цей diff змінює лише звітну сторінку й може стати базою повторної роботи; новому worker-у передають чисту версію вимоги, commit diff і список неперевірених критеріїв. Він перевіряє, що старі зміни сумісні з новою вимогою, додає валідацію, після чого тести запускаються на новій ревізії.
Спостережуваний результат — старий результат не губиться, але не може бути прийнятий під новим контрактом. Якщо зміна вимоги лише змінювала назву кнопки й уже готовий diff відповідає їй, повторне виконання може бути непотрібним після контрольованого порівняння критеріїв. Якщо ж вимога стосується доступу до даних або небезпечної дії, потрібна повторна перевірка меж і дозволів. Саме нова версія контракту дає змогу пояснити, чому попередній тестовий звіт більше не достатній.
73.8. Повтор, тайм-аут і скасування — це різні рішення
Повтор запускає ту саму логічну роботу ще раз. Backoff (зростаюча затримка між спробами) знижує тиск на тимчасово несправну залежність; випадкове відхилення затримки допомагає уникнути одночасних повторів багатьох клієнтів. Тайм-аут обмежує час очікування, але не доводить, що зовнішня сторона не виконала дію. Скасування означає заборонити подальшу роботу та визначити, як поводитися з уже відправленими запитами й частково створеними артефактами.
Повторювати можна тільки після класифікації помилки. Повтор читання, яке не змінило стан, зазвичай безпечніший за повтор списання, публікації, запрошення користувача або розгортання. Повтор має мати межу кількості/часу/вартості, враховувати ліміт залежності й визначати наступний крок після вичерпання спроб. Коли зовнішній результат невідомий, перед повтором потрібна звірка. Коли стан неможливо перевірити, безпечне рішення може бути паузою, а не ще одним викликом.
Для довготривалої операції команда може зберігати очікування як стан і прокидатися за таймером чи подією. Якщо використовується хмарна черга, треба знати семантику підтвердження й видимості повідомлення. Якщо використовується оркестратор довговічного виконання, треба знати, що саме він відтворює після рестарту та які callback-и можуть виконатися повторно. Наприклад, SQS явно попереджає, що отримане повідомлення може стати доступним знову після спливу visibility timeout; це характеристика SQS, а не всіх механізмів оренди.
Обмеження моделі за ходами чи токенами саме по собі не є бюджетом усього бізнес-процесу. Оркестратор має рахувати фактичні запити, час worker-ів, використання сервісів, вартість інструментів і час очікування. Він має мати правило завершення: прийнято, безпечно заблоковано, відхилено або скасовано. «Запуск не впав» — не достатня умова успіху.
73.9. Дозволи, інструкції та дані підпорядковані системним межам
Реєстр інструментів — це перелік доступних операцій із визначеними схемами, ресурсами, правами та власниками. Перевірка аргументів відповідає на питання, чи має запит правильну форму. Авторизація відповідає на питання, чи дозволена саме ця дія саме над цим ресурсом. Це різні перевірки.
Оркестратор має застосовувати мінімальні права: дослідження отримує лише читання; реалізація — запис в окреме робоче середовище; відправлення зовнішнього запиту має власний інструмент і власну область; злиття, публікація, видалення чи зміна дозволів не випливають автоматично з делегування. Дозвіл прив’язують до завдання, цілі, версії контракту, обсягу, часу та бюджету. Якщо revision або ресурс змінилися, дію треба перевірити знову.
Текст із issue, документації, браузера чи репозиторію може містити ворожі інструкції. Такий текст є даними для аналізу, а не правилом, яке переписує системну політику. Не передавайте довірені ключі у звичайний prompt і не записуйте їх до журналу. У спостереженнях зберігайте потрібні технічні докази, але не повний приватний текст, якщо він не потрібен для розслідування.
Людське погодження з’являється там, де цього вимагає ризик або власник дії. Для нього система має показати, яку саме дію, над яким ресурсом, за якою ревізією й з яким наслідком очікує. Повну політику схвалень, людські ролі й управління втомою від запитів розглядає наступна [глава 74](74-human-in-the-loop.md). Тут достатньо системної вимоги: оркестратор зберігає хто, коли й що погодив та повторно перевіряє, що дія лишається в погоджених межах.
73.10. Незалежне приймання й інтеграція вимагають доказів
Планувальник, worker і рецензент можуть використовувати мовні моделі, але однакове формулювання «готово» не робить їх незалежними. Рецензування має зіставити результат із критеріями й артефактами. Для зміни коду перевірте commit, diff, журнал тестів, базову гілку PR і результати CI (continuous integration — безперервної інтеграції). Перевірки мають вказувати на ту саму ревізію, яку пропонують прийняти.
Оркестратор має бути влаштований так, щоб worker не міг непомітно змінити власні критерії приймання, вимкнути захист або позначити власний неперевірений результат як прийнятий. Код перевіряє інваріанти й дозволені переходи; reviewer оцінює сутність змін за незалежними вимогами; людина вирішує визначені ризикові або неоднозначні питання. Додатковий reviewer корисний лише коли він має відмінне джерело перевірки чи критерій, а не просто повторює той самий контекст.
Після зовнішньої інтеграції збережіть її точну версію: посилання на PR, head commit, base commit, результати обов’язкових перевірок і стан злиття, якщо його дозволено. Якщо основна гілка просунулася після review або перевірок, з’ясуйте, чи докази все ще стосуються запропонованого diff. Після злиття перечитайте цільову гілку й зафіксуйте фактичний merge commit; перевірте, що саме перевірена зміна потрапила до неї. Якщо влитий commit має іншу ревізію через squash або перебазування, збережіть зв’язок між перевіреним diff і новим commit, а необхідні перевірки запустіть на фактичному результаті. Подія «PR створено» не є «код перевірений», а «перевірка зелена» не є «код злитий».
73.11. Спостереження й оцінювання охоплюють сам оркестратор
Кожна робота має мати кореляційний ключ, версію контракту, версію конфігурації, ідентифікатор запуску, останній підтверджений стан і посилання на артефакти. Оператор має побачити не лише «модель відповіла з помилкою», а й де зупинився процес: черга, інструмент, перевірка чи зовнішній API. Ключі доступу, приватні дані та непотрібне приховане міркування моделі не є корисними полями журналу.
Вимірюйте частку прийнятих задач, помилки за типом, час очікування та виконання, повтори, витрати, ручні зупинки, конфлікти версій і частку результатів, відправлених на переробку; загальні визначення метрик зведено в §71.11 [глави 71](71-agent-observability.md). Вимірювання треба прив’язати до корисного результату: зниження часу до перевіреного PR або частки помилок, а не кількості запущених агентів. Розділяйте якість моделі від надійності інфраструктури, інакше тимчасовий збій черги виглядатиме як погана якість відповіді. Для тимчасово недоступної залежності визначте безпечний запасний шлях (fallback): відкласти крок, повернути результат без необов’язкового збагачення або передати справу людині. Не дозволяйте запасному шляху непомітно послабити критерій приймання. Встановіть стоп-умови для невідомого зовнішнього результату, перевищеного бюджету, нечинного контракту й повторних помилок.
Оцінювання самого оркестратора охоплює інваріанти переходів, повторне повідомлення, втрату відповіді після зовнішнього запису, застарілий контракт, прострочену оренду, недоступність сховища, скасування й перевищення бюджету. Корисні контрольовані сценарії — ті, що відтворюють реальні межі відмов. Перевіряйте, що після збою система не приймає невідомий результат за невиконаний і не виконує повторний зовнішній запис без політики узгодження. Це тести вашого процесора робіт, а не домашня робота для читача.
Для змін оркестратора зберігайте сумісність версій контракту й подій, а версії моделі, SDK та схем інструментів записуйте поруч із запуском. Оновлення спершу перевіряйте на контрольному наборі задач і обмеженому запуску; якщо змінився формат результату чи поведінка, зупиніть поширення й поверніться до відомої версії. Не перемикайте посеред роботи вже створене завдання на новий контракт без зафіксованої перевірки. Якщо код відновлення старого завдання змінився, старі записи можуть тепер означати інший стан. Операторський runbook (покрокова інструкція дій під час штатної операції чи інциденту) має описувати, як знайти stuck task, перевірити зовнішній ресурс, призупинити небезпечні повтори, відновити чергу та зафіксувати ручне рішення. У [главі 63](63-incident-runbooks.md) розглянуто структуру runbook; тут важливо, що workflow-системі потрібен власний, а не лише створений нею продукт.
73.12. Оркестрація, хореографія й розмір кроку
В оркестрованому процесі визначений координатор знає поточний крок і надсилає наступні команди. У хореографованому процесі незалежні учасники реагують на події, не отримуючи кожну команду від одного центрального координатора. У першому випадку простіше побачити повний порядок, але координатор сильніше пов’язаний із компонентами та схемами переходів. У другому — учасники можуть розвиватися окремо, але складніше відновити повну історію й побачити, хто відповідає за завершення.
Це не вибір між «правильною централізацією» й «поганою децентралізацією». Software Architecture: The Hard Parts розглядає переваги, зв’язність, власника стану та обмін між orchestration і choreography для розподілених послідовностей робіт. Для обмеженої послідовності дослідження → код → перевірка → рецензування центральний координатор може дати читабельні стани. Для багатьох незалежних споживачів подій менш тісно з’єднана схема може бути доречною, якщо у кожного визначений власник і є спосіб бачити загальний результат. Вибір залежить від потрібної узгодженості й операційного розуміння.
Розмір кроку теж є компромісом. Якщо крок надто великий, його важко повторити без дублювання роботи, він довго утримує ресурси й створює багато невідомих після збою. Якщо кожна дрібна дія — окрема модельна задача, з’являються зайві переходи, контекстні пакети, черги та витрати. Гранулярність визначається можливістю перевірити результат, потребою відновити його окремо та ціною передачі між межами — не кількістю агентів у діаграмі.
73.13. Складність не зникає від паралельної роботи
Паралельні workers пришвидшують незалежні кроки, але координація має свою ціну: синхронізацію, порядок, розв’язання конфліктів, спільні контракти, повідомлення про збої та перевірку сумісності результатів. Brooks у статті «No Silver Bullet» відрізняє сутнісну складність задачі — ту, що походить від самої проблеми, — від випадкової складності конкретного інструмента чи представлення. Новий runtime може прибрати частину випадкової роботи зі збереження стану, але не вирішить, що означає «рахунок перевірено» або чи є вимога повною.
Ідея Brooks про концептуальну цілісність корисна для оркестратора: правила переходів, значення станів і межі дозволів мають складатися в одну зрозумілу модель, навіть якщо їх реалізують кілька модулів. Десять моделей із суперечливими контрактами не створюють ясність. Team Topologies також виходить із того, що людська організація має керувати потоком цінності, когнітивним навантаженням і відповідальністю за систему; її назви команд не слід перетворювати на обов’язкові класи агентів.
Власник оркестратора має бути визначений незалежно від того, хто створив результат. Він затверджує значення станів, відстежує помилки відновлення, ухвалює рішення щодо версій і знає, хто може зупинити небезпечну дію. Якщо цього власника немає, «автономна» система лише приховує ручне чергування за незрозумілими повідомленнями.
Висновок
Надійний оркестратор не починається з кількості агентів. Він починається з чіткої задачі, версійованого контракту, явного джерела стану та перевірних умов переходу. Система має зберігати намір до зовнішньої дії, звіряти зовнішній факт після неї, обмежувати повтори та блокувати застарілу роботу. Модель може пропонувати план і пояснювати результат; код визначає інваріанти та дозволи; людина відповідає за передбачені рішення з високим наслідком. Починайте з прозорого процесу й додавайте механізм лише там, де спостережуваний випадок виправдовує його вартість.
Джерела та подальше читання
Зовнішні джерела й мінливу документацію перевірено 10 жовтня 2026 року. Приклади роботи PR та задачі підтримки вище — навчальні, вигадані ситуації, а не звіти про реальний продукт.
- OpenAI, Agents API, огляд Agents API, quickstart та changelog — розподіл ролей між Agents API, Agents SDK і Responses API, зокрема керування циклом, інструментами застосунку, середовищем і станом; changelog датує вихід Agents API у публічну бета-версію 10 вересня 2026 року.
- Anthropic, Managed Agents: початок сесії, потік подій та webhooks — поточні стани, збережені події й межі webhook-повідомлень; Managed Agents позначено бета-версією. Перевірено 10.10.2026.
- GitHub, API для pull requests — формат фільтра head-гілки, фільтри базової гілки й стану та пагінація списку. Перевірено 10.10.2026.
- Amazon Web Services (AWS), доставка SQS щонайменше один раз і visibility timeout — гарантія стандартної черги, повторна доставка та межі часу видимості. Перевірено 10.10.2026.
- Martin Kleppmann і Chris Riccomini, Designing Data-Intensive Applications, 2nd edition, O’Reilly Media, лютий 2026, офіційний опис і зміст — глави 5, 8 і 9 про durable execution/workflows, повторно розглянуту обробку повідомлень «рівно один раз», часткові відмови, тайм-аути, оренди та розподілені системи. У цьому розділі застосовано ці межі; приклад SQS окремо звірено з документацією AWS.
- Neal Ford, Mark Richards, Pramod Sadalage та Zhamak Dehghani, Software Architecture: The Hard Parts, O’Reilly Media, 2021, [глава 11 про розподілені workflow](https://www.oreilly.com/library/view/software-architecture-the/9781492086888/ch11.html) — компроміси оркестрації/хореографії, керування станом, власника стану й зв’язності; [глава 7 про гранулярність](https://www.oreilly.com/library/view/software-architecture-the/9781492086888/ch07.html) — сили, що допомагають визначити межі компонентів.
- Frederick P. Brooks Jr., “No Silver Bullet: Essence and Accidents of Software Engineering”, University of North Carolina at Chapel Hill, технічний звіт TR86-020, вересень 1986 — різниця сутнісної та випадкової складності. Концептуальну цілісність розглянуто з The Mythical Man-Month: Essays on Software Engineering, 20th Anniversary Edition, 2nd edition, Addison-Wesley, 1995, сторінка видавця Pearson.
- Matthew Skelton і Manuel Pais, Team Topologies: Organizing Business and Technology for Fast Flow of Value, 2nd edition, IT Revolution, 2025, офіційна сторінка видання — когнітивне навантаження, ясна відповідальність за команди й адаптивна організація взаємодій; застосовано як принцип організації людської роботи, не як класифікацію агентів.
- Anthropic Engineering, “Effective harnesses for long-running agents”, 26.11.2025 — власне описаний експеримент із багатосесійною роботою: ініціалізація, поступовий прогрес, журнал і перевірка завершення. Автори прямо зазначають, що перевага одного агента над multi-agent підходом лишається відкритим питанням; приклад не доводить універсальної переваги будь-якого harness.
- Dmitry Mezhensky, Dmitry Larko та Eugene Steinberg, Grid Dynamics, “From prototype to production-ready agentic AI solution”, опубліковано на Temporal 29.09.2025 — опис переходу від ручного Redis/Kafka стану та повторів до workflow з відновлюваною історією й політиками повтору. Джерело опубліковане постачальником платформи та містить досвід клієнта; це один описаний випадок, а не незалежне порівняльне дослідження. Технічні гарантії SQS у розділі підтверджені окремо документацією AWS.