Skip to content

Agent2Agent (A2A) 协议官方规范

版本: 0.3.0

有关版本间更改的详细信息,请参见发行说明

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 端点的智能体或智能体系统,处理任务并提供响应。
  • Agent Card: 由 A2A 服务器发布的 JSON 元数据文档,描述其身份、能力、技能、服务端点和身份验证要求。
  • 消息: 客户端和远程智能体之间的一次通信,具有 role("user" 或 "agent")并包含一个或多个 Parts
  • 任务: 由 A2A 管理的工作的基本单元,由唯一 ID 标识。任务是有状态的,并通过定义的生命周期进行。
  • 部分: 消息或工件中的最小内容单元(例如,TextPartFilePartDataPart)。
  • 工件: 智能体作为任务结果生成的有形输出(例如,文档、图像、结构化数据),由 Parts 组成。
  • 流式传输(SSE): 通过服务器发送事件传递的任务实时增量更新(状态更改、工件块)。
  • 推送通知: 通过服务器发起的 HTTP POST 请求向客户端提供的 webhook URL 传递的异步任务更新,适用于长时间运行或断开连接的场景。
  • 上下文: 可选的、服务器生成的标识符,用于逻辑上分组相关任务。
  • 扩展: 智能体提供超出核心 A2A 规范的附加功能或数据的机制。

3. 传输和格式

3.1. 传输层要求

A2A 支持多种传输协议,所有协议都在 HTTP(S) 上运行。智能体在选择要实现的传输协议时具有灵活性,基于其特定要求和用例:

  • A2A 通信 必须 通过 HTTP(S) 进行。
  • A2A 服务器在其 AgentCard 中定义的一个或多个 URL 上暴露其服务。
  • 智能体 必须 至少实现本规范中定义的三种核心传输协议之一。
  • 所有支持的传输协议在状态和能力上都被视为相等。

3.2. 支持的传输协议

A2A 定义了三种核心传输协议。符合 A2A 标准的智能体应该实现至少一种这些传输协议。它们可以通过实现3.2.4中定义的传输扩展来合规。 所有三种协议在状态上都被视为相等,智能体可以根据其要求选择实现它们的任何组合。

3.2.1. JSON-RPC 2.0 传输

智能体 可以 支持 JSON-RPC 2.0 传输。如果实现,它 必须 符合这些要求:

  • 主要数据格式是 JSON-RPC 2.0 用于所有请求和响应(不包括 SSE 流包装器)。
  • 客户端请求和服务器响应 必须 遵循 JSON-RPC 2.0 规范。
  • 包含 JSON-RPC 载荷的 HTTP 请求和响应的 Content-Type必须application/json
  • 方法名称遵循 {category}/{action} 模式(例如,"message/send""tasks/get")。

3.2.2. gRPC 传输

智能体 可以 支持 gRPC 传输。如果实现,它 必须 符合这些要求:

  • 协议定义必须 使用 specification/grpc/a2a.proto 中的规范协议缓冲区定义。
  • 消息序列化必须 使用协议缓冲区版本 3 进行消息序列化。
  • 服务定义必须 实现 proto 文件中定义的 A2AService gRPC 服务。
  • 方法覆盖必须 提供与其它支持的传输功能等效的所有方法。
  • 字段映射必须 使用 json_name 注解以实现 HTTP/JSON 转码兼容性。
  • 错误处理必须 将 A2A 错误代码映射到 proto 注解中定义的适当 gRPC 状态代码。
  • 传输安全必须 支持 TLS 加密(带 TLS 的 HTTP/2 上的 gRPC)。

3.2.3. HTTP+JSON/REST 传输

智能体 可以 支持 REST 风格的 HTTP+JSON 传输。如果实现,它 必须 符合这些要求:

  • HTTP 方法必须 使用适当的 HTTP 动词(GET 用于查询,POST 用于操作,PUT 用于更新,DELETE 用于删除)。
  • URL 模式必须 遵循每个方法部分中记录的 URL 模式(例如,/v1/message:send/v1/tasks/{id})。
  • 内容类型必须 对请求和响应体使用 application/json
  • HTTP 状态代码必须 使用适当的 HTTP 状态代码(200、400、401、403、404、500 等),这些代码对应于 A2A 错误类型。
  • 请求/响应格式必须 使用在结构上等效于核心 A2A 数据结构的 JSON 对象。
  • 方法覆盖必须 提供与其它支持的传输功能等效的所有方法。
  • 错误格式必须 以一致的 JSON 格式返回错误响应,该格式映射到 A2A 错误类型。

3.2.4. 传输扩展

可以 将附加传输协议定义为核心 A2A 规范的扩展。此类扩展:

  • 必须 保持与核心传输的功能等效性
  • 必须 使用清晰的命名空间标识符以避免冲突
  • 必须 得到清晰的文档和规范
  • 应该 提供从核心传输的迁移路径

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

流式传输能力是 传输特定的

3.3.1. JSON-RPC 2.0 流式传输

当流式传输用于 message/streamtasks/resubscribe 等方法时:

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

3.3.2. gRPC 流式传输

gRPC 传输使用 服务器流式 RPC 进行流式操作,如协议缓冲区规范中所定义。

3.3.3. HTTP+JSON/REST 流式传输

如果支持 REST 传输,它 必须 使用类似于 JSON-RPC 的服务器发送事件实现流式传输。

3.4. 传输合规性和互操作性

3.4.1. 功能等效性要求

当智能体支持多种传输时,所有支持的传输 必须

  • 相同功能:提供相同的操作和能力集。
  • 一致行为:对相同请求返回语义上等效的结果。
  • 相同错误处理:使用第 8 节中定义的错误代码在传输间一致地映射错误。
  • 等效身份验证:支持 AgentCard 中声明的相同身份验证方案。

3.4.2. 传输选择和协商

  • 智能体声明:智能体 必须 在其 AgentCard 中使用 preferredTransportadditionalInterfaces 字段声明所有支持的传输。
  • 客户端选择:客户端 可以 选择智能体声明的任何传输。
  • 无传输协商:A2A 不定义动态传输协商协议。客户端基于静态 AgentCard 信息选择传输。
  • 回退行为:客户端 应该 实现回退逻辑,如果首选传输失败,则尝试替代传输。具体的回退策略取决于实现。

3.4.3. 传输特定扩展

传输 可以 提供不损害功能等效性的传输特定优化或扩展:

  • gRPC:可以利用 gRPC 特定功能,如双向流、元数据或自定义状态代码。
  • REST:可以提供附加的 HTTP 缓存头或支持 HTTP 条件请求。
  • JSON-RPC:可以在不与核心规范冲突的 JSON-RPC 请求/响应对象中包含附加字段。

此类扩展 必须 向后兼容,不得 破坏不支持扩展的客户端的互操作性。

3.5. 方法映射和命名约定

为确保跨不同传输的一致性和可预测性,A2A 定义了规范方法映射规则。

3.5.1. JSON-RPC 方法命名

JSON-RPC 方法 必须 遵循模式:{category}/{action},其中:

  • category 表示资源类型(例如,"message"、"tasks"、"agent")
  • action 表示操作(例如,"send"、"get"、"cancel")
  • 嵌套操作使用正斜杠(例如,"tasks/pushNotificationConfig/set")

3.5.2. gRPC 方法命名

gRPC 方法 必须 遵循使用 PascalCase 的协议缓冲区服务约定:

  • 将 JSON-RPC 类别/操作转换为 PascalCase 复合词
  • 使用标准 gRPC 方法前缀(Get、Set、List、Create、Delete、Cancel)

3.5.3. HTTP+JSON/REST 方法命名

REST 端点 必须 遵循带有适当 HTTP 动词的 RESTful URL 模式:

  • 使用基于资源的 URL:/v1/{resource}[/{id}][:{action}]
  • 使用与 REST 语义对齐的标准 HTTP 方法
  • 使用冒号表示法表示非 CRUD 操作

3.5.4. 方法映射合规性

实现多种传输时,智能体 必须

  • 使用标准映射:遵循 3.5.2 和 3.5.3 节中定义的方法映射。
  • 保持功能等效性:每个传输特定方法 必须 在所有支持的传输中提供相同的功能。
  • 一致参数:在传输间使用等效参数结构(考虑传输特定序列化差异)。
  • 等效响应:对相同操作在所有传输中返回语义上等效的响应。

3.5.5. 扩展方法命名

