这是用户在 2025-6-26 19:58 为 https://a2aproject.github.io/A2A/latest/specification/ 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?
Skip to content

Agent2Agent (A2A) 协议规范

版本:local-dev

1. 简介

Agent2Agent (A2A) 协议是一种开放标准,旨在促进独立、可能不透明的 AI 代理系统之间的通信和互作性。在代理可能使用不同的框架、语言或由不同供应商构建的生态系统中,A2A 提供了通用语言和交互模型。

本文档提供了 A2A 协议的详细技术规范。其主要目标是使代理能够:

  • 发现彼此的能力。
  • 协商交互方式(文本、文件、结构化数据)。
  • 管理协作任务。
  • 安全地交换信息以实现用户目标, 而无需访问彼此的内部状态、内存或工具。

1.1. A2A 的主要目标

  • 互作性: 弥合不同代理系统之间的通信鸿沟。
  • 协作: 使代理能够委派任务、交换上下文并共同处理复杂的用户请求。
  • 发现: 允许代理动态查找和了解其他代理的功能。
  • 灵活性: 支持多种交互模式,包括同步请求/响应、实时更新的流式处理和长时间运行任务的异步推送通知。
  • 安全: 依靠标准的 Web 安全实践,促进适合企业环境的安全通信模式。
  • 异步性: 本机支持可能涉及人机协同方案的长时间运行的任务和交互。

1.2. 指导原则

  • 简单: 重用现有的、易于理解的标准(HTTP、JSON-RPC 2.0、服务器发送的事件)。
  • 企业就绪: 通过与既定的企业实践保持一致,解决身份验证、授权、安全性、隐私、跟踪和监控问题。
  • 异步优先: 专为(可能非常)长时间运行的任务和人机交互而设计。
  • 模态不可知论: 支持交换各种内容类型,包括文本、音频/视频(通过文件引用)、结构化数据/表单和可能嵌入的 UI 组件(例如,部分中引用的 iframe)。
  • 不透明执行: 座席根据声明的功能和交换的信息进行协作,而无需分享他们的内部想法、计划或工具实施。

要更广泛地了解 A2A 的用途和优势,请参阅什么是 A2A?

2. 核心概念总结

A2A 围绕几个关键概念展开。有关详细说明,请参阅 关键概念 指南

  • A2A 客户: 代表用户或其他系统向 A2A 服务器发起请求的应用程序或代理。
  • A2A 服务器(远程代理): 一个代理或代理系统,用于公开符合 A2A 标准的 HTTP 端点,处理任务并提供响应。
  • 代理卡: 由 A2A 服务器发布的 JSON 元数据文档,描述其身份、功能、技能、服务终端节点和身份验证要求。
  • 消息: 客户端和远程代理之间的通信轮次,具有角色 (“user” 或 “agent”) 并包含一个或多个 Part
  • 任务: 由 A2A 管理的基本工作单元,由唯一 ID 标识。任务是有状态的,并在定义的生命周期中进行。
  • 部分:Message 或 Artifact 中的最小内容单位(例如 TextPartFilePartDataPart)。
  • 人工制品: 代理作为任务的结果生成的输出(例如,文档、图像、结构化数据),由 Parts 组成。
  • 流式处理 (SSE): 通过 Server-Sent Events 交付的任务(状态更改、构件块)的实时增量更新。
  • 推送通知: 通过服务器发起的 HTTP POST 请求向客户端提供的 Webhook URL 传递异步任务更新,适用于长时间运行或断开连接的场景。
  • 上下文: 一个可选的、服务器生成的标识符,用于对相关任务进行逻辑分组。
  • 外延: 一种机制,供代理提供核心 A2A 规范之外的其他功能或数据。

3. 传输和格式化

3.1. 传输协议

  • A2A 通信必须通过 HTTP(S) 进行。
  • A2A 服务器在其 AgentCard 中定义的 URL 上公开其服务。

3.2. 数据格式

A2A 使用 JSON-RPC 2.0 作为所有请求和响应(不包括 SSE 流包装器)的有效负载格式。

  • 客户端请求和服务器响应必须符合 JSON-RPC 2.0 规范。
  • 包含 JSON-RPC 负载的 HTTP 请求和响应的 Content-Type 标头必须是 application/json

3.3. 流传输(服务器发送的事件)

当 streaming 用于 message/streamtasks/resubscribe 等方法时:

  • 服务器使用 HTTP 200 OK 状态和 text/event-stream 的 Content-Type 标头进行响应。
  • 此 HTTP 响应的正文包含 W3C 定义的服务器发送事件 (SSE) 流。
  • 每个 SSE 数据字段都包含一个完整的 JSON-RPC 2.0 响应对象(具体来说,是 SendStreamingMessageResponse)。

4. 认证和授权

A2A 将代理视为标准的企业应用程序,依赖于已建立的 Web 安全实践。身份信息不会在 A2A JSON-RPC 负载中传输;它在 HTTP 传输层进行处理。

有关企业安全方面的全面指南,请参阅 Enterprise-Ready 功能

4.1. 传输安全

如第 3.1 节所述,生产部署必须使用 HTTPS。实现使用具有强密码套件的现代 TLS 配置(建议使用 TLS 1.2+)。

4.2. 服务器身份验证

A2A 客户端应在 TLS 握手期间根据受信任的证书颁发机构 (CA) 验证其 TLS 证书,以验证 A2A 服务器的身份。

4.3. 客户端/用户身份和身份验证过程

  1. 发现需求: 客户端通过 AgentCard 中的 authentication 字段发现服务器所需的身份验证方案。方案名称通常与 OpenAPI 身份验证方法一致(例如,“Bearer” 表示 OAuth 2.0 令牌,“Basic” 表示基本身份验证,“ApiKey” 表示 API 密钥)。
  2. 凭证获取(带外): 客户端通过特定于所需身份验证方案和身份提供商的带外过程获取必要的凭证(例如 API 密钥、OAuth 令牌、JWT)。此过程超出了 A2A 协议本身的范围。
  3. 凭证传输: 客户端将这些凭证包含在发送到服务器的每个 A2A 请求的相应 HTTP 标头 (例如,Authorization: Bearer <token>X-API-Key: <value>)中。

4.4. 服务器身份验证责任

A2A 服务器:

  • 必须根据提供的 HTTP 凭据及其从代理卡声明的身份验证要求对每个传入请求进行身份验证。
  • 使用标准 HTTP 状态代码(例如 401 未授权403 禁止 )进行身份验证质询或拒绝。
  • 包含相关的 HTTP 标头(例如 WWW-Authenticate)以及 401 Unauthorized 响应,以指明所需的身份验证方案,从而为客户端提供指导。

4.5. 任务内身份验证(辅助凭证)

