Event Driven Agents

Мультиагентная система без оркестратора: агенты не ждут команды, а подписаны на шину событий и реагируют асинхронно. Отказ от модели «запрос — ответ» в пользу «случилось событие — кто-то отреагировал».

Суть

В привычных паттернах кто-то главный решает, кому передать работу: планировщик, координатор, следующий узел графа. Событийная архитектура убирает это звено. Агенты подключены к шине (Kafka, RabbitMQ), каждый слушает интересующие его типы событий и сам решает, вмешиваться или нет. Результат работы — тоже событие, на которое может отреагировать другой агент.

Выигрыш — в отсутствии единой точки отказа и в естественной масштабируемости: добавить нового агента — значит подписать его на поток, а не переписать граф.

Где это оправдано

Домен узкий, но характерный: реактивные задачи с непредсказуемым моментом наступления. Мониторинг безопасности в реальном времени, транзакционный фрод-мониторинг: здесь момент срабатывания неизвестен заранее, а события идут потоком, а не по запросу пользователя.

Для задач с явным началом и концом («проанализируй этот документ») событийная модель только добавляет сложности — там уместнее fan-out или последовательный пайплайн из Multi Agent Patterns.

Два обязательных требования

В факультативе они сформулированы как жёсткие: без них паттерн разваливается в проде.

Идемпотентность. Агент обязан безопасно переваривать дубликаты событий. Шина гарантирует доставку «хотя бы один раз», а не «ровно один раз» — повтор придёт рано или поздно. Если обработка события списывает деньги или пишет в базу без ключа идемпотентности, повтор превращается в инцидент.

Dead-Letter Queue. События, на которых сломался парсинг ответа модели, уходят в отдельную очередь для ручного разбора. Без DLQ битое событие либо теряется молча, либо бесконечно возвращается в основную очередь и отравляет поток.

Главная слабость: потеря трассировки

Уязвимость паттерна — потеря контекста при трейсинге. В синхронной цепочке traceparent передаётся HTTP-заголовком почти бесплатно (см. W3C Trace Context). В шине событий заголовка нет: идентификатор нужно класть в метаданные сообщения и восстанавливать контекст на стороне подписчика вручную, причём в каждом агенте.

Стоит этим пренебречь — и расследование инцидента превращается в сопоставление меток времени из разных логов. Для системы, где ветвление задумано как норма, это дорого вдвойне.

Связано с

  • Multi Agent Patterns — паттерны с оркестратором, от которых событийная модель отказывается
  • Multi Agent Systems — место паттерна в общей картине MAS
  • W3C Trace Context — почему проброс идентификатора здесь становится ручной работой
  • Agent Failure Modes — молча потерянное событие не отражается ни в одной метрике
  • Hybrid Orchestration — противоположный полюс: максимум детерминизма вместо максимума автономии

Открытые вопросы

  • как ставить ключ идемпотентности, когда событие порождает недетерминированный ответ модели
  • что делать с событиями из DLQ: переигрывать после фикса промпта или считать потерянными