对于核心 A2A 规范中未定义的自定义或扩展方法:

  • JSON-RPC:遵循 {category}/{action} 模式,带有清晰的命名空间(例如,myorg.extension/action
  • gRPC:使用遵循协议缓冲区约定的适当服务和方法名称
  • REST:使用带有适当 HTTP 方法的清晰基于资源的 URL

扩展方法 必须 得到清晰的文档,不得 与核心 A2A 方法名称或语义冲突。

3.5.6. 方法映射参考表

为快速参考,下表总结了所有传输间的方法映射:

JSON-RPC 方法 gRPC 方法 REST 端点 描述
message/send SendMessage POST /v1/message:send 向智能体发送消息
message/stream SendStreamingMessage POST /v1/message:stream 发送带流式传输的消息
tasks/get GetTask GET /v1/tasks/{id} 获取任务状态
tasks/list ListTask GET /v1/tasks 列出任务(仅 gRPC/REST)
tasks/cancel CancelTask POST /v1/tasks/{id}:cancel 取消任务
tasks/resubscribe TaskSubscription POST /v1/tasks/{id}:subscribe 恢复任务流式传输
tasks/pushNotificationConfig/set CreateTaskPushNotification POST /v1/tasks/{id}/pushNotificationConfigs 设置推送通知配置
tasks/pushNotificationConfig/get GetTaskPushNotification GET /v1/tasks/{id}/pushNotificationConfigs/{configId} 获取推送通知配置
tasks/pushNotificationConfig/list ListTaskPushNotification GET /v1/tasks/{id}/pushNotificationConfigs 列出推送通知配置
tasks/pushNotificationConfig/delete DeleteTaskPushNotification DELETE /v1/tasks/{id}/pushNotificationConfigs/{configId} 删除推送通知配置
agent/getAuthenticatedExtendedCard GetAgentCard GET /v1/card 获取经过身份验证的 Agent Card

4. 认证和授权

A2A 将智能体视为标准企业应用程序,依赖于既定的 Web 安全实践。身份信息 在 A2A JSON-RPC 载荷中传输;它在 HTTP 传输层处理。

有关企业安全方面的综合指南,请参见企业就绪功能

4.1. 传输安全

如第 3.1 节所述,生产部署 必须 使用 HTTPS。实现 应该 使用现代 TLS 配置(推荐 TLS 1.3+)和强密码套件。

4.2. 服务器身份验证

A2A 客户端 应该 通过在 TLS 握手期间验证其 TLS 证书与受信任的证书颁发机构 (CA) 来验证 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 凭据和其从其 Agent Card 声明的认证要求对每个传入请求进行认证。
  • 应该 使用标准 HTTP 状态代码如 401 Unauthorized403 Forbidden 进行认证挑战或拒绝。
  • 应该401 Unauthorized 响应中包含相关 HTTP 头(例如,WWW-Authenticate)以指示所需的认证方案,指导客户端。
  • 应该 通过在 TLS 握手期间验证其 TLS 证书与受信任的证书颁发机构 (CA) 来验证客户端 webhook 服务器的身份。

4.5. 任务内认证(次要凭据)

如果智能体在执行任务期间需要 附加 凭据来访问 不同 系统或资源(例如,代表需要自己认证的用户访问特定工具):

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

4.6. 授权

客户端通过认证后,A2A 服务器负责基于经过认证的客户端/用户身份及其自己的策略对请求进行授权。授权逻辑是实现特定的,可能基于以下内容进行强制:

  • 请求的特定技能(例如,通过 Agent Card 中的 AgentSkill.id 识别)。
  • 任务内尝试的操作。
  • 与智能体管理的资源相关的数据访问策略。
  • 如果适用,与呈现令牌关联的 OAuth 范围。

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

5. 智能体发现:Agent Card

5.1. 目的

A2A 服务器 必须 提供 Agent Card。Agent Card 是一个 JSON 文档,描述服务器的身份、能力、技能、服务端点 URL 以及客户端应该如何认证和与之交互。客户端使用此信息来发现合适的智能体并配置其交互。

有关发现策略的更多信息,请参见智能体发现指南

5.2. 发现机制

客户端可以通过各种方法找到 Agent Card,包括但不限于:

  • 已知 URI:访问智能体域上的预定义路径(参见第 5.3 节)。
  • 注册表/目录:查询智能体的策划目录或注册表(可能是企业特定的、公共的或领域特定的)。
  • 直接配置:客户端可能预配置了 Agent Card URL 或卡片内容本身。

如果使用已知 URI 策略,Agent Card 的推荐位置是: https://{server_domain}/.well-known/agent-card.json 这遵循 RFC 8615 关于已知 URI 的原则。

5.4. Agent Card 的安全性

Agent Card 本身可能包含被视为敏感的信息。

  • 如果 Agent Card 包含敏感信息,提供卡片的端点 必须 受到适当访问控制的保护(例如,mTLS、网络限制、获取卡片需要认证)。
  • 通常 不建议 直接在 Agent Card 中包含明文机密(如静态 API 密钥)。优先选择客户端带外获取动态凭据的认证方案。

5.5. AgentCard 对象结构

/**
 * The AgentCard is a self-describing manifest for an agent. It provides essential
 * metadata including the agent's identity, capabilities, skills, supported
 * communication methods, and security requirements.
 */
export interface AgentCard {
  /**
   * The version of the A2A protocol this agent supports.
   * @default "0.3.0"
   */
  protocolVersion: string;
  /**
   * A human-readable name for the agent.
   *
   * @TJS-examples ["Recipe Agent"]
   */
  name: string;
  /**
   * A human-readable description of the agent, assisting users and other agents
   * in understanding its purpose.
   *
   * @TJS-examples ["Agent that helps users with recipes and cooking."]
   */
  description: string;
  /**
   * The preferred endpoint URL for interacting with the agent.
   * This URL MUST support the transport specified by 'preferredTransport'.
   *
   * @TJS-examples ["https://api.example.com/a2a/v1"]
   */
  url: string;
  /**
   * The transport protocol for the preferred endpoint (the main 'url' field).
   * If not specified, defaults to 'JSONRPC'.
   *
   * IMPORTANT: The transport specified here MUST be available at the main 'url'.
   * This creates a binding between the main URL and its supported transport protocol.
   * Clients should prefer this transport and URL combination when both are supported.
   *
   * @default "JSONRPC"
   * @TJS-examples ["JSONRPC", "GRPC", "HTTP+JSON"]
   */
  preferredTransport?: TransportProtocol | string;
  /**
   * A list of additional supported interfaces (transport and URL combinations).
   * This allows agents to expose multiple transports, potentially at different URLs.
   *
   * Best practices:
   * - SHOULD include all supported transports for completeness
   * - SHOULD include an entry matching the main 'url' and 'preferredTransport'
   * - MAY reuse URLs if multiple transports are available at the same endpoint
   * - MUST accurately declare the transport available at each URL
   *
   * Clients can select any interface from this list based on their transport capabilities
   * and preferences. This enables transport negotiation and fallback scenarios.
   */
  additionalInterfaces?: AgentInterface[];
  /** An optional URL to an icon for the agent. */
  iconUrl?: string;
  /** Information about the agent's service provider. */
  provider?: AgentProvider;
  /**
   * The agent's own version number. The format is defined by the provider.
   *
   * @TJS-examples ["1.0.0"]
   */
  version: string;
  /** An optional URL to the agent's documentation. */
  documentationUrl?: string;
  /** A declaration of optional capabilities supported by the agent. */
  capabilities: AgentCapabilities;
  /**
   * A declaration of the security schemes available to authorize requests. The key is the
   * scheme name. Follows the OpenAPI 3.0 Security Scheme Object.
   */
  securitySchemes?: { [scheme: string]: SecurityScheme };
  /**
   * A list of security requirement objects that apply to all agent interactions. Each object
   * lists security schemes that can be used. Follows the OpenAPI 3.0 Security Requirement Object.
   * This list can be seen as an OR of ANDs. Each object in the list describes one possible
   * set of security requirements that must be present on a request. This allows specifying,
   * for example, "callers must either use OAuth OR an API Key AND mTLS."
   *
   * @TJS-examples [[{"oauth": ["read"]}, {"api-key": [], "mtls": []}]]
   */
  security?: { [scheme: string]: string[] }[];
  /**
   * Default set of supported input MIME types for all skills, which can be
   * overridden on a per-skill basis.
   */
  defaultInputModes: string[];
  /**
   * Default set of supported output MIME types for all skills, which can be
   * overridden on a per-skill basis.
   */
  defaultOutputModes: string[];
  /** The set of skills, or distinct capabilities, that the agent can perform. */
  skills: AgentSkill[];
  /**
   * If true, the agent can provide an extended agent card with additional details
   * to authenticated users. Defaults to false.
   */
  supportsAuthenticatedExtendedCard?: boolean;
  /** JSON Web Signatures computed for this AgentCard. */
  signatures?: AgentCardSignature[];
}
// AgentCard conveys key information:
// - Overall details (version, name, description, uses)
// - Skills; a set of actions/solutions the agent can perform
// - Default modalities/content types supported by the agent.
// - Authentication requirements
// Next ID: 19
message AgentCard {
  // The version of the A2A protocol this agent supports.
  string protocol_version = 16;
  // A human readable name for the agent.
  // Example: "Recipe Agent"
  string name = 1;
  // A description of the agent's domain of action/solution space.
  // Example: "Agent that helps users with recipes and cooking."
  string description = 2;
  // A URL to the address the agent is hosted at. This represents the
  // preferred endpoint as declared by the agent.
  string url = 3;
  // The transport of the preferred endpoint. If empty, defaults to JSONRPC.
  string preferred_transport = 14;
  // Announcement of additional supported transports. Client can use any of
  // the supported transports.
  repeated AgentInterface additional_interfaces = 15;
  // The service provider of the agent.
  AgentProvider provider = 4;
  // The version of the agent.
  // Example: "1.0.0"
  string version = 5;
  // A url to provide additional documentation about the agent.
  string documentation_url = 6;
  // A2A Capability set supported by the agent.
  AgentCapabilities capabilities = 7;
  // The security scheme details used for authenticating with this agent.
  map<string, SecurityScheme> security_schemes = 8;
  // protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
  // Security requirements for contacting the agent.
  // This list can be seen as an OR of ANDs. Each object in the list describes
  // one possible set of security requirements that must be present on a
  // request. This allows specifying, for example, "callers must either use
  // OAuth OR an API Key AND mTLS."
  // Example:
  // security {
  //   schemes { key: "oauth" value { list: ["read"] } }
  // }
  // security {
  //   schemes { key: "api-key" }
  //   schemes { key: "mtls" }
  // }
  repeated Security security = 9;
  // protolint:enable REPEATED_FIELD_NAMES_PLURALIZED
  // The set of interaction modes that the agent supports across all skills.
  // This can be overridden per skill. Defined as mime types.
  repeated string default_input_modes = 10;
  // The mime types supported as outputs from this agent.
  repeated string default_output_modes = 11;
  // Skills represent a unit of ability an agent can perform. This may
  // somewhat abstract but represents a more focused set of actions that the
  // agent is highly likely to succeed at.
  repeated AgentSkill skills = 12;
  // Whether the agent supports providing an extended agent card when
  // the user is authenticated, i.e. is the card from .well-known
  // different than the card from GetAgentCard.
  bool supports_authenticated_extended_card = 13;
  // JSON Web Signatures computed for this AgentCard.
  repeated AgentCardSignature signatures = 17;
  // An optional URL to an icon for the agent.
  string icon_url = 18;
}

5.5.1. AgentProvider 对象

有关提供智能体的组织或实体的信息。

/**
 * Represents the service provider of an agent.
 *
 * @TJS-examples [{ "organization": "Google", "url": "https://ai.google.dev" }]
 */
export interface AgentProvider {
  /** The name of the agent provider's organization. */
  organization: string;
  /** A URL for the agent provider's website or relevant documentation. */
  url: string;
}
// Represents information about the service provider of an agent.
message AgentProvider {
  // The providers reference url
  // Example: "https://ai.google.dev"
  string url = 1;
  // The providers organization name
  // Example: "Google"
  string organization = 2;
}

5.5.2. AgentCapabilities 对象

指定智能体支持的可选 A2A 协议功能。

/**
 * Defines optional capabilities supported by an agent.
 */
export interface AgentCapabilities {
  /** Indicates if the agent supports Server-Sent Events (SSE) for streaming responses. */
  streaming?: boolean;
  /** Indicates if the agent supports sending push notifications for asynchronous task updates. */
  pushNotifications?: boolean;
  /** Indicates if the agent provides a history of state transitions for a task. */
  stateTransitionHistory?: boolean;
  /** A list of protocol extensions supported by the agent. */
  extensions?: AgentExtension[];
}
// Defines the A2A feature set supported by the agent
message AgentCapabilities {
  // If the agent will support streaming responses
  bool streaming = 1;
  // If the agent can send push notifications to the clients webhook
  bool push_notifications = 2;
  // Extensions supported by this agent.
  repeated AgentExtension extensions = 3;
}

5.5.2.1. AgentExtension 对象

指定智能体支持的 A2A 协议扩展。

/**
 * A declaration of a protocol extension supported by an Agent.
 *
 * @TJS-examples [{"uri": "https://developers.google.com/identity/protocols/oauth2", "description": "Google OAuth 2.0 authentication", "required": false}]
 */
export interface AgentExtension {
  /** The unique URI identifying the extension. */
  uri: string;
  /** A human-readable description of how this agent uses the extension. */
  description?: string;
  /**
   * If true, the client must understand and comply with the extension's requirements
   * to interact with the agent.
   */
  required?: boolean;
  /** Optional, extension-specific configuration parameters. */
  params?: { [key: string]: any };
}
// A declaration of an extension supported by an Agent.
message AgentExtension {
  // The URI of the extension.
  // Example: "https://developers.google.com/identity/protocols/oauth2"
  string uri = 1;
  // A description of how this agent uses this extension.
  // Example: "Google OAuth 2.0 authentication"
  string description = 2;
  // Whether the client must follow specific requirements of the extension.
  // Example: false
  bool required = 3;
  // Optional configuration for the extension.
  google.protobuf.Struct params = 4;
}

5.5.3. SecurityScheme 对象

描述访问智能体 url 端点的认证要求。有关示例,请参见示例 Agent Card

/**
 * Defines a security scheme that can be used to secure an agent's endpoints.
 * This is a discriminated union type based on the OpenAPI 3.0 Security Scheme Object.
 *
 * @see {@link https://swagger.io/specification/#security-scheme-object}
 */
export type SecurityScheme =
  | APIKeySecurityScheme
  | HTTPAuthSecurityScheme
  | OAuth2SecurityScheme
  | OpenIdConnectSecurityScheme
  | MutualTLSSecurityScheme;
message SecurityScheme {
  oneof scheme {
    APIKeySecurityScheme api_key_security_scheme = 1;
    HTTPAuthSecurityScheme http_auth_security_scheme = 2;
    OAuth2SecurityScheme oauth2_security_scheme = 3;
    OpenIdConnectSecurityScheme open_id_connect_security_scheme = 4;
    MutualTlsSecurityScheme mtls_security_scheme = 5;
  }
}

5.5.4. AgentSkill 对象

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

/**
 * Represents a distinct capability or function that an agent can perform.
 */
export interface AgentSkill {
  /** A unique identifier for the agent's skill. */
  id: string;
  /** A human-readable name for the skill. */
  name: string;
  /**
   * A detailed description of the skill, intended to help clients or users
   * understand its purpose and functionality.
   */
  description: string;
  /**
   * A set of keywords describing the skill's capabilities.
   *
   * @TJS-examples [["cooking", "customer support", "billing"]]
   */
  tags: string[];
  /**
   * Example prompts or scenarios that this skill can handle. Provides a hint to
   * the client on how to use the skill.
   *
   * @TJS-examples [["I need a recipe for bread"]]
   */
  examples?: string[];
  /**
   * The set of supported input MIME types for this skill, overriding the agent's defaults.
   */
  inputModes?: string[];
  /**
   * The set of supported output MIME types for this skill, overriding the agent's defaults.
   */
  outputModes?: string[];
  /**
   * Security schemes necessary for the agent to leverage this skill.
   * As in the overall AgentCard.security, this list represents a logical OR of security
   * requirement objects. Each object is a set of security schemes that must be used together
   * (a logical AND).
   *
   * @TJS-examples [[{"google": ["oidc"]}]]
   */
  security?: { [scheme: string]: string[] }[];
}
// AgentSkill represents a unit of action/solution that the agent can perform.
// One can think of this as a type of highly reliable solution that an agent
// can be tasked to provide. Agents have the autonomy to choose how and when
// to use specific skills, but clients should have confidence that if the
// skill is defined that unit of action can be reliably performed.
message AgentSkill {
  // Unique identifier of the skill within this agent.
  string id = 1;
  // A human readable name for the skill.
  string name = 2;
  // A human (or llm) readable description of the skill
  // details and behaviors.
  string description = 3;
  // A set of tags for the skill to enhance categorization/utilization.
  // Example: ["cooking", "customer support", "billing"]
  repeated string tags = 4;
  // A set of example queries that this skill is designed to address.
  // These examples should help the caller to understand how to craft requests
  // to the agent to achieve specific goals.
  // Example: ["I need a recipe for bread"]
  repeated string examples = 5;
  // Possible input modalities supported.
  repeated string input_modes = 6;
  // Possible output modalities produced
  repeated string output_modes = 7;
  // protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
  // Security schemes necessary for the agent to leverage this skill.
  // As in the overall AgentCard.security, this list represents a logical OR of
  // security requirement objects. Each object is a set of security schemes
  // that must be used together (a logical AND).
  repeated Security security = 8;
  // protolint:enable REPEATED_FIELD_NAMES_PLURALIZED
}

5.5.5. AgentInterface 对象

提供目标 URL 和支持的传输组合的声明,用于与智能体交互。这使智能体能够通过多种传输协议暴露相同的功能。

/**
 * Supported A2A transport protocols.
 */
export enum TransportProtocol {
  JSONRPC = "JSONRPC", // JSON-RPC 2.0 over HTTP (mandatory)
  GRPC = "GRPC", // gRPC over HTTP/2 (optional)
  HTTP_JSON = "HTTP+JSON", // REST-style HTTP with JSON (optional)
}
/**
 * Declares a combination of a target URL and a transport protocol for interacting with the agent.
 * This allows agents to expose the same functionality over multiple transport mechanisms.
 */
export interface AgentInterface {
  /**
   * The URL where this interface is available. Must be a valid absolute HTTPS URL in production.
   * @TJS-examples ["https://api.example.com/a2a/v1", "https://grpc.example.com/a2a", "https://rest.example.com/v1"]
   */
  url: string;
  /**
   * The transport protocol supported at this URL.
   *
   * @TJS-examples ["JSONRPC", "GRPC", "HTTP+JSON"]
   */
  transport: TransportProtocol | string;
}
// Defines additional transport information for the agent.
message AgentInterface {
  // The url this interface is found at.
  string url = 1;
  // The transport supported this url. This is an open form string, to be
  // easily extended for many transport protocols. The core ones officially
  // supported are JSONRPC, GRPC and HTTP+JSON.
  string transport = 2;
}

transport 字段 应该 使用核心 A2A 传输协议值之一:

  • "JSONRPC": HTTP 上的 JSON-RPC 2.0
  • "GRPC": HTTP/2 上的 gRPC
  • "HTTP+JSON": REST 风格的 HTTP 与 JSON

可以 使用附加传输值用于未来扩展,但此类扩展 不得 与核心 A2A 协议功能冲突。

5.5.6. AgentCardSignature 对象

表示用于验证 AgentCard 完整性的 JSON Web 签名 (JWS)。

/**
 * AgentCardSignature represents a JWS signature of an AgentCard.
 * This follows the JSON format of an RFC 7515 JSON Web Signature (JWS).
 */
export interface AgentCardSignature {
  /**
   * The protected JWS header for the signature. This is a Base64url-encoded
   * JSON object, as per RFC 7515.
   */
  protected: string;
  /** The computed signature, Base64url-encoded. */
  signature: string;
  /** The unprotected JWS header values. */
  header?: { [key: string]: any };
}
// AgentCardSignature represents a JWS signature of an AgentCard.
// This follows the JSON format of an RFC 7515 JSON Web Signature (JWS).
message AgentCardSignature {
  // The protected JWS header for the signature. This is always a
  // base64url-encoded JSON object. Required.
  string protected = 1 [(google.api.field_behavior) = REQUIRED];
  // The computed signature, base64url-encoded. Required.
  string signature = 2 [(google.api.field_behavior) = REQUIRED];
  // The unprotected JWS header values.
  google.protobuf.Struct header = 3;
}

5.6. 传输声明和 URL 关系

AgentCard 必须 正确声明 URL 和传输协议之间的关系:

5.6.1. 主 URL 和首选传输

  • 主 URL 要求url 字段 必须 指定智能体的主要端点。
  • 传输对应关系:主 url 处可用的传输协议 必须preferredTransport 字段匹配。
  • 必需声明preferredTransport 字段是 必需的必须 存在于每个 AgentCard 中。
  • 传输可用性:主 url 必须 支持在 preferredTransport 中声明的传输协议。

5.6.2. 附加接口

  • URL 唯一性additionalInterfaces 中的每个 AgentInterface 应该 指定不同的 URL 以确保清晰度,但如果多个传输协议在相同端点可用,则 可以 重用 URL。
  • 传输声明:每个 AgentInterface 必须 准确声明其指定 URL 处可用的传输协议。
  • 完整性additionalInterfaces 数组 应该 包括所有支持的传输,包括主 URL 的传输以确保完整性。

5.6.3. 客户端传输选择规则

客户端 必须 遵循选择传输时的这些规则:

  1. 解析传输声明:从主 url/preferredTransport 组合和所有 additionalInterfaces 中提取可用传输。
  2. 首选声明偏好:如果客户端支持 preferredTransport,它 应该 使用主 url
  3. 回退选择:如果首选传输不受客户端支持,它 可以additionalInterfaces 中选择任何支持的传输。
  4. 优雅降级:客户端 应该 实现回退逻辑,如果首选传输失败,则尝试替代传输。
  5. URL-传输匹配:客户端 必须 使用 AgentCard 中声明的所选传输协议的正确 URL。

5.6.4. 验证要求

AgentCard 必须 满足这些验证要求:

  • 传输一致性preferredTransport必须 存在,必须 在主 url 处可用。
  • 接口完整性:如果提供了 additionalInterfaces,它 应该 包括与主 urlpreferredTransport 对应的条目。
  • 无冲突:同一 URL 不得 在不同接口声明中声明冲突的传输协议。
  • 最小传输要求:智能体 必须 通过主 url/preferredTransport 组合或 additionalInterfaces 声明至少一个支持的传输协议。

5.7. 示例 Agent Card

{
  "protocolVersion": "0.2.9",
  "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",
  "preferredTransport": "JSONRPC",
  "additionalInterfaces" : [
    {"url": "https://georoute-agent.example.com/a2a/v1", "transport": "JSONRPC"},
    {"url": "https://georoute-agent.example.com/a2a/grpc", "transport": "GRPC"},
    {"url": "https://georoute-agent.example.com/a2a/json", "transport": "HTTP+JSON"}
  ],
  "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,
  "signatures": [
    {
      "protected": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJrZXktMSIsImprdSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWdlbnQvandrcy5qc29uIn0",
      "signature": "QFdkNLNszlGj3z3u0YQGt_T9LixY3qtdQpZmsTdDHDe3fXV9y9-B3m2-XgCpzuhiLt8E0tV6HXoZKHv4GtHgKQ"
    }
  ]
}

6. 协议数据对象

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

6.1. Task 对象

表示 A2A 服务器为 A2A 客户端处理的工作的有状态单元。任务封装了与特定目标或请求相关的整个交互。已达到终止状态(completed、canceled、rejected 或 failed)的任务无法重启。处于完成状态的任务 应该 使用工件向客户端返回生成的输出。有关更多信息,请参阅任务生命周期指南

/**
 * Represents a single, stateful operation or conversation between a client and an agent.
 */
export interface Task {
  /** A unique identifier (e.g. UUID) for the task, generated by the server for a new task. */
  id: string;
  /**
   * A server-generated unique identifier (e.g. UUID) for maintaining context across multiple related tasks or interactions.
   */
  contextId: string;
  /** The current status of the task, including its state and a descriptive message. */
  status: TaskStatus;
  /** An array of messages exchanged during the task, representing the conversation history. */
  history?: Message[];
  /** A collection of artifacts generated by the agent during the execution of the task. */
  artifacts?: Artifact[];
  /** Optional metadata for extensions. The key is an extension-specific identifier. */
  metadata?: {
    [key: string]: any;
  };
  /** The type of this object, used as a discriminator. Always 'task' for a Task. */
  readonly kind: "task";
}
// Task is the core unit of action for A2A. It has a current status
// and when results are created for the task they are stored in the
// artifact. If there are multiple turns for a task, these are stored in
// history.
message Task {
  // Unique identifier (e.g. UUID) for the task, generated by the server for a
  // new task.
  string id = 1;
  // Unique identifier (e.g. UUID) for the contextual collection of interactions
  // (tasks and messages). Created by the A2A server.
  string context_id = 2;
  // The current status of a Task, including state and a message.
  TaskStatus status = 3;
  // A set of output artifacts for a Task.
  repeated Artifact artifacts = 4;
  // protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
  // The history of interactions from a task.
  repeated Message history = 5;
  // protolint:enable REPEATED_FIELD_NAMES_PLURALIZED
  // A key/value object to store custom metadata about a task.
  google.protobuf.Struct metadata = 6;
}

6.2. TaskStatus 对象

表示 Task 的当前状态和相关上下文(例如,来自智能体的消息)。

/**
 * Represents the status of a task at a specific point in time.
 */
export interface TaskStatus {
  /** The current state of the task's lifecycle. */
  state: TaskState;
  /** An optional, human-readable message providing more details about the current status. */
  message?: Message;
  /**
   * An ISO 8601 datetime string indicating when this status was recorded.
   *
   * @TJS-examples ["2023-10-27T10:00:00Z"]
   */
  timestamp?: string;
}
// A container for the status of a task
message TaskStatus {
  // The current state of this task
  TaskState state = 1;
  // A message associated with the status.
  Message update = 2 [json_name = "message"];
  // Timestamp when the status was recorded.
  // Example: "2023-10-27T10:00:00Z"
  google.protobuf.Timestamp timestamp = 3;
}

6.3. TaskState 枚举

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

/**
 * Defines the lifecycle states of a Task.
 */
export enum TaskState {
  /** The task has been submitted and is awaiting execution. */
  Submitted = "submitted",
  /** The agent is actively working on the task. */
  Working = "working",
  /** The task is paused and waiting for input from the user. */
  InputRequired = "input-required",
  /** The task has been successfully completed. */
  Completed = "completed",
  /** The task has been canceled by the user. */
  Canceled = "canceled",
  /** The task failed due to an error during execution. */
  Failed = "failed",
  /** The task was rejected by the agent and was not started. */
  Rejected = "rejected",
  /** The task requires authentication to proceed. */
  AuthRequired = "auth-required",
  /** The task is in an unknown or indeterminate state. */
  Unknown = "unknown",
}
// The set of states a Task can be in.
enum TaskState {
  TASK_STATE_UNSPECIFIED = 0;
  // Represents the status that acknowledges a task is created
  TASK_STATE_SUBMITTED = 1;
  // Represents the status that a task is actively being processed
  TASK_STATE_WORKING = 2;
  // Represents the status a task is finished. This is a terminal state
  TASK_STATE_COMPLETED = 3;
  // Represents the status a task is done but failed. This is a terminal state
  TASK_STATE_FAILED = 4;
  // Represents the status a task was cancelled before it finished.
  // This is a terminal state.
  TASK_STATE_CANCELLED = 5;
  // Represents the status that the task requires information to complete.
  // This is an interrupted state.
  TASK_STATE_INPUT_REQUIRED = 6;
  // Represents the status that the agent has decided to not perform the task.
  // This may be done during initial task creation or later once an agent
  // has determined it can't or won't proceed. This is a terminal state.
  TASK_STATE_REJECTED = 7;
  // Represents the state that some authentication is needed from the upstream
  // client. Authentication is expected to come out-of-band thus this is not
  // an interrupted or terminal state.
  TASK_STATE_AUTH_REQUIRED = 8;
}

6.4. Message 对象

表示客户端和智能体之间的一次通信或一段上下文信息。消息用于指令、提示、回复和状态更新。

/**
 * Represents a single message in the conversation between a user and an agent.
 */
export interface Message {
  /** Identifies the sender of the message. `user` for the client, `agent` for the service. */
  readonly role: "user" | "agent";
  /**
   * An array of content parts that form the message body. A message can be
   * composed of multiple parts of different types (e.g., text and files).
   */
  parts: Part[];
  /** Optional metadata for extensions. The key is an extension-specific identifier. */
  metadata?: {
    [key: string]: any;
  };
  /** The URIs of extensions that are relevant to this message. */
  extensions?: string[];
  /**
   * A list of other task IDs that this message references for additional context.
   */
  referenceTaskIds?: string[];
  /**
   * A unique identifier for the message, typically a UUID, generated by the sender.
   */
  messageId: string;
  /**
   * The ID of the task this message is part of. Can be omitted for the first message of a new task.
   */
  taskId?: string;
  /**
   * The context ID for this message, used to group related interactions.
   */
  contextId?: string;
  /** The type of this object, used as a discriminator. Always 'message' for a Message. */
  readonly kind: "message";
}
// Message is one unit of communication between client and server. It is
// associated with a context and optionally a task. Since the server is
// responsible for the context definition, it must always provide a context_id
// in its messages. The client can optionally provide the context_id if it
// knows the context to associate the message to. Similarly for task_id,
// except the server decides if a task is created and whether to include the
// task_id.
message Message {
  // The unique identifier (e.g. UUID)of the message. This is required and
  // created by the message creator.
  string message_id = 1;
  // The context id of the message. This is optional and if set, the message
  // will be associated with the given context.
  string context_id = 2;
  // The task id of the message. This is optional and if set, the message
  // will be associated with the given task.
  string task_id = 3;
  // A role for the message.
  Role role = 4;
  // protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
  // Content is the container of the message content.
  repeated Part content = 5;
  // protolint:enable REPEATED_FIELD_NAMES_PLURALIZED
  // Any optional metadata to provide along with the message.
  google.protobuf.Struct metadata = 6;
  // The URIs of extensions that are present or contributed to this Message.
  repeated string extensions = 7;
}

6.5. Part 联合类型

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

/**
 * A discriminated union representing a part of a message or artifact, which can
 * be text, a file, or structured data.
 */
export type Part = TextPart | FilePart | DataPart;
// Part represents a container for a section of communication content.
// Parts can be purely textual, some sort of file (image, video, etc) or
// a structured data blob (i.e. JSON).
message Part {
  oneof part {
    string text = 1;
    FilePart file = 2;
    DataPart data = 3;
  }
  // Optional metadata associated with this part.
  google.protobuf.Struct metadata = 4;
}
/**
 * Defines base properties common to all message or artifact parts.
 */
export interface PartBase {
  /** Optional metadata associated with this part. */
  metadata?: {
    [key: string]: any;
  };
}

必须 是以下之一:

6.5.1. TextPart 对象

用于传达纯文本内容。

/**
 * Represents a text segment within a message or artifact.
 */
export interface TextPart extends PartBase {
  /** The type of this part, used as a discriminator. Always 'text'. */
  readonly kind: "text";
  /** The string content of the text part. */
  text: string;
}

6.5.2. FilePart 对象

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

/**
 * Represents a file segment within a message or artifact. The file content can be
 * provided either directly as bytes or as a URI.
 */
export interface FilePart extends PartBase {
  /** The type of this part, used as a discriminator. Always 'file'. */
  readonly kind: "file";
  /** The file content, represented as either a URI or as base64-encoded bytes. */
  file: FileWithBytes | FileWithUri;
}
// FilePart represents the different ways files can be provided. If files are
// small, directly feeding the bytes is supported via file_with_bytes. If the
// file is large, the agent should read the content as appropriate directly
// from the file_with_uri source.
message FilePart {
  oneof file {
    string file_with_uri = 1;
    bytes file_with_bytes = 2;
  }
  string mime_type = 3;
  string name = 4;
}

6.5.3. DataPart 对象

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

/**
 * Represents a structured data segment (e.g., JSON) within a message or artifact.
 */
export interface DataPart extends PartBase {
  /** The type of this part, used as a discriminator. Always 'data'. */
  readonly kind: "data";
  /** The structured data content. */
  data: {
    [key: string]: any;
  };
}
// DataPart represents a structured blob. This is most commonly a JSON payload.
message DataPart {
  google.protobuf.Struct data = 1;
}

6.6 FileBase 对象

文件内容的基础实体。

/**
 * Defines base properties for a file.
 */
export interface FileBase {
  /** An optional name for the file (e.g., "document.pdf"). */
  name?: string;
  /** The MIME type of the file (e.g., "application/pdf"). */
  mimeType?: string;
}

6.6.1 FileWithBytes 对象

表示文件的数据,用于 FilePart 中。

/**
 * Represents a file with its content provided directly as a base64-encoded string.
 */
export interface FileWithBytes extends FileBase {
  /** The base64-encoded content of the file. */
  bytes: string;
  /** The `uri` property must be absent when `bytes` is present. */
  uri?: never;
}

6.6.2 FileWithUri 对象

表示文件的 URI,用于 FilePart 中。

/**
 * Represents a file with its content located at a specific URI.
 */
export interface FileWithUri extends FileBase {
  /** A URL pointing to the file's content. */
  uri: string;
  /** The `bytes` property must be absent when `uri` is present. */
  bytes?: never;
}

6.7. Artifact 对象

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

/**
 * Represents a file, data structure, or other resource generated by an agent during a task.
 */
export interface Artifact {
  /**
   * A unique identifier (e.g. UUID) for the artifact within the scope of the task.
   */
  artifactId: string;
  /** An optional, human-readable name for the artifact. */
  name?: string;
  /** An optional, human-readable description of the artifact. */
  description?: string;
  /** An array of content parts that make up the artifact. */
  parts: Part[];
  /** Optional metadata for extensions. The key is an extension-specific identifier. */
  metadata?: {
    [key: string]: any;
  };
  /** The URIs of extensions that are relevant to this artifact. */
  extensions?: string[];
}
// Artifacts are the container for task completed results. These are similar
// to Messages but are intended to be the product of a task, as opposed to
// point-to-point communication.
message Artifact {
  // Unique identifier (e.g. UUID) for the artifact. It must be at least unique
  // within a task.
  string artifact_id = 1;
  // A human readable name for the artifact.
  string name = 3;
  // A human readable description of the artifact, optional.
  string description = 4;
  // The content of the artifact.
  repeated Part parts = 5;
  // Optional metadata included with the artifact.
  google.protobuf.Struct metadata = 6;
  // The URIs of extensions that are present or contributed to this Artifact.
  repeated string extensions = 7;
}

6.8. PushNotificationConfig 对象

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

/**
 * Defines the configuration for setting up push notifications for task updates.
 */
export interface PushNotificationConfig {
  /**
   * A unique identifier (e.g. UUID) for the push notification configuration, set by the client
   * to support multiple notification callbacks.
   */
  id?: string;
  /** The callback URL where the agent should send push notifications. */
  url: string;
  /** A unique token for this task or session to validate incoming push notifications. */
  token?: string;
  /** Optional authentication details for the agent to use when calling the notification URL. */
  authentication?: PushNotificationAuthenticationInfo;
}
// Configuration for setting up push notifications for task updates.
message PushNotificationConfig {
  // A unique identifier (e.g. UUID) for this push notification.
  string id = 1;
  // Url to send the notification too
  string url = 2;
  // Token unique for this task/session
  string token = 3;
  // Information about the authentication to sent with the notification
  AuthenticationInfo authentication = 4;
}

6.9. PushNotificationAuthenticationInfo 对象

指定认证要求的通用结构,通常在 PushNotificationConfig 中使用,以描述 A2A 服务器应如何向客户端的 webhook 进行认证。

/**
 * Defines authentication details for a push notification endpoint.
 */
export interface PushNotificationAuthenticationInfo {
  /** A list of supported authentication schemes (e.g., 'Basic', 'Bearer'). */
  schemes: string[];
  /** Optional credentials required by the push notification endpoint. */
  credentials?: string;
}
// Defines authentication details, used for push notifications.
message AuthenticationInfo {
  // Supported authentication schemes - e.g. Basic, Bearer, etc
  repeated string schemes = 1;
  // Optional credentials
  string credentials = 2;
}

6.10. TaskPushNotificationConfig 对象

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

/**
 * A container associating a push notification configuration with a specific task.
 */
export interface TaskPushNotificationConfig {
  /**
   * The unique identifier (e.g. UUID) of the task.
   */
  taskId: string;
  /** The push notification configuration for this task. */
  pushNotificationConfig: PushNotificationConfig;
}
message TaskPushNotificationConfig {
  // The resource name of the config.
  // Format: tasks/{task_id}/pushNotificationConfigs/{config_id}
  string name = 1;
  // The push notification configuration details.
  PushNotificationConfig push_notification_config = 2;
}

6.11. JSON-RPC 结构

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

6.11.1. JSONRPCRequest 对象

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

  • jsonrpc:指定 JSON-RPC 协议版本的字符串。必须 恰好是 "2.0"
  • method:包含要调用的方法名称的字符串(例如,"message/send""tasks/get")。
  • params:包含在调用方法期间使用的参数值的结构化值。如果方法不需要参数,此成员 可以 省略。A2A 方法通常对 params 使用 object
  • id:由客户端建立的标识符,如果包含,必须 包含字符串、数字或 NULL 值。如果不包含,则假定为通知。对于期望响应的请求,该值 不应NULL,数字 不应 包含小数部分。如果包含,服务器 必须 在响应对象中使用相同的值。此成员用于关联两个对象之间的上下文。A2A 方法通常期望响应或流,因此 id 通常存在且非空。

6.11.2. JSONRPCResponse 对象

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

  • jsonrpc:指定 JSON-RPC 协议版本的字符串。必须 恰好是 "2.0"
  • id:此成员是 必需的。它 必须 与请求对象中 id 成员的值相同。如果在请求对象中检测 id 时出现错误(例如,解析错误/无效请求),它 必须null
  • 或者 result:此成员在成功时是 必需的。如果调用方法时出现错误,则 不得 存在。此成员的值由服务器上调用的方法确定。
  • 或者 error:此成员在失败时是 必需的。如果调用期间未触发错误,则 不得 存在。此成员的值 必须JSONRPCError 对象。
  • 成员 resulterror 是互斥的:一个 必须 存在,另一个 必须 不存在。

6.12. JSONRPCError 对象

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

/**
 * Represents a JSON-RPC 2.0 Error object, included in an error response.
 */
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 containing additional information about the error.
   * This may be omitted.
   */
  data?: any;
}