如果代理在执行任务期间需要其他系统或资源的额外凭证(例如,代表需要自己身份验证的用户访问特定工具):

  1. 应该将 A2A 任务转换为 auth-required 状态(请参阅 TaskState)。
  2. 随附的 TaskStatus.message(通常是 DataPart提供有关所需辅助身份验证的详细信息,可能使用类似 PushNotificationAuthenticationInfo -的结构来描述需求。
  3. 然后,A2A 客户端在带外获取这些新凭证,并在后续的消息/发送消息/流请求中提供它们。如何使用这些凭证(例如,如果代理正在代理,则作为 A2A 消息中的数据传递,或者由客户端用于直接与辅助系统交互)取决于具体场景。

4.6. 授权

客户端通过身份验证后,A2A 服务器负责根据经过身份验证的客户端/用户身份及其自己的策略授权请求。授权逻辑是特定于实现的,并且可以根据以下条件强制执行:

  • 请求的特定技能(例如,由代理卡中的 AgentSkill.id 确定的技能)。
  • 在任务中尝试的作。
  • 与代理管理的资源相关的数据访问策略。
  • 与提供的令牌关联的 OAuth 范围(如果适用)。

服务器应实施最小权限原则。

5. 代理发现:代理卡

5.1. 目的

A2A 服务器必须提供代理卡。代理卡是一个 JSON 文档,用于描述服务器的身份、功能、技能、服务端点 URL 以及客户端应如何进行身份验证和与之交互。客户端使用此信息来发现合适的座席并配置其交互。

有关发现策略的更多信息,请参阅代理发现指南

5.2. 发现机制

客户可以通过多种方式找到代理卡,包括但不限于:

  • 已知 URI: 访问代理域上的预定义路径(请参阅 第 5.3 节 )。
  • 注册表/目录: 查询代理的精选目录或注册表(可能是特定于企业的、公共的或特定于域的)。
  • 直接配置: 客户端可以预先配置代理卡 URL 或卡内容本身。

如果使用已知的 URI 策略,则代理的代理卡的建议位置为: https://{server_domain}/.well-known/agent.json 这遵循了 RFC 8615 对已知 URI 的原则。

5.4. 代理卡的安全性

代理卡本身可能包含被视为敏感信息的信息。

  • 如果代理卡包含敏感信息,则为该卡提供服务的端点必须受到适当的访问控制(例如,mTLS、网络限制、获取卡所需的身份验证)的保护。
  • 通常不建议直接在代理卡中包含纯文本密钥(如静态 API 密钥)。首选客户端在带外获取动态凭据的身份验证方案。

5.5. AgentCard 对象结构

/**
 * An AgentCard conveys key information:
 * - Overall details (version, name, description, uses)
 * - Skills: A set of capabilities the agent can perform
 * - Default modalities/content types supported by the agent.
 * - Authentication requirements
 */
export interface AgentCard {
  /**
   * Human readable name of the agent.
   * @example "Recipe Agent"
   */
  name: string;
  /**
   * A human-readable description of the agent. Used to assist users and
   * other agents in understanding what the agent can do.
   * @example "Agent that helps users with recipes and cooking."
   */
  description: string;
  /**
   * A URL to the address the agent is hosted at. This represents the
   * preferred endpoint as declared by the agent.
   */
  url: string;
  /**
   * The transport of the preferred endpoint. If empty, defaults to JSONRPC.
   */
  preferredTransport?: string;
  /**
   * Announcement of additional supported transports. Client can use any of
   * the supported transports.
   */
  additionalInterfaces?: AgentInterface[];
  /** A URL to an icon for the agent. */
  iconUrl?: string;
  /** The service provider of the agent */
  provider?: AgentProvider;
  /**
   * The version of the agent - format is up to the provider.
   * @example "1.0.0"
   */
  version: string;
  /** A URL to documentation for the agent. */
  documentationUrl?: string;
  /** Optional capabilities supported by the agent. */
  capabilities: AgentCapabilities;
  /** Security scheme details used for authenticating with this agent. */
  securitySchemes?: { [scheme: string]: SecurityScheme };
  /** Security requirements for contacting the agent. */
  security?: { [scheme: string]: string[] }[];
  /**
   * The set of interaction modes that the agent supports across all skills. This can be overridden per-skill.
   * Supported media types for input.
   */
  defaultInputModes: string[];
  /** Supported media types for output. */
  defaultOutputModes: string[];
  /** Skills are a unit of capability that an agent can perform. */
  skills: AgentSkill[];
  /**
   * true if the agent supports providing an extended agent card when the user is authenticated.
   * Defaults to false if not specified.
   */
  supportsAuthenticatedExtendedCard?: boolean;
}
字段名称 类型 必填 描述
name string 是的 代理的可读名称。
description string 是的 人类可读的描述。 通用标志可能使用。
url string 是的 代理的 A2A 服务的基 URL。必须是绝对的。用于生产的 HTTPS。
provider AgentProvider 有关代理提供商的信息。
iconUrl string 代理图标的 URL。
version string 是的 代理或 A2A 实现版本字符串。
documentationUrl string 代理的人类可读文档的 URL。
capabilities AgentCapabilities 是的 指定支持的可选 A2A 协议功能(例如,流式处理、推送通知)。
securitySchemes { [scheme: string]: SecurityScheme } 用于使用此代理进行身份验证的安全方案详细信息。undefined 表示没有 A2A 通告的身份验证(不建议用于生产)。
security { [scheme: string]: string[]; }[] 联系代理的安全要求。
defaultInputModes string[] 是的 输入代理接受的媒体类型。
defaultOutputModes string[] 是的 代理生成的 Output Media Types。
skills AgentSkill[] 是的 一系列技能。如果代理执行作,则必须至少有一个。
supportsAuthenticatedExtendedCard boolean 表示支持通过经过身份验证的终端节点检索更详细的代理卡。

5.5.1. AgentProvider 对象

有关提供代理的组织或实体的信息。

/**
 * Represents the service provider of an agent.
 */
export interface AgentProvider {
  /** Agent provider's organization name. */
  organization: string;
  /** Agent provider's URL. */
  url: string;
}
字段名称 类型 必填 描述
organization string 是的 组织/实体的名称。
url string 是的 提供商的网站/联系人的 URL。

5.5.2. AgentCapabilities 对象

指定代理支持的可选 A2A 协议功能。

/**
 * Defines optional capabilities supported by an agent.
 */
export interface AgentCapabilities {
  /** true if the agent supports SSE. */
  streaming?: boolean;
  /** true if the agent can notify updates to client. */
  pushNotifications?: boolean;
  /** true if the agent exposes status change history for tasks. */
  stateTransitionHistory?: boolean;
  /** extensions supported by this agent. */
  extensions?: AgentExtension[];
}
字段名称 类型 必填 违约 描述
streaming boolean false 表示支持 SSE 流式处理方法 (message/streamtasks/resubscribe)。
pushNotifications boolean false 表示支持推送通知方法 ( tasks/pushNotificationConfig/* )。
stateTransitionHistory boolean false 未来功能的占位符:公开详细的任务状态更改历史记录。
extensions 代理扩展 [] 此代理支持的扩展列表。

5.5.2.1. AgentExtension 对象

指定代理支持的 A2A 协议的扩展。

/**
 * A declaration of an extension supported by an Agent.
 */
export interface AgentExtension {
  /** The URI of the extension. */
  uri: string;
  /** A description of how this agent uses this extension. */
  description?: string;
  /** Whether the client must follow specific requirements of the extension. */
  required?: boolean;
  /** Optional configuration for the extension. */
  params?: { [key: string]: any };
}
字段名称 类型 必填 描述
uri string 是的 受支持扩展的 URI。
required boolean 代理是否要求客户端遵循特定于扩展的某些协议逻辑。当尝试与需要客户端不支持的扩展的服务器交互时,客户端应该会失败。
description string 代理如何使用扩展的描述。
params object 特定于扩展的配置参数

5.5.3. SecurityScheme 对象

描述访问代理的 url 端点的身份验证要求。有关示例,请参阅 Sample Agent Card

/**
 * Mirrors the OpenAPI Security Scheme Object
 * (https://swagger.io/specification/#security-scheme-object)
 */
export type SecurityScheme =
  | APIKeySecurityScheme
  | HTTPAuthSecurityScheme
  | OAuth2SecurityScheme
  | OpenIdConnectSecurityScheme;

5.5.4. AgentSkill 对象

描述代理可以执行或解决的特定能力、功能或专业领域。

/**
 * Represents a unit of capability that an agent can perform.
 */
export interface AgentSkill {
  /** Unique identifier for the agent's skill. */
  id: string;
  /** Human readable name of the skill. */
  name: string;
  /**
   * Description of the skill - will be used by the client or a human
   * as a hint to understand what the skill does.
   */
  description: string;
  /**
   * Set of tagwords describing classes of capabilities for this specific skill.
   * @example ["cooking", "customer support", "billing"]
   */
  tags: string[];
  /**
   * The set of example scenarios that the skill can perform.
   * Will be used by the client as a hint to understand how the skill can be used.
   * @example ["I need a recipe for bread"]
   */
  examples?: string[]; // example prompts for tasks
  /**
   * The set of interaction modes that the skill supports
   * (if different than the default).
   * Supported media types for input.
   */
  inputModes?: string[];
  /** Supported media types for output. */
  outputModes?: string[];
}
字段名称 类型 必填 描述
id string 是的 此代理中的唯一技能标识符。
name string 是的 人类可读的技能名称。
description string 是的 详细的技能描述。 通用标志可能使用。
tags string[] 是的 用于可发现性的关键字/类别。
examples string[] 演示技能用法的示例提示或使用案例。
inputModes string[] 覆盖此特定技能的 defaultInputModes。接受的媒体类型。
outputModes string[] 覆盖此特定技能的 defaultOutputModes。生成的媒体类型。

5.6. 样本 Agent 卡

{
  "name": "GeoSpatial Route Planner Agent",
  "description": "Provides advanced route planning, traffic analysis, and custom map generation services. This agent can calculate optimal routes, estimate travel times considering real-time traffic, and create personalized maps with points of interest.",
  "url": "https://georoute-agent.example.com/a2a/v1",
  "provider": {
    "organization": "Example Geo Services Inc.",
    "url": "https://www.examplegeoservices.com"
  },
  "iconUrl": "https://georoute-agent.example.com/icon.png",
  "version": "1.2.0",
  "documentationUrl": "https://docs.examplegeoservices.com/georoute-agent/api",
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "stateTransitionHistory": false
  },
  "securitySchemes": {
    "google": {
      "type": "openIdConnect",
      "openIdConnectUrl": "https://accounts.google.com/.well-known/openid-configuration"
    }
  },
  "security": [{ "google": ["openid", "profile", "email"] }],
  "defaultInputModes": ["application/json", "text/plain"],
  "defaultOutputModes": ["application/json", "image/png"],
  "skills": [
    {
      "id": "route-optimizer-traffic",
      "name": "Traffic-Aware Route Optimizer",
      "description": "Calculates the optimal driving route between two or more locations, taking into account real-time traffic conditions, road closures, and user preferences (e.g., avoid tolls, prefer highways).",
      "tags": ["maps", "routing", "navigation", "directions", "traffic"],
      "examples": [
        "Plan a route from '1600 Amphitheatre Parkway, Mountain View, CA' to 'San Francisco International Airport' avoiding tolls.",
        "{\"origin\": {\"lat\": 37.422, \"lng\": -122.084}, \"destination\": {\"lat\": 37.7749, \"lng\": -122.4194}, \"preferences\": [\"avoid_ferries\"]}"
      ],
      "inputModes": ["application/json", "text/plain"],
      "outputModes": [
        "application/json",
        "application/vnd.geo+json",
        "text/html"
      ]
    },
    {
      "id": "custom-map-generator",
      "name": "Personalized Map Generator",
      "description": "Creates custom map images or interactive map views based on user-defined points of interest, routes, and style preferences. Can overlay data layers.",
      "tags": ["maps", "customization", "visualization", "cartography"],
      "examples": [
        "Generate a map of my upcoming road trip with all planned stops highlighted.",
        "Show me a map visualizing all coffee shops within a 1-mile radius of my current location."
      ],
      "inputModes": ["application/json"],
      "outputModes": [
        "image/png",
        "image/jpeg",
        "application/json",
        "text/html"
      ]
    }
  ],
  "supportsAuthenticatedExtendedCard": true
}

6. 协议数据对象

这些对象定义了在 A2A 协议的 JSON-RPC 方法中交换的数据的结构。

6.1. Task 对象

表示 A2A 服务器为 A2A 客户端处理的有状态工作单元。任务封装了与特定目标或请求相关的整个交互。已达到最终状态(已完成、已取消、已拒绝或失败)的任务无法重新启动。有关更多信息,请参阅任务生命周期指南

export interface Task {
  /** Unique identifier for the task */
  id: string;
  /** Server-generated id for contextual alignment across interactions */
  contextId: string;
  /** Current status of the task */
  status: TaskStatus;
  history?: Message[];
  /** Collection of artifacts created by the agent. */
  artifacts?: Artifact[];
  /** Extension metadata. */
  metadata?: {
    [key: string]: any;
  };
  /** Event type */
  kind: "task";
}
字段名称 类型 必填 描述
id string 是的 服务器生成的唯一任务标识符(例如 UUID)
contextId string 是的 服务器生成的 ID,用于跨交互的上下文对齐
status TaskStatus 是的 任务的当前状态(状态、消息、时间戳)。
artifacts Artifact[] 代理为此任务生成的输出数组。
history Message[] 最近交换的消息的可选数组(如果由 historyLength 请求)。
metadata Record<string, any> 与任务关联的任意键值元数据。
kind "task" 是的 类型鉴别器,文本值

6.2. TaskStatus 对象

表示 Task 的当前状态和关联的上下文(例如,来自代理的消息)。

/** TaskState and accompanying message. */
export interface TaskStatus {
  state: TaskState;
  /** Additional status updates for client */
  message?: Message;
  /**
   * ISO 8601 datetime string when the status was recorded.
   * @example "2023-10-27T10:00:00Z"
   * */
  timestamp?: string;
}
字段名称 类型 必填 描述
state TaskState 是的 任务的当前生命周期状态。
message Message 提供当前状态上下文的可选消息。
timestamp 字符串 (ISO 8601) 记录此状态时的时间戳(建议使用 UTC)。

6.3. TaskState 枚举

定义 Task 的可能生命周期状态。

/** Represents the possible states of a Task. */
export enum TaskState {
  Submitted = "submitted",
  Working = "working",
  InputRequired = "input-required",
  Completed = "completed",
  Canceled = "canceled",
  Failed = "failed",
  Rejected = "rejected",
  AuthRequired = "auth-required",
  Unknown = "unknown",
}
价值 描述 终端?
submitted 服务器已收到任务并已确认,但处理尚未主动启动。
working 代理正在主动处理任务。客户端可能会期待进一步的更新或终端状态。
input-required 代理需要客户端/用户的其他输入才能继续。任务实际上已暂停。 否 (暂停)
completed 任务已成功完成。结果通常位于 Task.artifactsTaskStatus.message 中。 是的
canceled 任务已取消(例如,通过 tasks/cancel 请求或服务器端策略)。 是的
failed 任务因处理过程中的错误而终止。TaskStatus.message 可能包含错误详细信息。 是的
rejected 任务因远程代理拒绝而终止。TaskStatus.message 可能包含错误详细信息。 是的
auth-required 代理需要客户端/用户进行其他身份验证才能继续。任务实际上已暂停。 否 (暂停)
unknown 无法确定任务的状态(例如,任务 ID 无效、未知或已过期)。 是的

6.4. 消息对象

表示客户端和代理之间的单个通信轮次或一段上下文信息。消息用于说明、提示、回复和状态更新。

/** Represents a single message exchanged between user and agent. */
export interface Message {
  /** Message sender's role */
  role: "user" | "agent";
  /** Message content */
  parts: Part[];
  /** Extension metadata. */
  metadata?: {
    [key: string]: any;
  };
  /** The URIs of extensions that are present or contributed to this Message. */
  extensions?: string[];
  /** List of tasks referenced as context by this message.*/
  referenceTaskIds?: string[];
  /** Identifier created by the message creator*/
  messageId: string;
  /** Identifier of task the message is related to */
  taskId?: string;
  /** The context the message is associated with */
  contextId?: string;
  /** Event type */
  kind: "message";
}
字段名称 类型 必填 描述
role “用户” |“代理” 是的 指示发件人:“user”( 来自 A2A 客户端)或 “agent”( 来自 A2A 服务器)。
parts Part[] 是的 内容部分数组。必须至少包含一个部分。
metadata Record<string, any> 与此消息关联的任意键值元数据。
extensions string[] 促成此消息的扩展 URI 的列表。
referenceTaskIds string[] 此消息作为上下文提示引用的任务列表。
messageId string 是的 消息发件人生成的消息标识符
taskId string 当前消息与之相关的任务标识符
contextId string 消息与之关联的上下文标识符
kind "message" 是的 类型鉴别器,文本值

6.5. 部分联合体类型

表示 MessageArtifact 中的不同内容。Part 是一种联合类型,将可导出内容表示为 TextPartFilePartDataPart。所有部件类型还包括一个可选的元数据字段 (Record<string, any>),用于特定于部件的元数据。

/** Represents a part of a message, which can be text, a file, or structured data. */
export type Part = TextPart | FilePart | DataPart;

必须是以下值之一:

6.5.1. TextPart 对象

用于传达纯文本内容。

/** Represents a text segment within parts.*/
export interface TextPart extends PartBase {
  /** Part type - text for TextParts*/
  kind: "text";
  /** Text content */
  text: string;
}
字段名称 类型 必填 描述
kind “text” (文本) 是的 将此部分标识为文本内容。
text string 是的 零件的文本内容。
metadata Record<string, any> 特定于此文本部分的可选元数据。

6.5.2. FilePart 对象

用于传送基于文件的内容。

/** Represents a File segment within parts.*/
export interface FilePart extends PartBase {
  /** Part type - file for FileParts */
  kind: "file";
  /** File content either as url or bytes */
  file: FileWithBytes | FileWithUri;
}
字段名称 类型 必填 描述
kind “file” (文字) 是的 将此部分标识为文件内容。
file 带字节的文件 |FileWithUri 文件 是的 包含文件详细信息和 data/reference。
metadata Record<string, any> 特定于此文件部分的可选元数据。

6.5.3. DataPart 对象

用于传输结构化 JSON 数据。对于表单、参数或任何机器可读的信息很有用。

/** Represents a structured data segment within a message part. */
export interface DataPart extends PartBase {
  /** Part type - data for DataParts */
  kind: "data";
  /** Structured data content
   */
  data: {
    [key: string]: any;
  };
}
字段名称 类型 必填 描述
kind “data” (文字) 是的 将此部分标识为结构化数据。
data Record<string, any> 是的 结构化 JSON 数据负载(对象或数组)。
metadata Record<string, any> 特定于此数据部分的可选元数据(例如,对架构的引用)。

6.6.1 FileWithBytes 对象

表示在 FilePart 中使用的文件的数据。

/** Define the variant where 'bytes' is present and 'uri' is absent */
export interface FileWithBytes extends FileBase {
  /** base64 encoded content of the file*/
  bytes: string;
  uri?: never;
}
字段名称 类型 必填 描述
name string 原始文件名(例如,“report.pdf”)。
mimeType string 媒体类型 (例如,image/png)。强烈推荐。
bytes string 是的 Base64 编码的文件内容。

6.6.2 FileWithUri 对象

表示在 FilePart 中使用的文件的 URI。

/** Define the variant where 'uri' is present and 'bytes' is absent  */
export interface FileWithUri extends FileBase {
  /** URL for the File content */
  uri: string;
  bytes?: never;
}
字段名称 类型 必填 描述
name string 原始文件名(例如,“report.pdf”)。
mimeType string 媒体类型 (例如,image/png)。强烈推荐。
uri string 是的 URI(强烈建议使用绝对 URL)来文件内容。辅助功能取决于上下文。

6.7. artifact 对象

表示代理在任务期间生成的有形输出。工件是代理工作的结果或产品。

/** Represents an artifact generated for a task. */
export interface Artifact {
  /** Unique identifier for the artifact. */
  artifactId: string;
  /** Optional name for the artifact. */
  name?: string;
  /** Optional description for the artifact. */
  description?: string;
  /** Artifact parts. */
  parts: Part[];
  /** Extension metadata. */
  metadata?: {
    [key: string]: any;
  };
  /** The URIs of extensions that are present or contributed to this Artifact. */
  extensions?: string[];
}
字段名称 类型 必填 描述
artifactId string 是的 代理生成的项目的标识符。
name string 对象的描述性名称。
description string 对象的可读描述。
parts Part[] 是的 对象的内容,作为一个或多个 Part 对象。必须至少有一个。
metadata Record<string, any> 与构件关联的任意键值元数据。
extensions string[] 促成此构件的扩展 URI 的列表。

6.8. PushNotificationConfig 对象

客户端提供给服务器的配置,用于发送有关任务更新的异步推送通知。

/**Configuration for setting up push notifications for task updates. */
export interface PushNotificationConfig {
  /** Push Notification ID - created by server to support multiple callbacks */
  id?: string;
  /** URL for sending the push notifications. */
  url: string;
  /** Token unique to this task/session. */
  token?: string;
  authentication?: PushNotificationAuthenticationInfo;
}
字段名称 类型 必填 描述
url string 是的 要 POST 任务更新的 A2A 服务器 URL 的绝对 HTTPS webhook URL。
token string 客户端的 Webhook 接收器用于验证通知的可选客户端生成的不透明令牌(例如,服务器将其包含在 X-A2A-Notification-Token 标头中)。
authentication PushNotificationAuthenticationInfo A2A 服务器在调用 url 时必须使用的身份验证详细信息。客户端的 Webhook(接收方)定义了这些要求。

6.9. PushNotificationAuthenticationInfo 对象

用于指定身份验证要求的通用结构,通常在 PushNotificationConfig 中使用,用于描述 A2A 服务器应如何对客户端的 Webhook 进行身份验证。

/** Defines authentication details for push notifications. */
export interface PushNotificationAuthenticationInfo {
  /** Supported authentication schemes - e.g. Basic, Bearer */
  schemes: string[];
  /** Optional credentials */
  credentials?: string;
}
字段名称 类型 必填 描述
schemes string[] 是的 A2A 服务器在调用客户端的 webhook 时必须使用的身份验证方案名称数组(例如,“Bearer”、“ApiKey”)。
credentials string 可选的静态凭证或特定于方案的配置信息。 如果涉及密钥,请极其小心地处理。 尽可能首选服务器端动态凭证获取。

6.10. 关于 TaskPushNotificationConfig 对象

用作方法的 tasks/pushNotificationConfig/set params 对象和 tasks/pushNotificationConfig/get 方法的 result 对象。

/**Parameters for setting or getting push notification configuration for a task */
export interface TaskPushNotificationConfig {
  /** Task id. */
  taskId: string;
  /** Push notification configuration. */
  pushNotificationConfig: PushNotificationConfig;
}
字段名称 类型 必填 描述
taskId string 是的 要为其配置推送通知或从中检索配置的任务的 ID。
pushNotificationConfig PushNotificationConfig 是的 推送通知配置。对于 set,所需的配置。对于 get,当前配置(服务器可以省略 secret)。

6.11. JSON-RPC 结构

A2A 遵循标准的 JSON-RPC 2.0 请求和响应结构。

6.11.1. JSONRPCRequest 对象

所有 A2A 方法调用都封装在 JSON-RPC Request 对象中。

  • jsonrpc:一个 String,用于指定 JSON-RPC 协议的版本。 必须正好为 “2.0”。
  • method:一个 String,其中包含要调用的方法的名称(例如,“message/send”、“tasks/get”)。
  • params:一个 Structured 值,用于保存要在方法调用期间使用的参数值。如果方法不需要任何参数,则可以省略此成员。A2A 方法通常将对象用于参数
  • id:客户端建立的标识符, 必须包含 String、Number 或 NULL 值(如果包含)。如果未包含,则假定为通知。对于需要响应的请求,该值不应NULL,并且 Numbers 不应包含小数部分。服务器必须在 Response 对象中使用相同的值(如果包含)进行回复。此成员用于关联两个对象之间的上下文。A2A 方法通常需要响应或流,因此 id 通常存在且非 null。

6.11.2. JSONRPCResponse 对象

来自 A2A 服务器的响应封装在 JSON-RPC Response 对象中。

  • jsonrpc:一个 String,用于指定 JSON-RPC 协议的版本。 必须正好为 “2.0”。
  • id:此成员为必填 。它必须与请求对象中 id 成员的值相同。如果在 Request 对象中检测 id 时出错(例如解析错误/无效请求),则它必须null
  • 任一结果 :成功时需要此成员。如果调用该方法时出错,则此成员不得存在。此成员的值由在 Server 上调用的方法确定。
  • OR 错误 :此成员在失败时是必需的 。如果在调用期间没有触发错误,则此成员不得存在。此成员的值必须是 JSONRPCError 对象。
  • 成员 resulterror 是互斥的:一个 MUST be 存在,另一个 MUST NOT

6.12. JSONRPCError 对象

当 JSON-RPC 调用遇到错误时,响应对象将包含值为该结构的错误成员。

/**
 * Represents a JSON-RPC 2.0 Error object.
 * This is typically included in a JSONRPCErrorResponse when an error occurs.
 */
export interface JSONRPCError {
  /**
   * A Number that indicates the error type that occurred.
   */
  code: number;

  /**
   * A String providing a short description of the error.
   */
  message: string;

  /**
   * A Primitive or Structured value that contains additional information about the error.
   * This may be omitted.
   */
  data?: any;
}
字段名称 类型 必填 描述
code integer 是的 整数错误代码。请参阅第 8 节(错误处理), 了解标准代码和 A2A 特定代码。
message string 是的 简短、可读的错误摘要。
data any 有关错误的可选附加结构化信息。

7. 协议 RPC 方法

所有 A2A RPC 方法都由 A2A 客户端通过向 A2A 服务器的 url(如其 AgentCard 中指定)发送 HTTP POST 请求来调用。HTTP POST 请求的正文必须是 JSONRPCRequest 对象,并且 Content-Type 标头必须是 application/json

A2A 服务器的 HTTP 响应正文必须是 JSONRPCResponse 对象(或者,对于流式处理方法,每个事件的数据都是 JSONRPCResponse 的 SSE 流)。JSON-RPC 响应的 Content-Typeapplication/json。对于 SSE 流,它是 text/event-stream

7.1. 消息/发送

向座席发送消息以启动新交互或继续现有交互。此方法适用于同步请求/响应交互,或者当客户端轮询(使用 tasks/get)可用于监控运行时间较长的任务时。已达到最终状态(已完成、已取消、已拒绝或失败)的任务无法重新启动。向此类任务发送消息将导致错误。有关更多信息,请参阅任务生命周期指南

7.1.1. MessageSendParams 对象

/** Sent by the client to the agent as a request. May create, continue or restart a task. */
export interface MessageSendParams {
  /** The message being sent to the server. */
  message: Message;
  /** Send message configuration. */
  configuration?: MessageSendConfiguration;
  /** Extension metadata. */
  metadata?: {
    [key: string]: any;
  };
}

/**Configuration for the send message request. */
export interface MessageSendConfiguration {
  /** Accepted output modalities by the client. */
  acceptedOutputModes: string[];
  /** Number of recent messages to be retrieved. */
  historyLength?: number;
  /** Where the server should send notifications when disconnected. */
  pushNotificationConfig?: PushNotificationConfig;
  /** If the server should treat the client as a blocking request. */
  blocking?: boolean;
}
字段名称 类型 必填 描述
message Message 是的 要发送的消息内容。Message.role 通常是 “user”
configuration MessageSendConfiguration 可选:其他消息配置
metadata Record<string, any> 特定于请求的元数据。

7.2. 消息/流

向代理发送消息以启动/继续任务,并通过服务器发送事件 (SSE) 为客户端订阅该任务的实时更新。此方法要求服务器具有 AgentCard.capabilities.streaming: true 。与 message/send 一样,已达到最终状态(已完成、已取消、已拒绝或失败)的任务无法重新启动。向此类任务发送消息将导致错误。有关更多信息,请参阅任务生命周期指南

  • 请求参数类型 MessageSendParams(与 message/send 相同)。
  • 响应(成功订阅时):
    • HTTP 状态:200 正常
    • HTTP 内容类型 text/event-stream
    • HTTP Body:服务器发送的事件流。每个 SSE 数据字段都包含一个 SendStreamingMessageResponse JSON 对象。
  • 响应(初始订阅失败时):
    • 标准 HTTP 错误代码(例如 4xx、5xx)。
    • HTTP 正文可以包含标准 JSONRPCResponse,其中包含详细说明失败的错误对象。

7.2.1. SendStreamingMessageResponse 对象

这是在服务器为 message/stream 请求或 tasks/resubscribe 请求发送的每个 Server-Sent Event 的 data 字段中找到的 JSON 对象的结构。

/**
 * JSON-RPC response model for the 'message/stream' method.
 */
export type SendStreamingMessageResponse =
  | SendStreamingMessageSuccessResponse
  | JSONRPCErrorResponse;

/**
 * JSON-RPC success response model for the 'message/stream' method.
 */
export interface SendStreamingMessageSuccessResponse
  extends JSONRPCSuccessResponse {
  result: Message | Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent;
}
字段名称 类型 必填 描述
jsonrpc “2.0” (文本) 是的 JSON-RPC 版本字符串。
id 字符串 | 是的 匹配原始 message/streamtasks/resubscribe 请求中的 id
result 任一消息
OR 任务
TaskStatusUpdateEvent
TaskArtifactUpdateEvent
是的 事件有效负载

7.2.2. TaskStatusUpdateEvent 对象

携带有关流式处理期间任务状态更改的信息。这是 SendStreamingMessageSuccessResponse .

/** Sent by server during sendStream or subscribe requests */
export interface TaskStatusUpdateEvent {
  /** Task id */
  taskId: string;
  /** The context the task is associated with */
  contextId: string;
  /** Event type */
  kind: "status-update";
  /** Current status of the task */
  status: TaskStatus;
  /** Indicates the end of the event stream */
  final: boolean;
  /** Extension metadata. */
  metadata?: {
    [key: string]: any;
  };
}
字段名称 类型 必填 违约 描述
taskId string 是的 正在更新的任务 ID
contextId string 是的 任务与之关联的上下文 ID
kind 字符串 , 文本 是的 status-update 类型鉴别器,文本值
status TaskStatus 是的 新的 TaskStatus 对象。
final boolean false 如果为 true,则表示这是当前流周期的终端状态更新。在此之后,服务器通常会关闭 SSE 连接。
metadata Record<string, any> undefined 特定于事件的元数据。

7.2.3. TaskArtifactUpdateEvent 对象

携带任务在流式处理期间生成的新的或更新的构件(或构件的块)。这是 SendTaskStreamingResponse 中可能的结果类型之一。

/** Sent by server during sendStream or subscribe requests */
export interface TaskArtifactUpdateEvent {
  /** Task id */
  taskId: string;
  /** The context the task is associated with */
  contextId: string;
  /** Event type */
  kind: "artifact-update";
  /** Generated artifact */
  artifact: Artifact;
  /** Indicates if this artifact appends to a previous one */
  append?: boolean;
  /** Indicates if this is the last chunk of the artifact */
  lastChunk?: boolean;
  /** Extension metadata. */
  metadata?: {
    [key: string]: any;
  };
}
字段名称 类型 必填 违约 描述
taskId string 是的 与生成的构件部件关联的任务 ID
contextId string 是的 任务与之关联的上下文 ID
kind 字符串 , 文本 是的 artifact-update 类型鉴别器,文本值
artifact Artifact 是的 Artifact 数据。可以是完整的工件或增量块。
append boolean false true 表示将部分附加到 artifact;false (默认) 表示 替换。
lastChunk boolean false true 表示这是构件的最终更新。
metadata Record<string, any> undefined 特定于事件的元数据。

7.3. tasks/get

检索以前启动的任务的当前状态(包括状态、构件和可选的历史记录)。这通常用于轮询通过 message/send 启动的任务的状态,或在通过推送通知收到通知后或 SSE 流结束后获取任务的最终状态。

7.3.1. TaskQueryParams 对象

/** Parameters for querying a task, including optional history length. */
export interface TaskQueryParams extends TaskIdParams {
  /** Number of recent messages to be retrieved. */
  historyLength?: number;
}
字段名称 类型 必填 描述
id string 是的 要检索其当前状态的任务的 ID。
historyLength integer 如果为正,则请求服务器在 Task.history 中包含最多 N 条最近的消息。
metadata Record<string, any> 特定于请求的元数据。

7.4. tasks/cancel

请求取消正在进行的任务。服务器将尝试取消任务,但不能保证成功(例如,任务可能已经完成或失败,或者当前阶段可能不支持取消)。

7.4.1. TaskIdParams 对象 (用于 tasks/canceltasks/pushNotificationConfig/get

仅包含任务 ID 和可选元数据的简单对象。

/** Parameters containing only a task ID, used for simple task operations. */
export interface TaskIdParams {
  /** Task id. */
  id: string;
  metadata?: {
    [key: string]: any;
  };
}
字段名称 类型 必填 描述
id string 是的 任务的 ID。
metadata Record<string, any> 特定于请求的元数据。

7.5. tasks/pushNotificationConfig/set

设置或更新指定任务的推送通知配置。这允许客户端告诉服务器在何处以及如何发送任务的异步更新。要求服务器具有 AgentCard.capabilities.pushNotifications: true

7.6. tasks/pushNotificationConfig/get

检索指定任务的当前推送通知配置。要求服务器具有 AgentCard.capabilities.pushNotifications: true

7.6.1. GetTaskPushNotificationConfigParams 对象 () tasks/pushNotificationConfig/get

用于获取任务的推送通知配置的对象。

/** Parameters for fetching a pushNotificationConfiguration associated with a Task */
export interface GetTaskPushNotificationConfigParams extends TaskIdParams {
  pushNotificationConfigId?: string;
}
字段名称 类型 必填 描述
id string 是的 任务的 ID。
pushNotificationConfigId string 推送通知配置 ID。如果未指定配置 ID,服务器将返回其中一个关联的配置
metadata Record<string, any> 特定于请求的元数据。

7.7. tasks/pushNotificationConfig/list

检索指定任务的关联推送通知配置。要求服务器具有 AgentCard.capabilities.pushNotifications: true

7.7.1. ListTaskPushNotificationConfigParams 对象 () tasks/pushNotificationConfig/list

用于获取任务的推送通知配置的对象。

/**
 * JSON-RPC request model for the 'tasks/pushNotificationConfig/list' method.
 */
export interface ListTaskPushNotificationConfigRequest extends JSONRPCRequest {
  id: number | string;
  /** A String containing the name of the method to be invoked. */
  method: "tasks/pushNotificationConfig/list";
  /** A Structured value that holds the parameter values to be used during the invocation of the method. */
  params: ListTaskPushNotificationConfigParams;
}
字段名称 类型 必填 描述
id string 是的 任务的 ID。
metadata Record<string, any> 特定于请求的元数据。

7.8. tasks/pushNotificationConfig/delete

删除任务的关联推送通知配置。要求服务器具有 AgentCard.capabilities.pushNotifications: true

7.8.1. DeleteTaskPushNotificationConfigParams 对象 () tasks/pushNotificationConfig/delete

用于删除任务的关联推送通知配置的对象。

/** Parameters for removing pushNotificationConfiguration associated with a Task */
export interface DeleteTaskPushNotificationConfigParams extends TaskIdParams {
  pushNotificationConfigId: string;
}
字段名称 类型 必填 描述
id string 是的 任务的 ID。
pushNotificationConfigId string 是的 推送通知配置 ID
metadata Record<string, any> 特定于请求的元数据。

7.9. tasks/resubscribe

允许客户端在上一个连接(来自 message/stream 或之前的 tasks/resubscribe)中断后重新连接到正在进行的任务的 SSE 流。要求服务器具有 AgentCard.capabilities.streaming: true

目的是继续接收后续更新。服务器对断开连接期间错过的事件的行为(例如,它是尝试回填一些错过的事件还是仅从重新订阅点发送新事件)取决于实现,并非由此规范严格定义。

  • 请求参数类型 TaskIdParams
  • 响应(成功重新订阅时):Response (on successful resubscription)
    • HTTP 状态:200 正常
    • HTTP 内容类型 text/event-stream
    • HTTP Body:一个 Server-Sent Events 流,格式与 message/stream 相同,携带任务的后续 SendStreamingMessageResponse 事件。
  • 响应(重新订阅失败时):
    • 标准 HTTP 错误代码(例如 4xx、5xx)。
    • HTTP 正文可以包含带有 error 对象的标准 JSONRPCResponse。如果任务不再处于活动状态、不存在或不支持/启用流式处理,则可能会失败。

7.10. agent/authenticatedExtendedCard

在客户端进行身份验证后,检索可能更详细的代理卡版本。此终端节点仅在 为 trueAgentCard.supportsAuthenticatedExtendedCard 可用。这是一个 HTTP GET 端点,而不是 JSON-RPC 方法。

  • 端点 URL{AgentCard.url}/../agent/authenticatedExtendedCard (相对于公有代理卡中指定的基 URL)。
  • HTTP 方法 GET
  • 身份验证 :客户端必须使用公共 AgentCard.securitySchemesAgentCard.security 字段中声明的方案之一对请求进行身份验证。
  • 请求参数 :无(HTTP GET 请求)。
  • 响应结果类型(成功时):AgentCard(完整的代理卡对象,可能包含公共卡中不存在的其他详细信息或技能)。
  • 响应错误类型 (失败时): 标准 HTTP 错误代码。
    • 401 未授权 :身份验证失败(凭据缺失或无效)。服务器包含 WWW-Authenticate 标头。
    • 403 Forbidden:身份验证成功,但客户端/用户无权访问扩展卡。
    • 404 Not Found:已声明 supportsAuthenticatedExtendedCard 功能,但服务器尚未在指定路径处实现此终端节点。
    • 5xx 服务器错误 :发生内部服务器错误。

检索此经过身份验证的卡的客户端在其经过身份验证的会话期间或直到卡的版本更改之前,将其缓存的公共代理卡替换为从此端点接收的内容。

7.10.1. AuthenticatedExtendedCardParams 对象

此终端节点不使用 JSON-RPC 参数 。如果需要,任何参数都将作为 HTTP 查询参数包含在内(尽管标准未定义任何参数)。

7.10.2. AuthenticatedExtendedCardResponse 对象

成功的响应正文是符合 AgentCard 接口的 JSON 对象。


8. 错误处理

A2A 使用标准的 JSON-RPC 2.0 错误代码和结构来报告错误。错误在 JSONRPCErrorResponse 对象的 error 成员中返回。请参阅 JSONRPCError 对象定义

8.1. 标准 JSON-RPC 错误

这些是由 JSON-RPC 2.0 规范定义的标准代码。

法典 JSON-RPC 规范含义 典型的 A2A 信息 描述
-32700 解析错误 无效的 JSON 负载 服务器收到格式不正确的 JSON。
-32600 请求无效 无效的 JSON-RPC 请求 JSON 负载是有效的 JSON,但不是有效的 JSON-RPC Request 对象。
-32601 未找到方法 未找到方法 请求的 A2A RPC 方法 (例如,“tasks/foo”) 不存在或不受支持。
-32602 无效的参数 方法参数无效 为该方法提供的参数无效(例如,类型错误、缺少必填字段)。
-32603 内部错误 内部服务器错误 在处理过程中,服务器上发生意外错误。
-32000-32099 服务器错误 (服务器定义) 保留用于实现定义的 server-errors。特定于 A2A 的错误使用此范围。

8.2. 特定于 A2A 的错误

这些是在 JSON-RPC 服务器错误范围(-32000-32099)中定义的自定义错误代码,用于提供有关 A2A 相关问题的更具体反馈。服务器应在适用的情况下使用这些代码。

法典 错误名称 (概念) 典型消息字符串 描述
-32001 TaskNotFoundError 未找到任务 指定的任务 ID 与现有任务或活动任务不对应。它可能无效、过期或已完成并清除。
-32002 TaskNotCancelableError 无法取消任务 尝试取消未处于可取消状态的任务(例如,它已达到 completedfailedcanceled 等最终状态)。
-32003 PushNotificationNotSupportedError 不支持推送通知 客户端尝试使用推送通知功能(例如), tasks/pushNotificationConfig/set 但服务器代理不支持它们(即 AgentCard.capabilities.pushNotifications false )。
-32004 UnsupportedOperationError 不支持此作 此 server agent 实现不支持请求的作或其特定方面(可能由参数暗示)。比 not find 方法更广泛。
-32005 ContentTypeNotSupportedError 不兼容的内容类型 代理或正在调用的特定技能不支持请求的 message.parts 中提供的 Media Type(或隐含的 Media Type)。
-32006 InvalidAgentResponseError 代理响应类型无效 代理为请求的方法生成了无效响应

对于上面未涵盖的更具体情况,服务器可以在 -32000-32099 范围内定义其他错误代码,但它们应该清楚地记录这些代码。JSONRPCError 对象的 data 字段可用于为任何错误提供更结构化的详细信息。

9. 常见工作流程和示例

本节提供了常见 A2A 交互的说明性 JSON 示例。时间戳、上下文 ID 和请求/响应 ID 用于演示目的。为简洁起见,如果不是示例的中心,则可以省略一些可选字段。

9.1. 获取已验证的扩展代理卡

场景: 客户端发现一个公共代理卡,指示支持经过身份验证的扩展卡,并希望检索完整详细信息。

  1. 客户端获取公共 Agent Card:
GET https://example.com/.well-known/agent.json

Server 使用公共 Agent Card 进行响应(如 Section 5.6 中的示例),包括 supportsAuthenticatedExtendedCard: true (在根级别)和 securitySchemes

  1. 客户端从公共卡识别所需的身份验证。

  2. 客户端在带外获取必要的凭证(例如,与 Google 一起执行 OAuth 2.0 流,从而产生访问令牌)。

  3. 客户端获取经过身份验证的扩展代理卡:

GET https://example.com/a2a/agent/authenticatedExtendedCard
Authorization: Bearer <obtained_access_token>
  1. Server 对请求进行身份验证和授权。

  2. 服务器使用完整的代理卡进行响应:

9.2. 基本执行 (同步 / 轮询风格)

场景: 客户提出一个简单的问题,座席快速响应任务

  1. 客户端使用 message/send 发送消息:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "tell me a joke"
        }
      ],
      "messageId": "9229e770-767c-417b-a0b0-f0741243c589"
    },
    "metadata": {}
  }
}
  1. Server 处理请求,创建任务并做出响应(任务快速完成)
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "363422be-b0f9-4692-a24d-278670e7c7f1",
    "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
    "status": {
      "state": "completed"
    },
    "artifacts": [
      {
        "artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
        "name": "joke",
        "parts": [
          {
            "kind": "text",
            "text": "Why did the chicken cross the road? To get to the other side!"
          }
        ]
      }
    ],
    "history": [
      {
        "role": "user",
        "parts": [
          {
            "kind": "text",
            "text": "tell me a joke"
          }
        ],
        "messageId": "9229e770-767c-417b-a0b0-f0741243c589",
        "taskId": "363422be-b0f9-4692-a24d-278670e7c7f1",
        "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
      }
    ],
    "kind": "task",
    "metadata": {}
  }
}

