A2A Docs спецификация 1.0.0

Начало / Миграция с 0.3 на 1.0

Миграция с 0.3 на 1.0

Что изменилось и в каком порядке обновлять

ПереводОснова: What's New in v1.0Сверено 05.10.2026, версия 1.0.0Открыть .md

Версия 1.0 — первая стабильная версия A2A. Она делает протокол строже и понятнее, но содержит ломающие изменения во взаимодействии, поэтому код, написанный для 0.3, придётся обновить. Страница систематизирует и переводит документ «What's New in v1.0» из официальной документации.

С чего начать#

Официальная документация расставляет приоритеты так.

Приоритет Что сделать
Критично, сразу Обновить разбор частей (Part) и событий потока (способ различения типов). Обновить разбор Agent Card (структура). Добавить заголовок A2A-Version во все запросы.
Высокий, в течение месяца Перейти на курсорную пагинацию. Обновить обработку значений состояния и ролей. Добавить поддержку параметра returnImmediately.
Средний, в течение трёх месяцев Реализовать проверку подписи Agent Card. Проверять требуемые расширения. Привести временные метки к ISO 8601. Реализовать новые типы ошибок.
Низкий, по возможности Использовать расширенные метаданные. Реализовать аутентификацию mTLS.

Переименование операций#

Версия 0.3.0 Версия 1.0
message/send SendMessage
message/stream SendStreamingMessage
tasks/get GetTask
(не было) ListTasks — новая операция
tasks/cancel CancelTask
tasks/resubscribe SubscribeToTask
agent/getAuthenticatedExtendedCard GetExtendedAgentCard
tasks/pushNotificationConfig/set CreateTaskPushNotificationConfig
tasks/pushNotificationConfig/get GetTaskPushNotificationConfig
tasks/pushNotificationConfig/list ListTaskPushNotificationConfigs
tasks/pushNotificationConfig/delete DeleteTaskPushNotificationConfig

Модель запросов всех операций push-уведомлений изменилась, а TaskPushNotificationConfig стала плоской. Оригинал отмечает, что на время перехода предусмотрены псевдонимы имён операций.

Значения перечислений#

Все значения перечислений теперь записываются в стиле SCREAMING_SNAKE_CASE с префиксом типа. Так требует спецификация ProtoJSON. Это один из самых заметных ломающих изменений.

Версия 0.3.0 Версия 1.0
"submitted" "TASK_STATE_SUBMITTED"
"working" "TASK_STATE_WORKING"
"completed" "TASK_STATE_COMPLETED"
"failed" "TASK_STATE_FAILED"
"canceled" "TASK_STATE_CANCELED"
"rejected" "TASK_STATE_REJECTED"
"input-required" "TASK_STATE_INPUT_REQUIRED"
"auth-required" "TASK_STATE_AUTH_REQUIRED"
"user" "ROLE_USER"
"agent" "ROLE_AGENT"
json
// 0.3.0
{ "status": { "state": "completed", "timestamp": "2024-03-15T10:15:00Z" } }

// 1.0
{ "status": { "state": "TASK_STATE_COMPLETED", "timestamp": "2024-03-15T10:15:00.000Z" } }

Время теперь указывается строго по ISO 8601 в UTC с миллисекундами: YYYY-MM-DDTHH:mm:ss.sssZ.

Part#

Структура частей полностью переработана. Вместо отдельных TextPart, FilePart и DataPart теперь одно сообщение Part.

Что изменилось:

  • удалены отдельные типы TextPart, FilePart, DataPart;
  • удалено поле-различитель kind;
  • удалён вложенный объект file;
  • появилось единое сообщение Part с полем oneof content: тип определяется тем, какое поле есть: text, raw, url или data;
  • mediaType заменяет mimeType и доступно для всех видов частей;
  • filename доступно для всех видов частей, а не только для файлов;
  • raw — встроенное двоичное содержимое (в JSON — base64);
  • url — ссылка на файл, заменяет file.fileWithUri.
json
// 0.3.0
{ "kind": "text", "text": "Hello world" }
{ "kind": "file", "file": { "fileWithUri": "https://example.com/doc.pdf", "mimeType": "application/pdf" } }
{ "kind": "data", "data": { "key": "value" } }