7. 协议 RPC 方法

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

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

7.1. message/send

向智能体发送消息以启动新交互或继续现有交互。此方法适用于同步请求/响应交互,或者当客户端轮询(使用 tasks/get)监视长时间运行的任务时可接受。已达到终止状态(completed、canceled、rejected 或 failed)的任务无法重启。向此类任务发送消息将导致错误。有关更多信息,请参阅任务生命周期指南

  • URL: message/send
  • HTTP 方法: POST
  • 载荷: MessageSendParams
  • 响应: Task | Message(消息对象或处理消息后任务的当前或最终状态)。
  • URL: SendMessage
  • HTTP 方法: POST
  • 载荷:
    message SendMessageRequest {
      Message msg = 1;
      SendMessageConfiguration configuration = 2;
    }
    
  • 响应:
    message SendMessageResponse {
      oneof payload {
        Task task = 1;
        Message msg = 2;
      }
    }
    
  • URL: /v1/message:send
  • HTTP 方法: POST
  • 载荷:
    {
      message: Message,
      configuration?: MessageSendConfiguration,
      metadata?: { [key: string]: any }
    }
    
  • 响应:
    // 返回消息或任务之一
    {
      message?: Message,
      task?: Task
    }
    

所有传输在失败时的 error 响应是 JSONRPCError 或等效对象。