场景: 客户提出一个简单的问题,代理在没有任务的情况下快速响应

  1. 客户端使用 message/send 发送消息:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "tell me a joke"
        }
      ],
      "messageId": "9229e770-767c-417b-a0b0-f0741243c589"
    },
    "metadata": {}
  }
}
  1. 服务器处理请求,在没有任务的情况下快速响应
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "messageId": "363422be-b0f9-4692-a24d-278670e7c7f1",
    "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
    "parts": [
      {
        "kind": "text",
        "text": "Why did the chicken cross the road? To get to the other side!"
      }
    ],
    "kind": "message",
    "metadata": {}
  }
}

如果任务运行时间较长,服务器最初可能会使用 status.state: “working” 进行响应。然后,客户端将定期调用 tasks/get with params: {"id": "363422be-b0f9-4692-a24d-278670e7c7f1"} ,直到任务达到最终状态。

9.3. 流式任务执行 (SSE)

场景: 客户要求代理写一篇长篇论文,描述所附的图片。

  1. 客户端发送消息并使用 message/stream 进行订阅:
{
  "method": "message/stream",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "write a long paper describing the attached pictures"
        },
        {
          "kind": "file",
          "file": {
            "mimeType": "image/png",
            "data": "<base64-encoded-content>"
          }
        }
      ],
      "messageId": "bbb7dee1-cf5c-4683-8a6f-4114529da5eb"
    },
    "metadata": {}
  }
}
  1. 服务器使用 HTTP 200 OK 进行响应, Content-Type: text/event-stream 并开始发送 SSE 事件:

事件 1:任务状态更新 - 正在工作

data: {
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
    "contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
    "status": {
      "state": "submitted",
      "timestamp":"2025-04-02T16:59:25.331844"
    },
    "history": [
      {
        "role": "user",
        "parts": [
          {
            "kind": "text",
            "text": "write a long paper describing the attached pictures"
          },
          {
            "kind": "file",
            "file": {
              "mimeType": "image/png",
              "data": "<base64-encoded-content>"
            }
          }
        ],
        "messageId": "bbb7dee1-cf5c-4683-8a6f-4114529da5eb",
        "taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
        "contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1"
      }
    ],
    "kind": "task",
    "metadata": {}
  }
}

data: {
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
    "contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
    "artifact": {
      "artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
      "parts": [
        {"type":"text", "text": "<section 1...>"}
      ]
    },
    "append": false,
    "lastChunk": false,
    "kind":"artifact-update"
  }
}

data: {
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
    "contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
    "artifact": {
      "artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
      "parts": [
        {"type":"text", "text": "<section 2...>"}
      ],
    },
    "append": true,
    "lastChunk": false,
    "kind":"artifact-update"
  }
}


data: {
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
    "contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
    "artifact": {
      "artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
      "parts": [
        {"type":"text", "text": "<section 3...>"}
      ]
    },
    "append": true,
    "lastChunk": true,
    "kind":"artifact-update"
  }
}