// 1.0
{ "text": "Hello world", "mediaType": "text/plain" }
{ "url": "https://example.com/doc.pdf", "filename": "doc.pdf", "mediaType": "application/pdf" }
{ "data": { "key": "value" }, "mediaType": "application/json" }

Код, который определял тип по kind, нужно заменить проверкой наличия поля:

javascript
// 0.3.0
if (part.kind === "text") { return part.text; }
else if (part.kind === "file") { /* part.file.fileWithUri или fileWithBytes */ }
else if (part.kind === "data") { return part.data; }

// 1.0
if ("text" in part) { return part.text; }
else if ("url" in part) { return fetchFile(part.url); }
else if ("raw" in part) { return decodeBase64(part.raw); }
else if ("data" in part) { return part.data; }

В Message и Artifact появилось поле extensions[] с URI расширений.

События потока#

Тип события больше не определяется полем kind: его определяет имя JSON-поля-обёртки.

  • удалено поле kind;
  • удалено логическое поле final у TaskStatusUpdateEvent: завершение потока определяется механизмом закрытия потока конкретной привязки;
  • новый шаблон: тип события определяется именем члена JSON, statusUpdate или artifactUpdate.
json
// 0.3.0
{ "kind": "status-update", "taskId": "...", "contextId": "...", "status": {}, "final": true }

// 1.0
{ "statusUpdate": { "taskId": "...", "contextId": "...", "status": {} } }
javascript
// 0.3.0
if (event.kind === "status-update") { handleStatusUpdate(event); }
else if (event.kind === "artifact-update") { handleArtifactUpdate(event); }

// 1.0
if ("statusUpdate" in event) { handleStatusUpdate(event.statusUpdate); }
else if ("artifactUpdate" in event) { handleArtifactUpdate(event.artifactUpdate); }

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

Agent Card#

Структура карточки переработана: сведения об интерфейсах собраны в один список.

Что Как было в 0.3.0 Как стало в 1.0
Версия протокола protocolVersion в карточке В каждом интерфейсе: supportedInterfaces[].protocolVersion
Основной адрес url supportedInterfaces[0].url
Предпочтительный транспорт и дополнительные интерфейсы preferredTransport, additionalInterfaces Единый список supportedInterfaces[] (у каждого url, protocolBinding, protocolVersion)
Расширенная карточка supportsAuthenticatedExtendedCard в корне capabilities.extendedAgentCard
Подписи Не было Необязательное поле signatures
json
// 0.3.0
{
  "protocolVersion": "0.3",
  "url": "https://agent.example.com/a2a",
  "preferredTransport": "JSONRPC",
  "supportsAuthenticatedExtendedCard": true,
  "additionalInterfaces": [...]
}

// 1.0
{
  "supportedInterfaces": [
    { "url": "https://agent.example.com/a2a", "protocolBinding": "JSONRPC", "protocolVersion": "1.0" }
  ],
  "capabilities": { "extendedAgentCard": true },
  "signatures": [...]
}
javascript
// 0.3.0
const endpoint = agentCard.url;
const transport = agentCard.preferredTransport;
const supportsExtended = agentCard.supportsAuthenticatedExtendedCard;

// 1.0
const primaryInterface = agentCard.supportedInterfaces[0];
const endpoint = primaryInterface.url;
const transport = primaryInterface.protocolBinding;
const supportsExtended = agentCard.capabilities.extendedAgentCard;

Адрес публикации остался прежним: /.well-known/agent-card.json. Подробнее: «Agent Card».

Пагинация#

Операция ListTasks появилась только в 1.0, и она сразу курсорная. Если вы реализовывали постраничный список по-своему, перейдите на pageToken и nextPageToken:

javascript
let pageToken = undefined;
do {
  const response = await listTasks({ pageToken, pageSize: 50 });
  // обработать response.tasks
  pageToken = response.nextPageToken;
} while (pageToken);

Подробнее: «Методы».

Ошибки#

HTTP+JSON-ответы с ошибкой теперь используют ProtoJSON-представление google.rpc.Status вместо RFC 9457. Тип содержимого изменился с application/problem+json на application/json. Для ошибок A2A в details (JSON-RPC: data) ДОЛЖЕН быть объект google.rpc.ErrorInfo с полями reason и domain: "a2a-protocol.org". Примеры и список ошибок: «Ошибки».

