Коротко: что такое A2A Protocol

A2A Protocol (Agent-to-Agent) — открытый стандарт взаимодействия между ИИ-агентами, разработанный Google и переданный под управление Linux Foundation. В отличие от MCP, который соединяет агента с инструментами, A2A решает проблему peer-to-peer коммуникации: как агент, написанный на LangGraph, может отдать задачу агенту на CrewAI, который запущен у другого вендора. Протокол использует HTTP, JSON-RPC и Server-Sent Events — технологии, знакомые каждому бэкенд-разработчику. В апреле 2026 года вышла версия v1.0 с поддержкой gRPC, multi-tenancy и подписанных Agent Card. На сегодня A2A поддерживают более 150 организаций, включая Microsoft Azure AI Foundry, AWS Bedrock AgentCore и Google Cloud.

Multi-agent системы в 2026 году упёрлись в фундаментальную проблему: агенты, собранные на разных фреймворках, не умеют разговаривать друг с другом. LangGraph, CrewAI, AutoGen, Semantic Kernel, Google ADK — каждый использует свой внутренний протокол. Соединить их можно, но через кастомные адаптеры, хрупкие прослойки форматирования и общие БД, которые не масштабируются.

A2A решает это на уровне протокола. Он определяет общий язык для агентов: как они находят друг друга, как договариваются о задачах, как передают результаты. При этом агенты могут оставаться полностью непрозрачными — не раскрывать свою внутреннюю память, инструменты или логику. Достаточно опубликовать Agent Card, и любой другой агент, поддерживающий A2A, сможет с вами взаимодействовать.

150+ Организаций поддерживают A2A
5 Production-языков SDK
24.5K Звёзд на GitHub
v1.0 Стабильный релиз (апрель 2026)

Архитектура A2A: как агенты общаются

В основе A2A — четыре абстракции, которые покрывают полный цикл взаимодействия:

Agent Card — JSON-документ, который каждый агент публикует по стандартному пути .well-known/agent.json. В нём указано, какие задачи агент умеет решать, поддерживает ли стриминг, какие форматы данных принимает и как проходит аутентификация. Другие агенты читают Agent Card, чтобы решить — делегировать этому агенту задачу или нет.

Task Object — основная единица обмена. Задача проходит через жизненный цикл: submitted → working → input_required → working → completed (или failed, canceled). Каждый переход сопровождается сообщением с деталями статуса.

Artifact — результат выполнения задачи. Может быть текстом, JSON, файлом или комбинацией форматов. Агент-отправитель забирает артефакт и использует в своём пайплайне.

Message — промежуточные сообщения во время выполнения задачи. Через них агенты обмениваются уточнениями, частичными результатами и статусами.

Коммуникация строится поверх HTTP с SSE для стриминга (или gRPC в v1.0). Никаких разделяемых баз данных, никаких общих инструментов — только структурированные JSON-RPC сообщения через сеть.

Agent Card: визитная карточка агента

Первый шаг к A2A-совместимости — научить агента рассказывать о себе. Agent Card — это JSON, который хостится на том же домене, что и агент, по адресу /.well-known/agent.json:

{
  "name": "candidate-screener",
  "description": "Проверяет кандидатов на соответствие требованиям",
  "url": "https://screener.example.com/a2a",
  "version": "1.0.0",
  "capabilities": {
    "supported_tasks": ["screen_candidate", "verify_credentials"],
    "streaming": true,
    "push_notifications": false
  },
  "authentication": {
    "schemes": [
      { "type": "bearer", "bearerFormat": "JWT" }
    ]
  },
  "default_input_modalities": ["text"],
  "default_output_modalities": ["text", "json"]
}

Что здесь важно: поле capabilities.supported_tasks — это словарь того, что агент умеет. Другие агенты не гадают на кофейной гуще, а просто читают этот список и сравнивают со своими потребностями. Если нужной задачи нет — поиск другого агента. Если есть — отправка запроса.

С версии v1.0 Agent Card можно подписывать с использованием JWK, чтобы агенты могли верифицировать, что карта действительно от доверенного источника. Это критически важно для enterprise-сценариев, где нельзя полагаться на добросовестность неизвестного узла.

Каждый A2A-совместимый агент обязан публиковать Agent Card. Это единственное жёсткое требование протокола — всё остальное опционально и настраивается под конкретный сценарий.

Task Lifecycle: жизненный цикл задачи

Когда один агент решает делегировать задачу другому, начинается путешествие через состояния. A2A определяет конечный автомат с шестью состояниями:

SUBMITTEDWORKING → (опционально INPUT_REQUIREDWORKING) → COMPLETED / FAILED / CANCELED