data: {
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
    "contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
    "status": {
      "state": "completed",
      "timestamp":"2025-04-02T16:59:35.331844"
    },
    "final": true,
    "kind":"status-update"
  }
}

(服务器在 final:true 事件后关闭 SSE 连接)。

9.4. 多轮交互(需要输入)

场景: 客户想要预订航班,而代理需要更多信息。

  1. 客户端使用 message/send 发送消息:
{
  "jsonrpc": "2.0",
  "id": "req-003",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [{ "kind": "text", "text": "I'd like to book a flight." }]
    },
    "messageId": "c53ba666-3f97-433c-a87b-6084276babe2"
  }
}
  1. 服务器响应,任务状态为 input-required
{
  "jsonrpc": "2.0",
  "id": "req-003",
  "result": {
    "id": "3f36680c-7f37-4a5f-945e-d78981fafd36",
    "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
    "status": {
      "state": "input-required",
      "message": {
        "role": "agent",
        "parts": [
          {
            "kind": "text",
            "text": "Sure, I can help with that! Where would you like to fly to, and from where? Also, what are your preferred travel dates?"
          }
        ],
        "messageId": "c2e1b2dd-f200-4b04-bc22-1b0c65a1aad2",
        "taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
        "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
      },
      "timestamp": "2024-03-15T10:10:00Z"
    },
    "history": [
      {
        "role": "user",
        "parts": [
          {
            "kind": "text",
            "text": "I'd like to book a flight."
          }
        ],
        "messageId": "c53ba666-3f97-433c-a87b-6084276babe2",
        "taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
        "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
      }
    ],
    "kind": "task"
  }
}
  1. 客户端消息/发送 使用相同的任务 ID 提供请求的输入):
{
  "jsonrpc": "2.0",
  "id": "req-004",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "I want to fly from New York (JFK) to London (LHR) around October 10th, returning October 17th."
        }
      ],
      "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
      "taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
      "messageId": "0db1d6c4-3976-40ed-b9b8-0043ea7a03d3"
    },
    "configuration": {
      "blocking": true
    }
  }
}
  1. Server 处理新的输入并做出响应(例如,任务已完成或需要更多输入):
{
  "jsonrpc": "2.0",
  "id": "req-004",
  "result": {
    "id": "3f36680c-7f37-4a5f-945e-d78981fafd36",
    "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
    "status": {
      "state": "completed",
      "message": {
        "role": "agent",
        "parts": [
          {
            "kind": "text",
            "text": "Okay, I've found a flight for you. Confirmation XYZ123. Details are in the artifact."
          }
        ]
      }
    },
    "artifacts": [
      {
        "artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
        "name": "FlightItinerary.json",
        "parts": [
          {
            "kind": "data",
            "data": {
              "confirmationId": "XYZ123",
              "from": "JFK",
              "to": "LHR",
              "departure": "2024-10-10T18:00:00Z",
              "arrival": "2024-10-11T06:00:00Z",
              "returnDeparture": "..."
            }
          }
        ]
      }
    ],
    "history": [
      {
        "role": "user",
        "parts": [
          {
            "kind": "text",
            "text": "I'd like to book a flight."
          }
        ],
        "messageId": "c53ba666-3f97-433c-a87b-6084276babe2",
        "taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
        "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
      },
      {
        "role": "agent",
        "parts": [
          {
            "kind": "text",
            "text": "Sure, I can help with that! Where would you like to fly to, and from where? Also, what are your preferred travel dates?"
          }
        ],
        "messageId": "c2e1b2dd-f200-4b04-bc22-1b0c65a1aad2",
        "taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
        "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
      },
      {
        "role": "user",
        "parts": [
          {
            "kind": "text",
            "text": "I want to fly from New York (JFK) to London (LHR) around October 10th, returning October 17th."
          }
        ],
        "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
        "taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
        "messageId": "0db1d6c4-3976-40ed-b9b8-0043ea7a03d3"
      }
    ],
    "kind": "task",
    "metadata": {}
  }
}

