Alexander Bond • 01.11.2026 • 8 мин чтения мультиагентные системыai ройоркестрация

Мультиагентные системы на практике: как оркестровать рой узких AI-агентов для сложных B2B-задач без потери контекста

Инженерный разбор: почему единый мега-промпт деградирует на 4–6 шаге диалога и как рой узких агентов поверх иерархического конечного автомата даёт 78% экономии токенов и p95 = 1.8 с. С рабочим кодом на FastMCP, Pydantic-стейтом и боевыми цифрами.

Инженерный разбор: почему единый мега-промпт деградирует на 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

Первая реализация почти всегда — шина сообщений, где агенты подписываются друг на друга. Через две недели вы получаете:

  • **Шторм взаимных вызовов.** Router отдаёт Supervisor'у, тот возвращает Router'у, цикл крутится 30–40 итераций, счёт растёт квадратично.
  • **Race conditions.** Два агента одновременно пишут в CRM: две сделки на одного лида, дубли задач.
  • **Циклические дедлоки.** A ждёт B, B ждёт C, C ждёт A. Внешне — «агент думает».
  • **Невоспроизводимость.** Нет детерминированного трейса — баг нельзя ни поймать, ни повторить.
  • Рабочее решение — иерархический конечный автомат (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. Следующий агент получает только сериализованный стейт + свою роль-инструкцию.

    Практические правила:

  • Сырой диалог видит только Knowledge Agent, и только последние 3 реплики.
  • Извлечённые факты живут в стейте как поля, а не как текст в истории.
  • Стейт на 15–20 полей — это 400–600 токенов вместо 6 000.
  • У каждого поля есть `source` и `confidence`: спорные значения не перезаписываются молча, а помечаются `needs_review`.
  • 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

    Автоматизируйте привлечение B2B-клиентов

    Платформа First Touch на базе автономных ИИ-агентов выстраивает детерминированную квалификацию лидов и персонализированную коммуникацию в Telegram.

    Попробовать First Touch