Разберём на примере. Агент-рекрутер (на LangGraph) отправляет задачу агенту-скринеру (на CrewAI):

  • SUBMITTED: задача принята в очередь. Скринер подтвердил получение, вернул ID задачи.
  • WORKING: скринер начал обработку. Проверяет резюме, сверяет навыки — каждые несколько секунд шлёт статус с SSE.
  • INPUT_REQUIRED: скринеру не хватает данных: «Какие языки программирования обязательны, а какие опциональны?». Рекрутер отвечает, и задача возвращается в WORKING.
  • COMPLETED: скринер вернул артефакт — JSON с оценкой кандидата (92/100, recommended).

Такой жизненный цикл покрывает и быстрые синхронные задачи (типа «переведи текст» — сразу COMPLETED), и длительные асинхронные («исследуй рынок» — может длиться часы с пуш-уведомлением о завершении).

Пишем A2A-сервер на Python

Официальный Python SDK от Google — a2a-sdk — позволяет поднять A2A-сервер буквально в несколько строк. Вот минимальный агент, который проверяет кандидатов:

# server.py — A2A-агент на Python
from a2a.agent import Agent, AgentCard
from a2a.server import A2AServer
from a2a.types import Task, TaskStatus, Message, TextPart, JSONPart

class CandidateScreener(Agent):
    """Проверяет кандидатов на соответствие требованиям."""

    def get_agent_card(self) -> AgentCard:
        return AgentCard(
            name="candidate-screener",
            description="Screens candidates against requirements",
            capabilities={"supported_tasks": ["screen_candidate"]}
        )

    async def handle_task(self, task: Task) -> TaskStatus:
        requirements = task.message.parts[0].text
        result = {
            "candidate": "John Doe",
            "score": 92,
            "qualified": True,
            "missing_skills": []
        }
        task.status = TaskStatus.COMPLETED
        task.artifact = [
            JSONPart(json=result),
            TextPart(text=f"Кандидат набрал {result['score']}/100")
        ]
        return task.status

if __name__ == "__main__":
    server = A2AServer(
        agent=CandidateScreener(),
        host="0.0.0.0",
        port=8001
    )
    server.start()
pip install a2a-sdk
python server.py
# Агент доступен: http://localhost:8001/a2a
# Agent Card: http://localhost:8001/.well-known/agent.json

Что здесь происходит: мы наследуем базовый класс Agent, определяем Agent Card (какие задачи умеем) и реализуем handle_task — точку входа для всех входящих задач. SDK сам разворачивает HTTP-сервер, публикует Agent Card и обрабатывает жизненный цикл задач.

Для более сложных сценариев — с реальной LLM, подключением к базе данных, MCP-инструментами — достаточно заменить логику внутри handle_task. A2A SDK не навязывает архитектуру агента, он только стандартизирует коммуникационный слой.

Клиент: обнаружение и делегирование

Теперь напишем агента-клиента, который находит скринера по Agent Card и отправляет ему задачу:

# client.py — ищем агента и делегируем задачу
from a2a.client import A2AClient
from a2a.types import Task, Message, TextPart

async def get_candidate_screening(agent_url: str, requirements: str):
    async with A2AClient(agent_url) as client:
        # Шаг 1: читаем Agent Card
        card = await client.get_agent_card()
        print(f"Найден агент: {card.name}")
        print(f"Умеет: {card.capabilities}")

        # Шаг 2: проверяем, что задача поддерживается
        if "screen_candidate" not in card.capabilities["supported_tasks"]:
            raise ValueError("Агент не умеет скринить кандидатов")

        # Шаг 3: отправляем задачу со стримингом
        task = Task(
            message=Message(parts=[TextPart(text=requirements)])
        )

        async for update in client.send_task_stream(task):
            print(f"Статус: {update.status}")
            if update.artifact:
                return update.artifact[0].json

# Использование
result = await get_candidate_screening(
    "https://screener.example.com/a2a",
    "Senior Python developer, 5+ years, financial services"
)

Клиент делает три вещи: обнаруживает агента (читает Agent Card), проверяет совместимость (сверяет supported_tasks) и отправляет задачу. Стриминг через SSE даёт промежуточные статусы — можно показывать пользователю прогресс или реагировать на запросы уточнения.

Если агент запросит дополнительную информацию (статус INPUT_REQUIRED), клиент может ответить — и задача продолжит исполнение. Это покрывает длинные диалоги между агентами без потери контекста.

Production-развёртывание

Версия v1.0, вышедшая в апреле 2026 года, принесла три enterprise-функции, которые переводят A2A из статуса «поиграться» в «работает в продe»:

Multi-tenancy. Один A2A-эндпоинт может хостить множество агентов под одной крышей. Платформенная команда разворачивает один A2A-шлюз, который маршрутизирует задачи к сотням специализированных агентов — с единой балансировкой, observability и безопасностью. Для SaaS-провайдеров это означает, что не нужно поднимать отдельный сервер под каждого клиентского агента.

gRPC transport. В дополнение к HTTP/SSE появился gRPC — с Protocol Buffers, bidirectioinal streaming и на порядок меньшей задержкой. Для in-house микросервисной архитектуры, где агенты общаются внутри одного кластера, gRPC снижает latency на 40–60% по сравнению с HTTP (по данным тестов Linux Foundation, апрель 2026). Для внешних интеграций лучше оставить HTTP/SSE — он совместимее и проходит через корпоративные прокси.