HTTP-адреса и идентификаторы#

  • Без префикса /v1. В HTTP+JSON-привязке убран префикс /v1. Было POST /v1/message:send, стало POST /message:send и GET /tasks/{id}. Версию при необходимости владелец агента может включить в базовый адрес.
  • Простые идентификаторы. Все идентификаторы теперь простые значения. Составные идентификаторы вида tasks/{taskId} ушли: операции, где раньше использовались составные идентификаторы, теперь принимают родителя и ресурс отдельными полями. Например, tasks/{taskId}/pushNotificationConfigs/{configId} превратилось в отдельные task_id и id. Идентификаторы прямо соответствуют ключам в базе данных.

OAuth 2.0#

Поддержка OAuth 2.0 приведена в соответствие с актуальными рекомендациями по безопасности (BCP).

  • Удалены потоки: ImplicitOAuthFlow (риск утечки токена через историю и журналы браузера) и PasswordOAuthFlow (риск раскрытия учётных данных).
  • Добавлен поток: DeviceCodeOAuthFlow (RFC 8628) для консольных инструментов, IoT-устройств и сред без удобного ввода.
  • Усилена безопасность: в AuthorizationCodeOAuthFlow добавлено поле pkceRequired (RFC 7636): оно показывает, обязателен ли PKCE. PKCE рекомендуется всем OAuth-клиентам и обязателен для публичных клиентов.
json
// 0.3.0: поток implicit (теперь удалён)
{ "implicitFlow": { "authorizationUrl": "https://auth.example.com/authorize", "scopes": { "read": "Read access" } } }

// 1.0: вместо него код авторизации + PKCE
{
  "authorizationCodeFlow": {
    "authorizationUrl": "https://auth.example.com/authorize",
    "tokenUrl": "https://auth.example.com/token",
    "pkceRequired": true,
    "scopes": { "read": "Read access" }
  }
}

Что нового в 1.0#

  • Новая операция ListTasks с фильтрацией и курсорной пагинацией.
  • Мультитенантность. Поле tenant во всех запросах и в AgentInterface: так можно обслуживать несколько агентов с одной точки входа.
  • Режим выполнения. Параметр returnImmediately в SendMessageConfiguration: ждать завершения задачи (по умолчанию) или вернуться сразу.
  • Подпись Agent Card. JWS и каноническая форма JSON (RFC 8785).
  • Требуемые расширения. Расширение в Agent Card можно пометить как обязательное (required).
  • Согласование версий. Заголовок A2A-Version и версия протокола в каждом интерфейсе.
  • Взаимная аутентификация TLS. Объявление схемы mTLS среди схем безопасности.
  • Новые зависимости. google.rpc.Status и ErrorInfo, RFC 8785, RFC 7515, руководства по проектированию API Google и ISO 8601.

Порядок миграции#

Оригинал советует мигрировать поэтапно.

  1. Слой совместимости. Научитесь разбирать оба шаблона различения типов (старый и новый), определять версию протокола и поддерживать обе структуры Agent Card на время перехода.
  2. Двойная поддержка. Переведите все API на выдачу формата 1.0, оставив читателей для 0.3.0. Добавьте обработку заголовка A2A-Version и курсорную пагинацию рядом со старой постраничной.
  3. Только 1.0. Уберите код совместимости с 0.3.0: старый разбор различителей, постраничную выдачу и поддержку двух форматов.

Стратегия обратной совместимости#

Каждый интерфейс (AgentInterface) объявляет собственную версию протокола. Агент может поддерживать несколько версий одновременно, открыв несколько интерфейсов. Клиент выбирает подходящий интерфейс из Agent Card, а SDK могут поддерживать несколько версий протокола и постепенно отказываться от старых.

Что проверить тестами#

  • работу с данными и формата 0.3.0, и формата 1.0;
  • проверку подписи Agent Card;
  • курсорную пагинацию в крайних случаях: пустой результат, единственная страница;
  • обработку новых типов ошибок;
  • проверку требуемых расширений.

Расхождения внутри оригинала#

Пока мы сверяли источники, нашлись места, где документы описывают одно и то же по-разному. Это не ошибки перевода; сверяйтесь с a2a.proto.

  • У события TaskArtifactUpdateEvent на странице «What's New» есть поле index, а в таблице спецификации (раздел 4.2.2) его нет.
  • Примеры заголовка A2A-Version в разных местах спецификации показывают разные значения.
  • Для требований безопасности Agent Card встречаются два названия: security и security_requirements.