9.5. 推送通知的设置和使用

场景: 客户端请求生成长时间运行的报告,并希望在生成后通过 Webhook 收到通知。

  1. 使用 pushNotification 配置发送客户端消息/发送
{
  "jsonrpc": "2.0",
  "id": "req-005",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "Generate the Q1 sales report. This usually takes a while. Notify me when it's ready."
        }
      ],
      "messageId": "6dbc13b5-bd57-4c2b-b503-24e381b6c8d6"
    },
    "configuration": {
      "pushNotificationConfig": {
        "url": "https://client.example.com/webhook/a2a-notifications",
        "token": "secure-client-token-for-task-aaa",
        "authentication": {
          "schemes": ["Bearer"]
          // Assuming server knows how to get a Bearer token for this webhook audience,
          // or this implies the webhook is public/uses the 'token' for auth.
          // 'credentials' could provide more specifics if needed by the server.
        }
      }
    }
  }
}
  1. Server 确认任务(例如,状态 submittedworking):
{
  "jsonrpc": "2.0",
  "id": "req-005",
  "result": {
    "id": "43667960-d455-4453-b0cf-1bae4955270d",
    "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
    "status": { "state": "submitted", "timestamp": "2024-03-15T11:00:00Z" }
    // ... other fields ...
  }
}
  1. (稍后)A2A Server 完成任务并 POST 通知: https://client.example.com/webhook/a2a-notifications

  2. HTTP 标头可能包括:

    • Authorization: Bearer <server_jwt_for_webhook_audience> (如果服务器向 Webhook 进行身份验证)
    • Content-Type: application/json
    • X-A2A-Notification-Token: secure-client-token-for-task-aaa
  3. HTTP 正文(Task 对象作为 JSON 有效负载发送):
{
  "id": "43667960-d455-4453-b0cf-1bae4955270d",
  "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
  "status": { "state": "completed", "timestamp": "2024-03-15T18:30:00Z" },
  "kind": "task"
  // ... other fields ...
}
  1. 客户端的 Webhook 服务:

  2. 接收 POST。

  3. 验证 Authorization 标头(如果适用)。
  4. 验证 X-A2A-Notification-Token
  5. 在内部处理通知(例如,更新应用程序状态、通知最终用户)。