Подписанные Agent Card. JWK-подпись Agent Card позволяет агентам убедиться, что карта не подделана. В enterprise-среде, где агент может делегировать задачу агенту из другого облака (Azure → GCP), проверка подписи — базовая гигиена безопасности.

Как выглядит архитектура на проде: у каждого агента есть свой микросервис (Docker-контейнер), который публикует A2A-эндпоинт. Агент-оркестратор (обычно на LangGraph или Google ADK) держит в памяти Agent Card всех известных агентов и маршрутизирует задачи. Если задача требует цепочки из трёх агентов — оркестратор вызывает первого, тот частично обрабатывает и вызывает второго через A2A, результат возвращается по цепочке обратно.

A2A и MCP: не конкуренты, а слои

Самый частый вопрос, который возникает при знакомстве с A2A: «А как же MCP? Он же тоже для агентов». Разница принципиальная: MCP соединяет агента с инструментами (базами данных, API, файловой системой), а A2A соединяет агентов друг с другом.

Вот таблица для наглядности:

ПараметрA2AMCP
НазначениеАгент ↔ агентАгент ↔ инструмент
ОбластьМежорганизационная, кроссплатформеннаяВнутренние инструменты агента
ОбнаружениеAgent Card (.well-known/agent.json)Статическая конфигурация эндпоинта
ПротоколJSON-RPC + SSE / gRPCJSON-RPC
АутентификацияOpenAI-совместимые схемы + JWKOAuth 2.0 / API keys
Модель задачиAsync lifecycle (streaming, push)Синхронные вызовы инструментов
Когда использоватьКоординация агентов через границыПредоставление инструментов агенту

На практике A2A и MCP — комплементарные протоколы. Один и тот же агент может использовать MCP для доступа к PostgreSQL и A2A для делегирования задачи другому агенту. Google ADK, например, поддерживает оба протокола из коробки: MCP — для инструментов, A2A — для inter-agent коммуникации.

Когда A2A не нужен: если вы строите single-agent систему, которая просто вызывает инструменты — A2A будет лишним оверхедом. MCP и обычного REST API достаточно. A2A оправдан, когда в системе два и более автономных агента, работающих на разных платформах или у разных вендоров.

Что ещё важно знать

Чем A2A отличается от обычного REST API между сервисами?

REST API требует, чтобы вы заранее знали эндпоинты, форматы запросов и схему данных. A2A добавляет слой обнаружения (Agent Card), стандартизированный жизненный цикл задач (task lifecycle) и динамическую маршрутизацию — агенты сами находят друг друга и определяют, могут ли выполнить задачу. Для микросервисной архитектуры, где вы контролируете оба конца, REST может быть проще. Для гетерогенной среды с агентами от разных вендоров A2A — единственный стандартизированный вариант.

Можно ли использовать A2A без Google ADK?

Да, это ключевая особенность A2A. Протокол не привязан к ADK — Python SDK работает с любым фреймворком (LangGraph, CrewAI, Semantic Kernel, AutoGen). A2A только определяет формат сообщений и жизненный цикл, внутренняя реализация агента остаётся на ваше усмотрение. Более того, A2A Python SDK поддерживает интеграцию с Anthropic, OpenAI, AWS Bedrock и HuggingFace через дополнительные пакеты.

Какие SDK доступны для A2A?

На момент v1.0 доступны production-релизы на Python (a2a-sdk), JavaScript/TypeScript, Java, Go и .NET. Python SDK — самый зрелый, с поддержкой стриминга, multi-tenancy и gRPC. Остальные SDK покрывают базовый функционал: Agent Card, Task Lifecycle, HTTP/SSE транспорт. Все SDK распространяются под Apache 2.0 на GitHub a2aproject/A2A.

Как A2A решает проблему безопасности при общении агентов разных вендоров?

Двумя способами. Во-первых, Agent Card может быть подписан JWK — каждый агент проверяет подпись перед делегированием задачи. Во-вторых, A2A поддерживает стандартные OpenAPI-схемы аутентификации (Bearer, OAuth 2.0, API Key). Агенты могут требовать аутентификацию при каждом запросе. Кроме того, агенты не раскрывают свои внутренние инструменты, память или логику — только Agent Card и задачи. Это принцип opaque agent design: внешний мир видит только то, что агент решил показать.

A2A подходит для локальных LLM или только для облачных?

Подходит для любых LLM — облачных, локальных (Ollama, vLLM), on-premise. A2A не касается слоя инференса. Агент внутри использует любую модель, а снаружи общается через A2A. Можно построить гибридную систему: часть агентов на локальных моделях (конфиденциальные данные), часть — на GPT-5.5 или Claude для сложных задач. A2A будет единым протоколом для всех.