7.1.1. MessageSendParams 对象

/**
 * Defines the parameters for a request to send a message to an agent. This can be used
 * to create a new task, continue an existing one, or restart a task.
 */
export interface MessageSendParams {
  /** The message object being sent to the agent. */
  message: Message;
  /** Optional configuration for the send request. */
  configuration?: MessageSendConfiguration;
  /** Optional metadata for extensions. */
  metadata?: {
    [key: string]: any;
  };
}
message SendMessageRequest {
  // The message to send to the agent.
  Message request = 1
      [(google.api.field_behavior) = REQUIRED, json_name = "message"];
  // Configuration for the send request.
  SendMessageConfiguration configuration = 2;
  // Optional metadata for the request.
  google.protobuf.Struct metadata = 3;
}
/**
 * Defines configuration options for a `message/send` or `message/stream` request.
 */
export interface MessageSendConfiguration {
  /** A list of output MIME types the client is prepared to accept in the response. */
  acceptedOutputModes?: string[];
  /** The number of most recent messages from the task's history to retrieve in the response. */
  historyLength?: number;
  /** Configuration for the agent to send push notifications for updates after the initial response. */
  pushNotificationConfig?: PushNotificationConfig;
  /** If true, the client will wait for the task to complete. The server may reject this if the task is long-running. */
  blocking?: boolean;
}
// Configuration of a send message request.
message SendMessageConfiguration {
  // The output modes that the agent is expected to respond with.
  repeated string accepted_output_modes = 1;
  // A configuration of a webhook that can be used to receive updates
  PushNotificationConfig push_notification = 2;
  // The maximum number of messages to include in the history. if 0, the
  // history will be unlimited.
  int32 history_length = 3;
  // If true, the message will be blocking until the task is completed. If
  // false, the message will be non-blocking and the task will be returned
  // immediately. It is the caller's responsibility to check for any task
  // updates.
  bool blocking = 4;
}

