Инженерный разбор: почему единый мега-промпт деградирует на 4–6 шаге диалога и как рой узких агентов поверх иерархического конечного автомата даёт 78% экономии токенов и p95 = 1.8 с. С рабочим кодом на FastMCP, Pydantic-стейтом и боевыми цифрами.
Мультиагентные системы на практике: как оркестровать рой узких AI-агентов для сложных B2B-задач без потери контекста
1. Почему один мега-промпт умирает на пятом шаге
Возьмите типовую B2B-воронку: квалифицировать лида, ответить по прайсу, вызвать CRM, проверить юридическую формулировку. Соблазн один — system prompt на 3000 токенов и одна «умная» модель. В демо это работает. В проде ломается на 4–6 шаге диалога — и именно на этом месте First Touch заменил мега-промпт роем узких автономных агентов с раздельными контекстами.
Причины деградации измеримы.
Context rot. Каждая реплика добавляет в окно 300–800 токенов. К шестому шагу в контексте лежит 5–6 тысяч токенов, из которых 70% — мусор: приветствия, отменённые ветки, прошлые версии цен. Модель цепляется за устаревшие факты, точность извлечения падает на 15–25% относительно чистого контекста.
Дрейф инструкций. Чем длиннее промпт, тем ниже вес каждого правила. Запрет «не называй цену без квалификации» на 2800-м токене системного сообщения игнорируется примерно в трети прогонов. Это не баг модели — это математика attention.
Экспоненциальная стоимость. Полный контекст переотправляется на каждом шаге: 6 шагов × 6К токенов = 36К входных токенов на один диалог, и почти всё это — пересказ самого себя.
2. Декомпозиция ролей в B2B-рое
Правило деления: агент = одна задача + один тип выхода. Два разных выхода — это два агента.
Router / Triage Agent
Быстрая дешёвая модель (7–8B). Определяет язык, намерение (spam / support / sales / churn), извлекает сущности. Выход — enum + confidence. Доступа к инструментам нет вообще. Стоимость шага — 150–250 токенов.
Qualification Agent
Детерминированный опросник: бюджет, срок, роль клиента, интеграции. Ключевое: это не «поговори с клиентом», это «заполни слоты». Задаёт по одному вопросу, завершается по заполнению slots или отказу. Выход — LeadProfile.
Knowledge Agent
Единственный, кто видит сырой текст диалога и документацию. Работает поверх RAG: top-k=8 чанков, обязательное цитирование source_id. Генерировать факты не имеет права — только извлекать с указанием источника.
Action / FastMCP Tool Agent
Выполняет сайд-эффекты: создание сделки, обновление полей, отправка письма. Инструменты описаны через FastMCP — строгая типизация аргументов и автогенерация JSON-схемы. Агент не рассуждает, он маппит стейт в вызов инструмента.
Supervisor / Guardrail Agent
Проверяет исходящее сообщение: нет выдуманных цен, нет обещаний SLA, tone-of-voice соблюдён, PII не утекли. Возвращает Approve | Reject(reason) | Rewrite(text). Единственный агент с правом вета.
3. State Machine побеждает свободный Pub/Sub
Первая реализация почти всегда — шина сообщений, где агенты подписываются друг на друга. Через две недели вы получаете:
Рабочее решение — иерархический конечный автомат (HSM) с централизованной контекстной шиной:
TRIAGE → QUALIFY → ENRICH → ACT → REVIEW → (DONE | ESCALATED)
Бесплатно получаете: валидируемые переходы (из TRIAGE нельзя в ACT), одного владельца записи в стейт на состояние, полный трейс переходов для observability и понятную точку для step budget.
Обмен между агентами — не свободный текст, а структурированный контракт. Мы фиксируем его в спецификациях llms.txt: единый машиночитаемый протокол знаний с полями состояния, допустимыми переходами и форматом tool-вызовов. Это снимает главную боль интеграции — «что именно агент А обязан вернуть агенту Б».
4. Context Compaction и Handoff
Handoff — это не «переслать историю». Это сериализация состояния:
1. Агент возвращает строго типизированный объект (Pydantic-модель).
2. Оркестратор мёржит его в общий SwarmState с версионированием.
3. Следующий агент получает только сериализованный стейт + свою роль-инструкцию.
Практические правила:
5. Защита от дедлоков и сбоев
Step budget / TTL. Жёсткий лимит — 4 перехода агентов на один входящий запрос. Исчерпали — ESCALATED человеку. Без лимита рой гарантированно найдёт способ зациклиться.
Идемпотентность tool-вызовов. Каждый вызов получает idempotency_key = hash(lead_id + action + payload_version). Повторный вызов с тем же ключом возвращает кэшированный результат вместо второй сделки.
Fallback. Таймаут инструмента 2 с → один retry с exponential backoff → degraded mode: агент возвращает ActionPending, ставит задачу в очередь, пользователю отвечает без подтверждения записи.
Circuit breaker на внешних API: 5 ошибок подряд — инструмент выключается на 60 секунд, роут уходит в ветку без него.
6. Рабочий код: FastMCP + Async Orchestrator
from enum import Enum
from typing import Literal
from pydantic import BaseModel, Field
class Stage(str, Enum):
TRIAGE = 'triage'; QUALIFY = 'qualify'; ENRICH = 'enrich'
ACT = 'act'; REVIEW = 'review'; DONE = 'done'; ESCALATED = 'escalated'
class LeadProfile(BaseModel):
budget_usd: int | None = None
deadline_days: int | None = None
integrations: list[str] = Field(default_factory=list)
confidence: float = 0.0
needs_review: bool = False
class SwarmState(BaseModel):
request_id: str
stage: Stage = Stage.TRIAGE
intent: Literal['sales', 'support', 'spam', 'churn'] | None = None
profile: LeadProfile = LeadProfile()
facts: dict[str, str] = {}
steps: int = 0
trace: list[str] = Field(default_factory=list)
MAX_STEPS = 4
class SwarmOrchestrator:
def __init__(self, agents: dict[Stage, object]):
self.agents = agents
self.allowed = {
(Stage.TRIAGE, Stage.QUALIFY),
(Stage.QUALIFY, Stage.ENRICH),
(Stage.ENRICH, Stage.ACT),
(Stage.ACT, Stage.REVIEW),
(Stage.REVIEW, Stage.DONE),
(Stage.REVIEW, Stage.ESCALATED),
}
async def run(self, state: SwarmState, message: str) -> SwarmState:
while state.stage not in (Stage.DONE, Stage.ESCALATED):
if state.steps >= MAX_STEPS:
state = state.model_copy(update={'stage': Stage.ESCALATED})
state.trace.append('budget_exceeded')
break
agent = self.agents[state.stage]
nxt, patch = await agent.handle(state, message)
if (state.stage, nxt) not in self.allowed:
raise ValueError(f'illegal transition {state.stage} -> {nxt}')
state = state.model_copy(update={**patch, 'stage': nxt, 'steps': state.steps + 1})
state.trace.append(f'{agent.name}:{nxt.value}')
return state
Инструменты описываются декларативно, схема аргументов генерируется автоматически:
from fastmcp import FastMCP
mcp = FastMCP('crm')
@mcp.tool()
async def create_deal(lead_id: str, amount_usd: int, idempotency_key: str) -> dict:
return await crm.upsert(lead_id, amount_usd, key=idempotency_key)
7. Продакшен-метрики и юнит-экономика роя
Боевые цифры First Touch на одном наборе из 12 000 реальных B2B-диалогов:
| Метрика | Единый агент | Рой микро-агентов |
|---|---|---|
| Токенов на диалог | 18 000 | 4 200 |
| Стоимость диалога | $0.18 | $0.038 |
| Точность извлечения | 72% | 98.4% |
| p95 отклика | 6.4 с | 1.8 с |
Снижение стоимости сессии — 78%. Секрет не в «более дешёвой модели», а в том, что 80% шагов обслуживаются маленькими моделями на коротком контексте, и только Knowledge/Supervisor используют крупную.
Где рой проигрывает: на одношаговых задачах (классификация письма) overhead оркестрации — 200–300 мс и лишний вызов. Правило: до 3 шагов — один агент, от 4 — рой.
8. Заключение
Мультиагентность — это не про «много моделей». Это про управляемое состояние: типизированный стейт, детерминированные переходы, бюджет шагов и явные guardrail'ы. Рой выигрывает у мега-промпта не интеллектом, а инженерией контекста.
К 2026 году мультиагентные графы станут таким же стандартом enterprise-автоматизации, как сегодня — очередь и база данных. Кто строит их сейчас, получает 78% экономии на токенах и предсказуемый p95.
Нужно спроектировать рой с нуля или провести аудит существующей системы? First Touch — консультации по мультиагентной архитектуре, аудит контекстных бюджетов и сборка оркестратора под вашу B2B-воронку.
🚀 Проект автора: First Touch (https://aifirsttouch.ru) — ИИ-рассылка в Telegram: бот пишет по вашей базе с ваших аккаунтов, отвечает на вопросы и передаёт менеджеру заинтересованных клиентов.
Автор: Alexander Bond — AI-разработчик и архитектор автономных систем
Теги: мультиагентные системы, ai рой, оркестрация, b2b автоматизация, mcp