9.6. 文件交换(上传和下载)

场景: 客户端发送图像进行分析,代理返回修改后的图像。

  1. 带有 FilePart 的客户端消息/发送 (上传图像字节):
{
  "jsonrpc": "2.0",
  "id": "req-007",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "Analyze this image and highlight any faces."
        },
        {
          "kind": "file",
          "file": {
            "name": "input_image.png",
            "mimeType": "image/png",
            "bytes": "iVBORw0KGgoAAAANSUhEUgAAAAUA..." // Base64 encoded image data
          }
        }
      ],
      "messageId": "6dbc13b5-bd57-4c2b-b503-24e381b6c8d6"
    }
  }
}
  1. Server 处理镜像并使用工件中的 FilePart 进行响应(例如,为修改后的镜像提供 URI):
{
  "jsonrpc": "2.0",
  "id": "req-007",
  "result": {
    "id": "43667960-d455-4453-b0cf-1bae4955270d",
    "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
    "status": { "state": "completed", "timestamp": "2024-03-15T12:05:00Z" },
    "artifacts": [
      {
        "artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
        "name": "processed_image_with_faces.png",
        "parts": [
          {
            "kind": "file",
            "file": {
              "name": "output.png",
              "mimeType": "image/png",
              // Server might provide a URI to a temporary storage location
              "uri": "https://storage.example.com/processed/task-bbb/output.png?token=xyz"
              // Or, alternatively, it could return bytes directly:
              // "bytes": "ASEDGhw0KGgoAAAANSUhEUgAA..."
            }
          }
        ]
      }
    ],
    "kind": "task"
  }
}