7.2. message/stream

向智能体发送消息以启动/继续任务 订阅客户端通过服务器发送事件 (SSE) 实时更新该任务。此方法要求服务器具有 AgentCard.capabilities.streaming: true。就像 message/send 一样,已达到终止状态(completed、canceled、rejected 或 failed)的任务无法重启。向此类任务发送消息将导致错误。有关更多信息,请参阅任务生命周期指南

  • URL: SendStreamingMessage
  • HTTP 方法: POST
  • 载荷:
    message SendMessageRequest {
      Message msg = 1;
      SendMessageConfiguration configuration = 2;
    }
    
  • 响应:
    message StreamResponse {
      oneof payload {
        Task task;
        Message msg;
        TaskStatusUpdateEvent status_update;
        TaskArtifactUpdateEvent artifact_update;
      }
    }
    
  • URL: /v1/message:stream
  • HTTP 方法: POST
  • 载荷:
    {
      message: Message,
      configuration?: MessageSendConfiguration,
      metadata?: { [key: string]: any }
    }
    
  • 响应:
    {
      message?: Message
      task?: Task
      statusUpdate?: TaskStatusUpdateEvent
      artifactUpdate?: TaskArtifactUpdateEvent
    }
    

7.2.1. SendStreamingMessageResponse 对象

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

