Содержание
Коротко: что такое 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, сможет с вами взаимодействовать.
Архитектура 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 определяет конечный автомат с шестью состояниями:
SUBMITTED → WORKING → (опционально INPUT_REQUIRED → WORKING) → 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 соединяет агентов друг с другом.
Вот таблица для наглядности:
| Параметр | A2A | MCP |
|---|---|---|
| Назначение | Агент ↔ агент | Агент ↔ инструмент |
| Область | Межорганизационная, кроссплатформенная | Внутренние инструменты агента |
| Обнаружение | Agent Card (.well-known/agent.json) | Статическая конфигурация эндпоинта |
| Протокол | JSON-RPC + SSE / gRPC | JSON-RPC |
| Аутентификация | OpenAI-совместимые схемы + JWK | OAuth 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 будет единым протоколом для всех.