Проблема
Запит виглядає звичайним: перевірити кейс клієнта і підготувати коротку відповідь.
У трейсах видно інше: оркестратор запустив 5 агентів,
троє з них робили майже ту саму підзадачу,
кількість handoff-ів між агентами дійшла до 14 за один run,
а фінальна відповідь так і не сформувалась до timeout.
Система не падає одразу.
Вона починає шуміти: ростуть дублікати, handoff-и, черга і latency.
Аналогія: уяви зміну в ресторані, де офіціанти не поділили столи. Троє людей приймають одне замовлення, а інші столи чекають. Роботи багато, але результат гірший. Multi-agent chaos в AI-системах працює так само: дій більше, а корисного прогресу менше.
Чому це стається
Multi-agent chaos виникає не через саму кількість агентів, а через відсутність жорсткої координації між ними.
У production зазвичай так:
- ролі агентів перетинаються, і одна підзадача отримує кількох власників;
- делегування йде без чітких меж по глибині і кількості передач;
- немає єдиного правила арбітражу (arbitration), хто приймає фінальне рішення;
- дубльовані
tool_callвід різних агентів множать навантаження; - без stop reasons і budget gates run довго не сходиться.
Проблема не в самому multi-agent підході.
Кілька агентів діють без єдиного контуру контролю.
Які збої трапляються найчастіше
У production найчастіше видно чотири патерни multi-agent chaos.
Перетин ролей (Role overlap)
Два або більше агентів беруть ту саму підзадачу і дають різні проміжні результати.
Типова причина: немає role map і явного власника підзадачі.
Цикл делегування (Delegation loop)
Agent A делегує B, B делегує C, C повертає назад A. Зовні run "активний", але прогресу немає.
Типова причина: немає ліміту на глибину делегування і бюджет передач.
Дубльована робота між агентами (Cross-agent duplicate work)
Різні агенти викликають той самий tool з однаковими або майже однаковими аргументами.
Це швидко переходить у tool spam.
Типова причина: відсутній dedupe на рівні всього run, а не лише одного агента.
Надмірний fan-out (Unbounded fan-out)
Один агент породжує багато дочірніх задач, і система витрачає ресурси швидше, ніж завершує корисну роботу.
Типова причина: немає caps на кількість активних агентів і parallel tasks.
Як виявляти ці проблеми
Multi-agent chaos добре видно по комбінації orchestration- і runtime-метрик.
| Метрика | Сигнал multi-agent chaos | Що робити |
|---|---|---|
agent_handoffs_per_run | багато передач задач без завершення | ввести max_handoffs і stop reason |
delegation_depth_p95 | ланцюги делегування стають занадто глибокими | обмежити глибину і примусово повертати в orchestrator |
duplicate_subtask_rate | кілька агентів роблять ту саму підзадачу | lock власника задачі + dedupe signatures |
cross_agent_tool_overlap_rate | ріст однакових tool_call між агентами | shared cache, per-run dedupe, bounded fan-out |
multi_agent_chaos_stop_rate | часті multi_agent_chaos:* stop reasons | переглянути ролі агентів і arbitration policy |
Як відрізнити multi-agent chaos від корисної спеціалізації
Не кожен довгий multi-agent run означає хаос. Ключове питання: чи кожен агент додає унікальний внесок у фінальний результат.
Нормально, якщо:
- у підзадачі є один власник і зрозуміла зона відповідальності;
- handoff змінює стан задачі, а не просто передає її далі;
- кількість агентів і викликів росте разом із якістю відповіді.
Небезпечно, якщо:
- одна підзадача має кількох власників;
- агенти "перекидають" задачу без нового сигналу;
- вартість і latency ростуть, а run не сходиться до
final_answer.
Як зупиняти такі збої
Практично це виглядає так:
- задаєш рольову карту: хто що робить і хто власник кожної підзадачі;
- ставиш ліміти на активних агентів, кількість передач і глибину делегування;
- вводиш arbitration step перед кожною новою делегацією;
- при конфліктах або перевищенні бюджету перемикаєшся у fallback (single-agent або часткова відповідь).
Мінімальний guard для multi-agent координації:
from dataclasses import dataclass
import json
def task_signature(task: dict) -> str:
return json.dumps(task, sort_keys=True, ensure_ascii=False)
@dataclass(frozen=True)
class MultiAgentLimits:
max_agents_per_run: int = 4
max_handoffs: int = 8
max_delegation_depth: int = 3
max_parallel_subtasks: int = 6
max_duplicate_signature: int = 2
class MultiAgentChaosGuard:
def __init__(self, limits: MultiAgentLimits = MultiAgentLimits()):
self.limits = limits
self.seen_agents: set[str] = set()
self.handoffs = 0
self.in_flight_signatures: set[str] = set()
self.signature_claims: dict[str, int] = {}
self.owner_by_signature: dict[str, str] = {}
def register_agent(self, agent_id: str) -> str | None:
self.seen_agents.add(agent_id)
if len(self.seen_agents) > self.limits.max_agents_per_run:
return "multi_agent_chaos:agent_fanout"
return None
def on_handoff(self, _from_agent: str, to_agent: str, depth: int) -> str | None:
self.handoffs += 1
if self.handoffs > self.limits.max_handoffs:
return "multi_agent_chaos:handoff_budget"
if depth > self.limits.max_delegation_depth:
return "multi_agent_chaos:delegation_depth"
return self.register_agent(to_agent)
def claim_subtask(self, agent_id: str, task: dict) -> str | None:
sig = task_signature(task)
owner = self.owner_by_signature.get(sig)
if owner is not None and owner != agent_id:
return "multi_agent_chaos:ownership_conflict"
self.owner_by_signature.setdefault(sig, agent_id)
self.signature_claims[sig] = self.signature_claims.get(sig, 0) + 1
if self.signature_claims[sig] > self.limits.max_duplicate_signature:
return "multi_agent_chaos:duplicate_subtask"
if sig not in self.in_flight_signatures:
if len(self.in_flight_signatures) >= self.limits.max_parallel_subtasks:
return "multi_agent_chaos:parallel_fanout"
self.in_flight_signatures.add(sig)
return None
def finish_subtask(self, task: dict) -> None:
self.in_flight_signatures.discard(task_signature(task))
Це базовий guard.
У цій версії seen_agents рахує і спроби розширення fan-out, а не лише вже допущених агентів.
max_agents_per_run тут обмежує кількість унікальних агентів у межах одного run.
У production його зазвичай доповнюють shared state store,
priority queue для підзадач і явним fallback у single-agent режим.
on_handoff(...) викликають до передачі задачі іншому агенту,
а claim_subtask(...) — до запуску роботи, щоб зупиняти хаос ще на вході.
Де це реалізується в архітектурі
У production контроль multi-agent chaos зазвичай розкладений між трьома шарами системи.
Orchestration Topologies визначає, як агенти взаємодіють, хто є власником стану і де проходить арбітраж (arbitration). Без цього шару хаос між агентами майже неминучий.
Agent Runtime керує execution limits,
stop reasons (multi_agent_chaos:*) і fallback переходами.
Саме тут ставлять handoff/depth budgets і умови примусової зупинки.
Tool Execution Layer закриває дубльовані виклики інструментів між агентами: dedupe, retries, timeout і shared caching у межах run.
Checklist
Перш ніж шипити multi-agent сценарій у production:
- [ ] role map і власник для кожної підзадачі задані явно;
- [ ]
max_agents_per_run,max_handoffs,max_delegation_depthзадані; - [ ] є lock власника задачі і per-run dedupe signatures;
- [ ] bounded fan-out на паралельні підзадачі увімкнений;
- [ ] stop reasons покривають
multi_agent_chaos:*; - [ ] є fallback: single-agent mode або часткова відповідь;
- [ ] алерти на
agent_handoffs_per_run,duplicate_subtask_rate,queue_backlog; - [ ] runbook описує, як локалізувати конфлікт ролей під час інциденту.
FAQ
Q: Більше агентів завжди означає кращу якість?
A: Ні. Без координації більше агентів часто дає більше дублювань і конфліктів, а не кращий результат.
Q: Чи можна прибрати chaos лише правкою prompt?
A: Ні. Prompt допомагає, але корінь проблеми в orchestration-контролі: ролях, власності задач, budgets і arbitration.
Q: Що робити, якщо chaos вже почався у production?
A: Тимчасово обмежити fan-out, знизити кількість активних агентів, увімкнути single-agent fallback і перевірити stop reasons у трейсах.
Q: Хто має приймати фінальне рішення в multi-agent системі?
A: Зазвичай один orchestrator або arbitration step. Без єдиного власника фінального рішення система швидко переходить у конфлікти або дублювання.
Multi-agent chaos майже ніколи не виглядає як одна велика поломка. Частіше це накопичення маленьких конфліктів між агентами. Тому production-системам потрібні не лише "розумні" агенти, а й жорстка orchestration-дисципліна.
Пов'язані сторінки
Якщо ця проблема виникла у production, корисно також подивитися:
- Чому AI агенти ламаються — загальна карта збоїв у production.
- Deadlocks — як циклічне очікування між агентами блокує workflow.
- Cascading failures — як локальна помилка розповзається по системі.
- Tool spam — як дубльовані виклики інструментів з'їдають бюджет.
- Agent Runtime — де ставити budgets, stop reasons і fallback.
- Orchestration Topologies — як проектувати керовану взаємодію агентів.
- Tool Execution Layer — де централізувати retries, dedupe і timeout.