/**
 * Represents a JSON-RPC response for the `message/stream` method.
 */
export type SendStreamingMessageResponse =
  | SendStreamingMessageSuccessResponse
  | JSONRPCErrorResponse;
/**
 * Represents a successful JSON-RPC response for the `message/stream` method.
 * The server may send multiple response objects for a single request.
 */
export interface SendStreamingMessageSuccessResponse
  extends JSONRPCSuccessResponse {
  /** The result, which can be a Message, Task, or a streaming update event. */
  result: Message | Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent;
}
// The stream response for a message. The stream should be one of the following
// sequences:
// If the response is a message, the stream should contain one, and only one,
// message and then close
// If the response is a task lifecycle, the first response should be a Task
// object followed by zero or more TaskStatusUpdateEvents and
// TaskArtifactUpdateEvents. The stream should complete when the Task
// if in an interrupted or terminal state. A stream that ends before these
// conditions are met are
message StreamResponse {
  oneof payload {
    Task task = 1;
    Message msg = 2 [json_name = "message"];
    TaskStatusUpdateEvent status_update = 3;
    TaskArtifactUpdateEvent artifact_update = 4;
  }
}

7.2.2. TaskStatusUpdateEvent 对象

在流式传输过程中携带任务状态更改的信息。这是 SendStreamingMessageSuccessResponseresult 类型之一。

/**
 * An event sent by the agent to notify the client of a change in a task's status.
 * This is typically used in streaming or subscription models.
 */