9.7. 结构化数据交换(请求和提供 JSON)

场景: 客户端要求提供特定 JSON 格式的未结支持票证列表。

  1. 客户端消息/发送 Part.metadata 在所需输出模式/媒体类型上的提示:(注意:A2A 在 v0.2.0 中没有正式标准化模式协商,但根据客户端/服务器之间的约定,元数据可以用于此类提示)。
{
  "jsonrpc": "2.0",
  "id": 9,
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "Show me a list of my open IT tickets",
          "metadata": {
            "mimeType": "application/json",
            "schema": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "ticketNumber": { "type": "string" },
                  "description": { "type": "string" }
                }
              }
            }
          }
        }
      ],
      "messageId": "85b26db5-ffbb-4278-a5da-a7b09dea1b47"
    },
    "metadata": {}
  }
}
  1. Server 使用结构化 JSON 数据进行响应:
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "id": "d8c6243f-5f7a-4f6f-821d-957ce51e856c",
    "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
    "status": {
      "state": "completed",
      "timestamp": "2025-04-17T17:47:09.680794"
    },
    "artifacts": [
      {
        "artifactId": "c5e0382f-b57f-4da7-87d8-b85171fad17c",
        "parts": [
          {
            "kind": "text",
            "text": "[{\"ticketNumber\":\"REQ12312\",\"description\":\"request for VPN access\"},{\"ticketNumber\":\"REQ23422\",\"description\":\"Add to DL - team-gcp-onboarding\"}]"
          }
        ]
      }
    ],
    "kind": "task"
  }
}

这些示例说明了 A2A 在处理各种交互模式和数据类型方面的灵活性。实现者应参考所有字段和约束的详细对象定义。

10. 附录

10.1. 与 MCP 的关系(模型上下文协议)

A2A 和 MCP 是针对代理系统的不同方面设计的互补协议:

  • 模型上下文协议 (MCP): 专注于标准化 AI 模型和代理与工具、API、数据源和其他外部资源的连接和交互方式。它定义了描述工具功能(如 LLM 中的函数调用)、传递输入和接收结构化输出的结构化方法。将 MCP 视为代理使用特定功能或访问资源的 “作方法”。
  • Agent2Agent 协议 (A2A): 专注于标准化独立(通常不透明的 )AI 代理作为对等方相互通信和协作的方式。A2A 为代理提供了一个应用程序级协议,用于发现彼此、协商交互模式、管理共享任务以及交换对话上下文或复杂结果。这是关于代理如何合作委派工作。

它们如何协同工作: A2A 客户端代理可能会请求 A2A Server 代理来执行复杂任务。反过来,Server 代理可能会使用 MCP 与多个底层工具、API 或数据源进行交互,以收集信息或执行完成 A2A 任务所需的作。

有关更详细的比较,请参阅 A2A 和 MCP 指南

10.2. 安全注意事项摘要

安全性是 A2A 的首要问题。关键考虑因素包括:

  • 运输安全: 在生产环境中,始终将 HTTPS 与强 TLS 配置一起使用。
  • 认证:
    • 通过标准 HTTP 机制(例如,带有 Bearer 令牌的 Authorization 标头、API 密钥)进行处理。
    • 要求在 AgentCard 中声明。
    • 凭证必须由客户端在带外获取。
    • A2A 服务器必须对每个请求进行身份验证。
  • 授权:
    • 基于经过身份验证的身份的服务器端责任。
    • 实施最小权限原则。
    • 可以是精细的,基于技能、作或数据。
  • 推送通知安全性:
    • Webhook URL 验证(通过 A2A 服务器发送通知)对于防止 SSRF 至关重要。
    • 对 A2A 服务器对客户端的 webhook 进行身份验证是必不可少的。
    • 客户端的 webhook 接收器对通知进行身份验证(验证它来自合法的 A2A 服务器并且相关)至关重要。
    • 请参阅流媒体和异步作指南以获取详细的推送通知安全性。
  • 输入验证: 服务器必须严格验证所有 RPC 参数以及 MessageArtifact 部分中的数据内容/结构,以防止注入攻击或处理错误。
  • 资源管理: 实施速率限制、并发控制和资源限制,以保护代理免受滥用或过载。
  • 数据隐私: 遵守 MessageArtifact 部分中交换的数据的所有适用隐私法规。最大限度地减少敏感数据传输。

有关全面讨论,请参阅 Enterprise-Ready Features 指南