A2A-стриминг и асинхронные задачи для длительных агентных рабочих процессов
Долгоживущие A2A-задачи продолжают существовать после завершения чат-сессий.
Большинство демонстраций AI-агентов по-прежнему ведут себя как чат-завершения с дополнительными шагами: вы отправляете промпт, ждете несколько секунд и получаете ответ в одном сообщении.
Реальная работа агентов часто не укладывается в эту схему. Исследования, ревью кода, анализ закупок, расследование инцидентов и многоэтапное планирование могут занимать минуты или часы, требовать уточнений на полпути, потоковой передачи частичных результатов, делегирования другому агенту и генерации файлов, а не просто текстового ответа. Именно здесь асинхронная модель протокола A2A приобретает значение в рамках более широкого кластера AI Systems, поскольку A2A рассматривает долгосрочную работу как Task (Задачу) с жизненным циклом, а не как однократный HTTP-ответ. Клиенты могут оставаться подключенными через Server-Sent Events (SSE), опрашивать состояние задачи или регистрировать push-вебхуки, если не могут удерживать соединение открытым.

В этой статье рассматривается операционный дизайн для таких рабочих процессов, включая выбор между потоковой передачей, опросом и push-уведомлениями, то, как input_required вписывается в рабочие процессы с участием человека, обработку ошибок и то, что необходимо инструментировать в продакшене. Об Agent Cards, сообщениях, частях и полной модели задач см. в статье Что такое протокол A2A? Объяснение Agent Cards и задач.
Почему долгосрочным задачам A2A-агентов нужен асинхронный дизайн
Синхронная модель запрос/ответ быстро дает сбой, когда работа агента охватывает инструменты, делегирование, утверждения и крупные артефакты. Задача агента может вызывать несколько серверов MCP внутренне, делегировать подзадачи другому агенту через A2A, ждать одобрения человека, генерировать крупные артефакты по частям, терпеть неудачу на полпути и требовать частичного восстановления, а также накапливать стоимость токенов на нескольких этапах. HTTP API могут аппроксимировать это с помощью таймаутов, фоновых задач и ad-hoc конечных точек статуса, но A2A встраивает идентичность задачи и состояние в протокол, чтобы клиенты и шлюзы могли последовательно рассуждать о работе. О том, как эти слои вписываются в производственного ассистента перед добавлением асинхронных границ A2A, см. в статье Архитектура AI-ассистентов: LLM, память, инструменты, маршрутизация, наблюдаемость.
Моя практическая позиция такова: не создавайте Task для всего, потому что однострочное резюме не нуждается в жизненном цикле. Используйте Task, когда работа является состоятельной, подлежащей аудиту, долгосрочной, производящей артефакты или требующей ввода в процессе выполнения. Основное правило из разъяснительной статьи остается в силе: простые взаимодействия могут возвращать Message, тогда как сложная работа должна возвращать Task.
Жизненный цикл задачи A2A и переходы состояний
Задача A2A проходит через состояния, которые клиенты могут запрашивать в любое время. Точное написание немного различается в зависимости от реализации, но модель стабильна на всех серверах, которые следуют протоколу.
Состояние submitted означает, что клиент отправил работу, и агент принял или поставил ее в очередь. В состоянии working агент активно обрабатывает данные, что может включать вызовы инструментов, делегирование или потоковую передачу частичного вывода. Состояние input_required указывает на то, что агент приостановил работу, так как ему нужен дополнительный ввод, уточнение или одобрение человека, и это не является состоянием ошибки. completed — это терминальный успех с доступными артефактами; failed — это терминальная ошибка, детали и частичные артефакты которой зависят от реализации; canceled означает, что клиент, шлюз или авторизованный вызывающий остановил задачу; а rejected означает, что агент отклонил задачу из-за политики, несоответствия возможностей или аутентификации.
Когда input_required приостанавливает versus вызывает сбой рабочего процесса
Рассматривайте input_required как преднамеренную паузу, а не как исключение. Агент сообщает вам, что он не может продолжить без чего-то от вас, будь то отсутствующий параметр, подтверждение политики или подпись менеджера на действие с высоким риском. Рабочий процесс терпит сбой, когда задача достигает failed или rejected, или когда вызывающий превышает таймаут, ожидая ввода, который так и не пришел, поэтому вы должны проектировать явные таймауты для человеческих шагов, а не оставлять утверждения на неопределенное время.
Утверждение, которое ждет три дня без эскалации, — это застрявший рабочий процесс, а не терпеливый, и застрявшие рабочие процессы забивают хранилища задач, делая дашборды наблюдаемости сложнее для чтения.
Кто может отменить задачу A2A
Право на отмену должно быть определено на этапе дизайна, а не обсуждаться во время инцидента. Клиент обычно может отменять задачи, которые он создал; шлюз может отменять от имени арендаторов, при нарушениях политики или лимитах бюджета; а агент upstream может отменять делегированную работу при оркестрации через A2A, если протокол и политика позволяют это. Логируйте, кто отменил и почему, потому что в цепочках мультиагентов сиротская работа является распространенным источником неожиданных счетов за токены.
Участие человека в цикле с состояниями задач input_required
input_required — одна из самых недооцениваемых функций дизайна A2A, и многие команды относятся к ней как к коду ошибки, тогда как это полноправное состояние рабочего процесса. В продакшене вы столкнетесь со случаями, когда агент должен остановиться, например, тратя бюджет на неоднозначный запрос, выполняя необратимое действие, получая доступ к конфиденциальным данным без подтверждения области видимости или делегируя специалисту, которому нужен явный намеренный пользователь. Моделируйте эти случаи как преднамеренные переходы к input_required, с четким сообщением, объясняющим, что требуется.
Потоки утверждений для рискованного делегирования A2A
Когда Агент A делегирует Агенту B через A2A, и Агент B переходит в input_required для утверждения человеком, три системы должны согласовать дальнейшие действия. Нижний агент приостанавливается и показывает, что ему нужно, оркестратор или шлюз выводит эту паузу пользователю, а ответ пользователя возобновляет задачу через новое сообщение. Сравнение A2A против MCP объясняет, почему делегирование через границы агентов — это иная проблема, чем доступ к инструментам, и почему семантика утверждений должна находиться на уровне задач, а не внутри одного вызова MCP. Не допускайте автоматического утверждения из-за неудобства UX, поскольку дорогие ошибки обычно происходят из-за удобных сокращений, а не из-за отсутствия моделей.
UX-паттерны для приостановленных задач A2A
Блокирующее ожидание означает, что UI показывает спиннер или карточку утверждения, пока задача не покинет input_required, что хорошо работает для коротких человеческих шагов. Неблокирующее ожидание означает, что клиент записывает ID задачи, позволяет пользователю продолжить работу в другом месте и использует опрос или push для уведомления, когда снова потребуется ввод, что необходимо для мобильных устройств, утверждений через email или ассистентов с вкладками. Таймаут, когда люди медленны, означает определение SLA для каждого шага и, после N часов, переход к failed или эскалацию в другую очередь, поскольку необязательные ожидания забивают хранилища задач и запутывают дашборды наблюдаемости.
Как шлюз A2A обрабатывает input_required
Если вы запускаете шлюз A2A, решите, будет ли он прозрачно пересылать события input_required, агрегировать паузы от нескольких нижних агентов в один пользовательский запрос или принудительно требовать утверждения для определенных навыков перед выходом из input_required. Аутентификация и политика для утвержденных действий описаны в отдельной статье по безопасности; пока предположим, что каждая возобновленная задача должна нести ту же пользовательскую идентичность и область видимости, что и исходный запрос.
Выбор синхронного режима, потоковой передачи SSE, опроса или push-уведомлений
A2A поддерживает несколько режимов взаимодействия, и правильный выбор зависит от возможностей клиента и потребностей в задержке, а не от того, какой режим звучит наиболее современно.
| Режим | Лучше всего для | Требования к клиенту | Компромиссы |
|---|---|---|---|
| Sync (SendMessage, короткая задача) | Быстрая работа, немедленные сообщения | Простой HTTP-клиент | Таймауты на медленных агентах |
| Потоковая передача SSE | Прогресс в реальном времени, инкрементные артефакты | Долгосрочное соединение | Прокси, ограничения фонового режима мобильных устройств |
| Опрос (GetTask) | Пакетные клиенты, простые интеграции | Таймер + ID задачи | Более высокая задержка, больше запросов |
| Push-вебхуки | Мобильные, serverless, многочасовые задания | Получатель HTTPS + проверка | Асинхронная сложность, усиление безопасности |
Сначала прочитайте флаги возможностей Agent Card
Прежде чем выбрать режим, прочитайте Agent Card агента, так как потоковая передача требует capabilities.streaming: true, а поддержка push-уведомлений объявляется отдельно. Клиенты, которые предполагают, что каждый агент потоково передает данные, будут ломаться при минимальных реализациях, поэтому согласование не является церемониальным: оно предотвращает сбои во время выполнения, когда специализированный агент поддерживает только опрос состояния.
Когда использовать опрос ассистента вокруг A2A
Ваша среда выполнения ассистента может оборачивать опрос задач A2A в цикл планировщика, а не exposing raw protocol details to the user. Этот паттерн пересекается с общими опрашивающими агентами, которые являются фоновыми процессами, которые просыпаются, проверяют состояние и действуют. Об устойчивом планировании, идемпотентности и паттернах очередей вне A2A см. в статье Опрашивающие агенты в AI-ассистентах: 11 паттернов реализации. Используйте опрос ассистента, когда вы оркестрируете множество задач A2A из единой плоскости управления, и используйте нативную потоковую передачу A2A или push, когда клиент подключается непосредственно к границе агента.
Потоковая передача A2A через Server-Sent Events (SSE)
SSE — это основной канал реального времени A2A. Клиент вызывает SendStreamingMessage, открывает HTTP-соединение и получает ответ text/event-stream, пока задача не достигнет терминального или прерванного состояния. Полезная нагрузка каждого события имеет форму JSON-RPC, а типичные типы результатов включают снимок Task, TaskStatusUpdateEvent для переходов жизненного цикла и промежуточных сообщений агента, а также TaskArtifactUpdateEvent для доставки артефактов по частям с подсказками append и lastChunk для сборки.
client may call SubscribeToTask
Обновления прогресса потоковой передачи и частичные артефакты
Потоковая передача сияет, когда пользователи должны видеть происходящую работу, будь то счетчики шагов (“3 из 7 источников просмотрено”), частичная генерация текста, инкрементные фрагменты файлов для крупных отчетов или переходы состояний от working к input_required без опроса. Проектируйте UI вокруг типов событий, а не вокруг единого финального блока, потому что если вы отображаете вывод только при прибытии completed, вам лучше использовать опрос.
Разрывы соединения SSE и повторная подписка
Сети обрываются, ноутбуки засыпают, а балансировщики нагрузки таймаутуют соединения SSE, поэтому длинные потоки нуждаются в логике восстановления, а не в оптимистичных предположениях. A2A предоставляет SubscribeToTask, чтобы клиенты могли повторно подключиться к потоку выполняющейся задачи, и ваш клиентский SDK должен сохранять taskId локально, обнаруживать закрытие потока до терминального состояния, повторно подписываться с отступлением и дедуплицировать события, если сервер воспроизводит перекрывающееся состояние. Без логики повторной подписки долгосрочные задачи кажутся хрупкими в продакшене, даже когда бэкенд агента здоров.
Push-уведомления и вебхуки A2A
Push подходит для сценариев, где SSE не является хорошим выбором, таких как мобильные приложения в фоновом режиме, обработчики serverless или задачи, которые выполняются часами или днями. Клиент предоставляет PushNotificationConfig с url (вебхук HTTPS на стороне клиента), необязательным token для проверки входящих POST-запросов и необязательными деталями authentication для того, как сервер A2A аутентифицируется у вебхука. Конфигурация может передаваться вместе с начальным вызовом SendMessage или SendStreamingMessage, или добавляться позже через CreateTaskPushNotificationConfig для существующей задачи.
Когда происходит значительное обновление, сервер A2A отправляет POST на вебхук, и клиент обычно вызывает GetTask с уведомленным taskId, чтобы получить полную обновленную задачу и артефакты. Push — это сигнал, а не транспорт полного полезного载荷.
Когда push превосходит открытое соединение SSE
Предпочитайте push, когда клиент не может поддерживать SSE (мобильные, edge-функции), когда обновления редкие и основаны на вехах, а не на токенах, или когда вы хотите, чтобы сервер будил отключенный движок рабочего процесса. Предпочитайте SSE, когда пользователи наблюдают за прогрессом в реальном времени, когда артефакты потоково передаются множеством мелких фрагментов или когда важна задержка менее нескольких секунд.
Корреляция push-уведомлений с задачами A2A
Каждый обработчик push должен логировать и распространять taskId, трассировочный или корреляционный ID от исходного запроса, тип события или переход состояния, а также временную метку из уведомления, чтобы устаревшие события могли быть отклонены. Атаки воспроизведения и дублированная доставка происходят в продакшене, поэтому идемпотентные обработчики не являются опциональными.
Обзор безопасности конечных точек push
Push introduces SSRF risk on the server when malicious clients register internal URLs, and impersonation risk on the client when fake POSTs arrive at the webhook. Mitigations include URL allowlists, ownership verification, signed JWTs with JWKS, timestamp checks, and validating the config token. The full threat model, identity layers, and gateway controls live in A2A and MCP Agent Security: Identity, Delegation, and Audit Trails; until you have read it, treat webhook verification with the same seriousness as payment callbacks.
Push создает риск SSRF на сервере, когда злонамеренные клиенты регистрируют внутренние URL-адреса, и риск имитации на клиенте, когда фальшивые POST-запросы поступают на вебхук. Митигации включают списки разрешенных URL-адресов, проверку владения, подписанные JWT с JWKS, проверку временных меток и валидацию токена конфигурации. Полная модель угроз, слои идентичности и контролы шлюза описаны в Безопасность агентов A2A и MCP: Идентичность, делегирование и журналы аудита; пока вы не прочитаете это, относитесь к проверке вебхуков с такой же серьезностью, как к обратным вызовам платежей.
Асинхронные паттерны рабочих процессов A2A
Отправка задачи “выстрелил и забыл”
Клиент отправляет задачу, немедленно получает ID задачи и отключается, затем позже опрашивает GetTask или ждет push. Это паттерн по умолчанию для serverless и пакетных конвейеров, но вы должны сохранять ID задачи в устойчивом хранилище перед подтверждением пользователю, потому что serverless-вызовы, забывающие ID, теряют работу.
Возобновление задачи после input_required
После input_required пользователь отправляет новое сообщение для той же задачи, и агент переходит обратно в working. Проектируйте сообщения так, чтобы контекст возобновления был явным, потому что “Утверждено: продолжить с поставщиком X” лучше, чем голое “да”, когда вам нужно аудировать, что было утверждено шесть часов назад.
Цепочка делегирования A2A с промежуточными артефактами
Рассмотрите рабочий процесс исследования, где оркестратор владеет задачей T1 и делегирует извлечение, суммаризацию и верификацию специализированным агентам, каждый со своим собственным ID задачи и артефактами по пути.
Каждый этап имеет свой собственный ID задачи и машину состояний, поэтому оркестратор должен потоково передавать или опрашивать нижние задачи независимо, сохранять промежуточные артефакты перед началом следующего этапа и优雅но терпеть неудачу, если T3 завершается, но T4 отклоняет черновик. Паттерны оркестрации мультиагентов охватывает выбор топологии, когда эти специалисты работают как отдельные службы, а не в одной среде выполнения. Частичный прогресс ценен, и неудачная верификация не должна удалять usable черновик без четкой причины.
Устойчивое хранилище задач для задерженного завершения
Состояние задачи и артефакты должны переживать перезагрузки процессов. Если ваш агент работает в Kubernetes, предполагайте, что поды умирают посреди задачи, и резервируйте записи задач и блобы артефактов в хранилище, которое не принадлежит исключительно контейнеру агента.
Обработка ошибок для долгосрочных рабочих процессов A2A
Долгосрочные рабочие процессы терпят неудачу предсказуемым образом через таймауты, повторные попытки, частичные артефакты и небезопасное отмену, и каждый из них нуждается в явной политике, а не ad-hoc обработке в коде клиента.
Таймауты на каждый этап и сквозные бюджеты
Устанавливайте таймауты на двух уровнях: на каждый этап максимум для одной задачи агента перед эскалацией или отменой, и сквозной максимум для видимого пользователем рабочего процесса. Агент извлечения, который зависает, не должен блокировать весь оркестратор, пока браузер пользователя не истечет по таймауту.
Повторные попытки и идемпотентность для задач A2A
Повторные попытки без идемпотентности дублируют побочные эффекты, такие как двойные списания, дубликаты тикетов и повторные emails. Используйте стабильные ID сообщений клиента или ключи идемпотентности, где позволяет протокол, и для бизнес-мутаций согласуйте с Идемпотентность в распределенных системах, которая действительно работает. Повторяйте только временные сбои, такие как сетевые шумы или 503, и не повторяйте слепо rejected или сбои политики, потому что вы увеличите стоимость и раздражите нижних агентов.
Политики восстановления частичных артефактов
Когда задача терпит неудачу после создания частичных артефактов, определите, будете ли вы выставлять частичный вывод пользователю с четкой меткой “неполный”, позволять возобновление с последней хорошей контрольной точки или отбрасывать частичный вывод, когда он может ввести в заблуждение в медицинских, юридических или финансовых контекстах.
Безопасная отмена через цепочки делегирования
Отменяйте нижние задачи, когда верхний пользователь прерывает, используйте граф делегирования, чтобы отмена распространялась, и логируйте отмененные задачи, которые уже incurred стоимость, потому что финансовые команды это замечают.
Наблюдаемость для асинхронных рабочих процессов A2A
Вы не можете отлаживать асинхронную работу мультиагентов, если не можете проследить ее через границы, что означает корреляцию идентификаторов на каждом этапе, а не полагаться на неструктурированные логи. Минимальные поля корреляции включают trace ID для рабочего процесса, инициированного пользователем, task ID для каждой задачи агента, включая делегированные дочерние, agent ID для Agent Card или службы, которая обработала этап, и parent task ID, который связывает цепочки делегирования.
Логируйте каждый переход состояния с временными метками и логируйте события создания артефактов с размером и хешем, а не обязательно полным содержимым, когда применяются политики PII. Атрибутируйте стоимость и задержку на каждый этап, потому что мультиагентные рабочие процессы скрывают расход токенов, пока не придет счет, а метки стоимости на задачу делают ответ на вопрос “какой специалист дорогой?” возможным. Об метриках, бэкендах трассировки и специфичных для LLM паттернах инструментирования см. в Наблюдаемость для систем LLM и более широком столпе Наблюдаемость, чтобы узнать, как эти сигналы вписываются в производственный стек телеметрии.
Когда пользователь спрашивает “почему агент это сделал?”, ваш ответ должен быть трассировкой, охватывающей оркестратор, этапы A2A, вызовы инструментов MCP и любые паузы input_required, а не уклончивым ответом и grep по логам.
Контрольный список для продакшена потоковой передачи A2A и асинхронных задач
Перед отправкой долгосрочных путей A2A в продакшен, проверьте следующие области.
Agent Card и возможности
-
capabilities.streamingотражает фактическую поддержку SSE - Поддержка push-уведомлений задокументирована, если реализована
- Навыки, требующие утверждения человека, документируют ожидаемое поведение
input_required
Режимы клиента
- Клиент SSE обрабатывает повторную подписку через SubscribeToTask
- Интервал опроса отступает под нагрузкой
- Вебхук push проверяет подлинность и отклоняет устаревшие события
Устойчивость
- Состояние задачи переживает перезагрузки процесса агента
- Артефакты хранятся вне эфемерной файловой системы контейнера
- Промежуточные артефакты доступны для частичного восстановления
Ошибки и политика
- Определены бюджеты таймаутов на каждый этап и сквозные
- Повторные попытки идемпотентны для мутирующих операций
- Отмена распространяется через ребра делегирования
Наблюдаемость
- trace ID + task ID + agent ID на каждом этапе
- Переходы состояний логируются
- Атрибуция стоимости на задачу или на агента
Тестирование нагрузки
- SSE через ваш обратный прокси (буферизация ломает потоки)
- Параллельные долгосрочные задачи без утечек памяти на открытых соединениях
- Обработка наводнения push без перегрузки вебхука
Заключение
Ценность A2A проявляется наиболее четко, когда работа не укладывается в один синхронный вызов API, потому что потоковая передача, асинхронные задачи, push-уведомления и явные состояния задач — это то, как протокол обрабатывает реальные рабочие нагрузки агентов, такие как исследования, делегирование, утверждения и крупные артефакты, не притворяясь, что все завершается за один HTTP-обмен. Начните с самого простого режима, который работает, добавьте SSE, когда пользователям нужен прогресс в реальном времени, добавьте push, когда соединения не могут оставаться открытыми, относитесь к input_required как к первоклассному инструменту дизайна, а не к сбою, и инструментрируйте каждый этап, чтобы мультиагентные асинхронные рабочие процессы не обогнали вашу способность их объяснять.
Часто задаваемые вопросы
Когда следует использовать потоковую передачу A2A вместо опроса? Используйте потоковую передачу, когда клиент может удерживать открытое HTTP-соединение и вам нужны обновления прогресса с низкой задержкой или инкрементные артефакты. Используйте опрос, когда соединения ненадежны, клиенты пакетно ориентированы или вам нужны только периодические проверки статуса долгосрочных задач.
Что означает input_required в задаче A2A? Это состояние паузы, где агенту нужна дополнительная информация или утверждение человека. Проектируйте UX и таймауты вокруг него явно, а не относитесь к нему как к ошибке.
Как работают push-уведомления A2A? Зарегистрируйте PushNotificationConfig с вебхуком HTTPS. Сервер отправляет POST при значительных обновлениях; клиент вызывает GetTask для получения полного состояния и артефактов.
Как следует повторять попытки неудачных задач A2A? Повторяйте попытки временных сбоев с ключами идемпотентности, уважайте бюджеты таймаутов и не повторяйте слепо терминальные состояния, такие как rejected или сбои политики.
Что следует логировать для долгосрочных рабочих процессов A2A? Коррелируйте trace ID, task ID и agent ID через этапы. Логируйте переходы состояний, артефакты, делегирование, утверждения и стоимость на шаг, чтобы вы могли реконструировать полный рабочий процесс.
Источники
- Протокол A2A – Потоковая передача и асинхронные операции: https://a2a-protocol.org/latest/topics/streaming-and-async/
- Протокол A2A – Обзор спецификации: https://a2a-protocol.org/latest/specification/