export interface TaskStatusUpdateEvent {
  /**
   * The ID of the task that was updated.
   */
  taskId: string;
  /**
   * The context ID associated with the task.
   */
  contextId: string;
  /** The type of this event, used as a discriminator. Always 'status-update'. */
  readonly kind: "status-update";
  /** The new status of the task. */
  status: TaskStatus;
  /** If true, this is the final event in the stream for this interaction. */
  final: boolean;
  /** Optional metadata for extensions. */
  metadata?: {
    [key: string]: any;
  };
}
// TaskStatusUpdateEvent is a delta even on a task indicating that a task
// has changed.
message TaskStatusUpdateEvent {
  // The id of the task that is changed
  string task_id = 1;
  // The id of the context that the task belongs to
  string context_id = 2;
  // The new status of the task.
  TaskStatus status = 3;
  // Whether this is the last status update expected for this task.
  bool final = 4;
  // Optional metadata to associate with the task update.
  google.protobuf.Struct metadata = 5;
}

7.2.3. TaskArtifactUpdateEvent 对象

在流式传输过程中携带任务生成的新工件或更新工件(或工件块)。这是 SendTaskStreamingResponseresult 类型之一。

/**
 * An event sent by the agent to notify the client that an artifact has been
 * generated or updated. This is typically used in streaming models.
 */
export interface TaskArtifactUpdateEvent {
  /**
   * The ID of the task this artifact belongs to.
   */
  taskId: string;
  /**
   * The context ID associated with the task.
   */
  contextId: string;
  /** The type of this event, used as a discriminator. Always 'artifact-update'. */
  readonly kind: "artifact-update";
  /** The artifact that was generated or updated. */
  artifact: Artifact;
  /** If true, the content of this artifact should be appended to a previously sent artifact with the same ID. */
  append?: boolean;
  /** If true, this is the final chunk of the artifact. */
  lastChunk?: boolean;
  /** Optional metadata for extensions. */
  metadata?: {
    [key: string]: any;
  };
}
// TaskArtifactUpdateEvent represents a task delta where an artifact has
// been generated.
message TaskArtifactUpdateEvent {
  // The id of the task for this artifact
  string task_id = 1;
  // The id of the context that this task belongs too
  string context_id = 2;
  // The artifact itself
  Artifact artifact = 3;
  //  Whether this should be appended to a prior one produced
  bool append = 4;
  // Whether this represents the last part of an artifact
  bool last_chunk = 5;
  // Optional metadata associated with the artifact update.
  google.protobuf.Struct metadata = 6;
}

7.3. tasks/get

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

  • URL: GetTask
  • HTTP 方法: POST
  • 载荷:
    message GetTaskRequest {
      // name=tasks/{id}
      string name;
      int32 history_length;
    }
    
  • 响应: Task
  • URL: v1/tasks/{id}?historyLength={historyLength}
  • HTTP 方法: GET
  • 载荷:
  • 响应: Task

7.3.1. TaskQueryParams 对象

/**
 * Defines parameters for querying a task, with an option to limit history length.
 */
export interface TaskQueryParams extends TaskIdParams {
  /** The number of most recent messages from the task's history to retrieve. */
  historyLength?: number;
}

7.4. tasks/cancel

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

  • URL: tasks/cancel
  • HTTP 方法: POST
  • 载荷: TaskIdParams
  • 响应: Task
  • URL: CancelTask
  • HTTP 方法: POST
  • 载荷:
    message CancelTaskRequest{
      // name=tasks/{id}
      string name;
    }
    
  • 响应: Task
  • URL: /v1/tasks/{id}:cancel
  • HTTP 方法: POST
  • 载荷:
    {
      name: string
    }
    
  • 响应: Task

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

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

/**
 * Defines parameters containing a task ID, used for simple task operations.
 */
export interface TaskIdParams {
  /**
   * The unique identifier (e.g. UUID) of the task.
   */
  id: string;
  /** Optional metadata associated with the request. */
  metadata?: {
    [key: string]: any;
  };
}

7.5. tasks/pushNotificationConfig/set

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

  • URL: CreateTaskPushNotification
  • HTTP 方法: POST
  • 载荷:
    message SetTaskPushNotificationRequest {
      TaskPushNotificationConfig config = 1;
    }
    
  • 响应: TaskPushNotificationConfig
  • URL: /v1/tasks/{id}/pushNotificationConfigs
  • HTTP 方法: POST
  • 载荷:
    {
      config: TaskPushNotificationConfig
    }
    
  • 响应: TaskPushNotificationConfig

7.6. tasks/pushNotificationConfig/get

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

  • URL: GetTaskPushNotification
  • HTTP 方法: POST
  • 载荷:
    message TaskSubscriptionRequest {
      // name=tasks/{id}/pushNotification/{id}
      string name;
    }
    
  • 响应: TaskPushNotificationConfig
  • URL: /v1/tasks/{taskId}/pushNotificationConfigs/{configId}
  • HTTP 方法: GET
  • 载荷:
  • 响应: TaskPushNotificationConfig

响应 error 类型(失败时): JSONRPCError(例如,PushNotificationNotSupportedErrorTaskNotFoundError)。

7.6.1. GetTaskPushNotificationConfigParams 对象(tasks/pushNotificationConfig/get

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

/**
 * Defines parameters for fetching a specific push notification configuration for a task.
 */
export interface GetTaskPushNotificationConfigParams extends TaskIdParams {
  /**
   * The ID of the push notification configuration to retrieve.
   */
  pushNotificationConfigId?: string;
}

7.7. tasks/pushNotificationConfig/list

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

  • URL: ListTaskPushNotification
  • HTTP 方法: POST
  • 载荷:
    message ListTaskPushNotificationRequest {
      // parent=tasks/{id}
      string parent = 1;
    }
    
  • 响应: repeated TaskPushNotificationConfig
  • URL: /v1/tasks/{id}/pushNotificationConfigs
  • HTTP 方法: GET
  • 载荷::无
  • 响应: [TaskPushNotificationConfig]

7.7.1. ListTaskPushNotificationConfigParams 对象(tasks/pushNotificationConfig/list

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

/**
 * Defines parameters for listing all push notification configurations associated with a task.
 */
export interface ListTaskPushNotificationConfigParams extends TaskIdParams {}

7.8. tasks/pushNotificationConfig/delete

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

7.8.1. DeleteTaskPushNotificationConfigParams 对象(tasks/pushNotificationConfig/delete

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

/**
 * Defines parameters for deleting a specific push notification configuration for a task.
 */
export interface DeleteTaskPushNotificationConfigParams extends TaskIdParams {
  /**
   * The ID of the push notification configuration to delete.
   */
  pushNotificationConfigId: string;
}

7.9. tasks/resubscribe

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

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

  • URL: TaskSubscription
  • HTTP 方法: POST
  • 载荷:
    message TaskSubscriptionRequest{
      // name=tasks/{id}
      string name;
    }
    
  • 响应:
    message StreamResponse {
      oneof payload {
        Task task;
        Message msg;
        TaskStatusUpdateEvent status_update;
        TaskArtifactUpdateEvent artifact_update;
      }
    }
    
  • URL: /v1/tasks/{id}:subscribe
  • HTTP 方法: POST
  • 载荷:
    {
      name: string
    }
    
  • 响应:
    {
      message?: Message
      task?: Task
      statusUpdate?: TaskStatusUpdateEvent
      artifactUpdate?: TaskArtifactUpdateEvent
    }
    

7.10. agent/getAuthenticatedExtendedCard

在客户端认证后检索可能更详细的 Agent Card 版本。仅当 AgentCard.supportsAuthenticatedExtendedCardtrue 时才可使用此端点。

  • 认证:客户端 必须 使用公共 AgentCard.securitySchemesAgentCard.security 字段中声明的方案之一对请求进行认证。
  • 响应 result 类型(成功时)AgentCard(完整的 Agent Card 对象,可能包含公共卡中不存在的附加详细信息或技能)。
  • 响应 error 类型(失败时):标准 HTTP 错误代码。
    • 401 Unauthorized:认证失败(缺少或无效凭据)。服务器 应该 包含 WWW-Authenticate 头。
  • URL: agent/getAuthenticatedExtendedCard
  • HTTP 方法: POST
  • 载荷:
  • 响应: AgentCard
  • URL: GetAgentCard
  • HTTP 方法: POST
  • 载荷:
  • 响应: AgentCard
  • URL: /v1/card
  • HTTP 方法: GET
  • 载荷:
  • 响应: AgentCard

获取此认证卡的客户端 应该 在其认证会话期间或直到卡版本更改时,用从此端点接收的内容替换其缓存的公共 Agent Card。

/**
 * Represents a successful JSON-RPC response for the `agent/getAuthenticatedExtendedCard` method.
 */
export interface GetAuthenticatedExtendedCardSuccessResponse
  extends JSONRPCSuccessResponse {
  /** The result is an Agent Card object. */
  result: AgentCard;
}

8. 错误处理

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

8.1. 标准 JSON-RPC 错误

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

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

8.2. A2A 特定错误

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

代码 错误名称(概念性) 典型的 message 字符串 描述
-32001 TaskNotFoundError 任务未找到 指定的任务 id 不对应于现有或活动任务。它可能是无效的、过期的或已完成并清除的。
-32002 TaskNotCancelableError 任务无法取消 尝试取消处于不可取消状态的任务(例如,它已达到终端状态如 completedfailedcanceled)。
-32003 PushNotificationNotSupportedError 不支持推送通知 客户端尝试使用推送通知功能(例如,tasks/pushNotificationConfig/set),但服务器智能体不支持它们(即,AgentCard.capabilities.pushNotificationsfalse)。
-32004 UnsupportedOperationError 此操作不受支持 请求的操作或其特定方面(可能由参数暗示)不被此服务器智能体实现支持。比方法未找到更广泛。
-32005 ContentTypeNotSupportedError 不兼容的内容类型 请求的 message.parts 中提供的 媒体类型(或工件隐含的)不被智能体或调用的特定技能支持。
-32006 InvalidAgentResponseError 无效的智能体响应类型 智能体为请求的方法生成了无效响应
-32007 AuthenticatedExtendedCardNotConfiguredError 未配置认证扩展卡 智能体未配置认证扩展卡。

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

9. 常见工作流和示例

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

9.1. 获取认证扩展 Agent Card

场景: 客户端发现一个公共 Agent Card,表明支持认证扩展卡,并希望获取完整详细信息。

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

服务器响应公共 Agent Card(如第 5.6 节中的示例),包括 supportsAuthenticatedExtendedCard: true(在根级别)和 securitySchemes

  1. 客户端从公共卡中识别所需的认证。

  2. 客户端通过带外获取必要的凭据(例如,使用 Google 执行 OAuth 2.0 流程,生成访问令牌)。

  3. 客户端使用 agent/getAuthenticatedExtendedCard 请求获取认证扩展 Agent Card:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "agent/getAuthenticatedExtendedCard"
}
  1. 服务器认证和授权请求。

  2. 服务器响应完整的 Agent Card 作为 JSON-RPC 结果:

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. 服务器处理请求,创建任务并响应(任务快速完成)
{
  "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": {}
  }
}

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

场景: 客户端提出一个简单问题,智能体快速响应而无需任务

  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": {}
  }
}

9.3. 流式任务执行(SSE)

场景: 客户端要求智能体写一篇描述附加图片的长论文。

  1. 客户端发送消息并使用 message/stream 订阅:
{
  "jsonrpc": "2.0",
  "id": 1,
  "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": [
        {"kind":"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": [
        {"kind":"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": [
        {"kind":"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. 客户端 message/send(提供所需输入,使用 相同 任务 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. 服务器处理新输入并响应(例如,任务完成或需要更多输入):
{
  "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. 客户端 message/sendpushNotification 配置:
{
  "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"]
          // 假设服务器知道如何获取用于此 webhook 受众的 Bearer 令牌,
          // 或者这暗示 webhook 是公共的/使用 'token' 进行认证。
          // 'credentials' 可以在服务器需要时提供更多细节。
        }
      }
    }
  }
}
  1. 服务器确认任务(例如,状态 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" }
    // ... 其他字段 ...
  }
}
  1. (稍后)A2A 服务器完成任务并向 https://client.example.com/webhook/a2a-notifications 发送 POST 通知:

  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 正文(任务对象作为 JSON 载荷发送):
{
  "id": "43667960-d455-4453-b0cf-1bae4955270d",
  "contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
  "status": { "state": "completed", "timestamp": "2024-03-15T18:30:00Z" },
  "kind": "task"
  // ... 其他字段 ...
}
  1. 客户端的 Webhook 服务:

  2. 接收 POST。

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

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

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

  1. 客户端 message/sendFilePart(上传图像字节):
{
  "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 编码的图像数据
          }
        }
      ],
      "messageId": "6dbc13b5-bd57-4c2b-b503-24e381b6c8d6"
    }
  }
}
  1. 服务器处理图像并响应 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",
              // 服务器可能提供临时存储位置的 URI
              "uri": "https://storage.example.com/processed/task-bbb/output.png?token=xyz"
              // 或者,或者返回字节:
              // "bytes": "ASEDGhw0KGgoAAAANSUhEUgAA..."
            }
          }
        ]
      }
    ],
    "kind": "task"
  }
}

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

场景: 客户端请求特定 JSON 格式的开放支持工单列表。

  1. 客户端 message/sendPart.metadata 暗示所需的输出模式/媒体类型: (注意:A2A 在 v0.2.0 中没有正式标准化模式协商,但可以按客户端/服务器之间的约定使用 metadata 进行此类暗示)。
{
  "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. 服务器响应结构化 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 服务器智能体执行复杂任务。服务器智能体反过来可能使用 MCP 与几个底层工具、API 或数据源交互,以收集信息或执行完成 A2A 任务所需的行动。

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

10.2. 安全考虑摘要

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

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

有关全面讨论,请参阅企业就绪功能指南

11. A2A 合规要求

本节定义了 A2A 合规实现的规范要求。

11.1. 智能体合规性

对于被认为是 A2A 合规 的智能体,它 必须

11.1.1. 传输支持要求

  • 支持至少一种传输:智能体 必须 实现第 3.2 节中定义的至少一种传输协议。
  • 暴露 Agent Card必须 提供有效的 AgentCard 文档,如第 5 节中定义。
  • 声明传输能力必须AgentCard 中准确声明所有支持的传输,使用 preferredTransportadditionalInterfaces 字段,遵循第 5.6 节中的要求。

11.1.2. 核心方法实现

必须 通过至少一种支持的传输实现以下所有核心方法:

  • message/send - 发送消息和启动任务
  • tasks/get - 检索任务状态和结果
  • tasks/cancel - 请求任务取消

11.1.3. 可选方法实现

可以 实现以下可选方法:

  • message/stream - 流式消息交互(需要 capabilities.streaming: true
  • tasks/resubscribe - 恢复现有任务的流式传输(需要 capabilities.streaming: true
  • tasks/pushNotificationConfig/set - 配置推送通知(需要 capabilities.pushNotifications: true
  • tasks/pushNotificationConfig/get - 检索推送通知配置(需要 capabilities.pushNotifications: true
  • tasks/pushNotificationConfig/list - 列出推送通知配置(需要 capabilities.pushNotifications: true
  • tasks/pushNotificationConfig/delete - 删除推送通知配置(需要 capabilities.pushNotifications: true
  • agent/authenticatedExtendedCard - 检索认证扩展 Agent Card(需要 supportsAuthenticatedExtendedCard: true

11.1.4. 多传输合规性

如果智能体支持附加传输(gRPC、HTTP+JSON),它 必须

  • 功能等效性:在所有支持的传输中提供相同的功能。
  • 一致行为:对相同操作返回语义上等效的结果。
  • 传输特定要求:符合第 3.2 节中为每个支持的传输定义的所有要求。
  • 方法映射合规性:使用第 3.5 节中定义的标准方法映射用于所有支持的传输。

11.1.5. 数据格式合规性

  • JSON-RPC 结构必须 使用第 6.11 节中定义的有效 JSON-RPC 2.0 请求/响应对象。
  • A2A 数据对象必须 使用第 6 节中定义的数据结构用于所有协议实体。
  • 错误处理必须 使用第 8 节中定义的错误代码。

11.2. 客户端合规性

对于被认为是 A2A 合规 的客户端,它 必须

11.2.1. 传输支持

  • 多传输能力必须 能够与使用至少一种传输协议的智能体通信。
  • Agent Card 处理必须 能够解析和解释 AgentCard 文档。
  • 传输选择必须 能够从智能体声明的能力中选择适当的传输,遵循第 5.6.3 节中定义的规则。

11.2.2. 协议实现

  • 核心方法使用必须 正确构造至少 message/sendtasks/get 方法的请求。
  • 错误处理必须 正确处理第 8.2 节中定义的所有 A2A 错误代码。
  • 认证必须 在与需要认证的智能体交互时支持至少一种认证方法。

11.2.3. 可选客户端功能

客户端 可以 实现:

  • 多传输支持:支持 gRPC 和/或 HTTP+JSON 传输。
  • 流式支持:处理流式方法和服务器发送事件。
  • 推送通知处理:作为推送通知的 webhook 端点。
  • 扩展 Agent Card:检索和使用认证扩展 Agent Card。

11.3. 合规测试

实现 应该 通过以下方式验证合规性:

  • 传输互操作性:测试与使用不同传输实现的智能体通信。
  • 方法映射验证:验证所有支持的传输使用第 3.5 节中定义的正确方法名称和 URL 模式。
  • 错误处理:验证对所有定义的错误条件的正确处理。
  • 数据格式验证:确保 JSON 模式与 types/src/types.ts 中的 TypeScript 类型定义匹配。
  • 多传输一致性:对于多传输智能体,验证所有支持的传输之间的功能等效性。