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 中的最小内容单位(例如TextPart、FilePart、DataPart)。
人工制品: 代理作为任务的结果生成的输出(例如,文档、图像、结构化数据),由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/stream 或 tasks/resubscribe 等方法时:
服务器使用 HTTP200 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. 客户端/用户身份和身份验证过程 ¶
发现需求: 客户端通过AgentCard中的authentication字段发现服务器所需的身份验证方案。方案名称通常与 OpenAPI 身份验证方法一致(例如,“Bearer” 表示 OAuth 2.0 令牌,“Basic” 表示基本身份验证,“ApiKey” 表示 API 密钥)。
凭证获取(带外): 客户端通过特定于所需身份验证方案和身份提供商的带外过程获取必要的凭证(例如 API 密钥、OAuth 令牌、JWT)。此过程超出了 A2A 协议本身的范围。
凭证传输: 客户端将这些凭证包含在发送到服务器的每个 A2A 请求的相应 HTTP 标头 (例如,Authorization: Bearer <token>,X-API-Key: <value>)中。
4.4. 服务器身份验证责任 ¶
A2A 服务器:
必须根据提供的 HTTP 凭据及其从代理卡声明的身份验证要求对每个传入请求进行身份验证。
应使用标准 HTTP 状态代码(例如401 未授权或403 禁止)进行身份验证质询或拒绝。
应包含相关的 HTTP 标头(例如WWW-Authenticate)以及401 Unauthorized响应,以指明所需的身份验证方案,从而为客户端提供指导。
4.5. 任务内身份验证(辅助凭证)¶
如果代理在执行任务期间需要其他系统或资源的额外凭证(例如,代表需要自己身份验证的用户访问特定工具):
它应该将 A2A 任务转换为auth-required状态(请参阅TaskState)。
随附的TaskStatus.message(通常是DataPart) 应提供有关所需辅助身份验证的详细信息,可能使用类似PushNotificationAuthenticationInfo-的结构来描述需求。
然后,A2A 客户端在带外获取这些新凭证,并在后续的消息/发送或消息/流请求中提供它们。如何使用这些凭证(例如,如果代理正在代理,则作为 A2A 消息中的数据传递,或者由客户端用于直接与辅助系统交互)取决于具体场景。
4.6. 授权 ¶
客户端通过身份验证后,A2A 服务器负责根据经过身份验证的客户端/用户身份及其自己的策略授权请求。授权逻辑是特定于实现的,并且可以根据以下条件强制执行:
请求的特定技能(例如,由代理卡中的AgentSkill.id确定的技能)。
在任务中尝试的作。
与代理管理的资源相关的数据访问策略。
与提供的令牌关联的 OAuth 范围(如果适用)。
服务器应实施最小权限原则。
5. 代理发现:代理卡 ¶
5.1. 目的 ¶
A2A 服务器必须提供代理卡。代理卡是一个 JSON 文档,用于描述服务器的身份、功能、技能、服务端点 URL 以及客户端应如何进行身份验证和与之交互。客户端使用此信息来发现合适的座席并配置其交互。
有关发现策略的更多信息,请参阅代理发现指南 。
5.2. 发现机制 ¶
客户可以通过多种方式找到代理卡,包括但不限于:
已知 URI: 访问代理域上的预定义路径(请参阅 第 5.3 节 )。
注册表/目录: 查询代理的精选目录或注册表(可能是特定于企业的、公共的或特定于域的)。
直接配置: 客户端可以预先配置代理卡 URL 或卡内容本身。
5.3. 推荐位置 ¶
如果使用已知的 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/stream、tasks/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;
}
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.artifacts 或 TaskStatus.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. 部分联合体类型 ¶
表示 Message 或 Artifact 中的不同内容。Part 是一种联合类型,将可导出内容表示为 TextPart、FilePart 或 DataPart。所有部件类型还包括一个可选的元数据字段 (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对象。
成员result和error是互斥的:一个 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-Type 为 application/json。对于 SSE 流,它是 text/event-stream。
7.1. 消息/发送 ¶
向座席发送消息以启动新交互或继续现有交互。此方法适用于同步请求/响应交互,或者当客户端轮询(使用 tasks/get)可用于监控运行时间较长的任务时。已达到最终状态(已完成、已取消、已拒绝或失败)的任务无法重新启动。向此类任务发送消息将导致错误。有关更多信息,请参阅任务生命周期指南 。
请求参数类型 :MessageSendParams
响应结果类型(成功时):任务|消息(消息对象或处理消息后任务的当前或最终状态)。
响应错误类型(失败时):JSONRPCError。
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数据字段都包含一个SendStreamingMessageResponseJSON 对象。
响应(初始订阅失败时):
标准 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/stream 或 tasks/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 流结束后获取任务的最终状态。
请求参数类型 :TaskQueryParams
响应结果类型(成功时):任务(任务当前状态的快照)。
响应错误类型(失败时):JSONRPCError(例如,如果未找到任务 ID,请参阅TaskNotFoundError)。
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¶
请求取消正在进行的任务。服务器将尝试取消任务,但不能保证成功(例如,任务可能已经完成或失败,或者当前阶段可能不支持取消)。
请求参数类型 :TaskIdParams
响应结果类型(成功时):任务(尝试取消后的任务状态。理想情况下,如果成功,Task.status.state将被“取消”)。
响应错误类型(失败时):JSONRPCError(例如,TaskNotFoundError、TaskNotCancelableError)。
7.4.1. TaskIdParams 对象 (用于 tasks/cancel 和 tasks/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 。
请求参数类型 :TaskPushNotificationConfig
响应结果类型(成功时):TaskPushNotificationConfig(确认已设置的配置。服务器可以省略或掩盖响应中authentication.credentials字段中的任何敏感详细信息(如机密)。
响应错误类型(失败时):JSONRPCError(例如,PushNotificationNotSupportedErrorTaskNotFoundError、与无效PushNotificationConfig相关的错误)。
7.6. tasks/pushNotificationConfig/get¶
检索指定任务的当前推送通知配置。要求服务器具有 AgentCard.capabilities.pushNotifications: true 。
请求参数类型 :GetTaskPushNotificationConfigParams|TaskIdParams(注意:此方法已弃用 TaskIdParams 类型。请改用 GetTaskPushNotificationConfigParams。
响应结果类型(成功时):TaskPushNotificationConfig(任务的当前推送通知配置。如果没有与任务关联的推送通知配置,则 Server 可能会返回错误。
响应错误类型(失败时):JSONRPCError(例如PushNotificationNotSupportedErrorTaskNotFoundError)。
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 。
请求参数类型 :ListTaskPushNotificationConfigParams
响应结果类型(成功时):TaskPushNotificationConfig[](与任务关联的推送通知配置。
响应错误类型(失败时):JSONRPCError(例如PushNotificationNotSupportedErrorTaskNotFoundError)。
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 。
请求参数类型 :DeleteTaskPushNotificationConfigParams
响应结果类型(成功时):[null]
响应错误类型(失败时):JSONRPCError(例如PushNotificationNotSupportedErrorTaskNotFoundError)。
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¶
在客户端进行身份验证后,检索可能更详细的代理卡版本。此终端节点仅在 为 true 时 AgentCard.supportsAuthenticatedExtendedCard 可用。这是一个 HTTP GET 端点,而不是 JSON-RPC 方法。
端点 URL:{AgentCard.url}/../agent/authenticatedExtendedCard(相对于公有代理卡中指定的基 URL)。
HTTP 方法 :GET
身份验证 :客户端必须使用公共AgentCard.securitySchemes和AgentCard.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 |
无法取消任务 |
尝试取消未处于可取消状态的任务(例如,它已达到 completed、failed 或 canceled 等最终状态)。 |
-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. 获取已验证的扩展代理卡 ¶
场景: 客户端发现一个公共代理卡,指示支持经过身份验证的扩展卡,并希望检索完整详细信息。
客户端获取公共 Agent Card:
Server 使用公共 Agent Card 进行响应(如 Section 5.6 中的示例),包括 supportsAuthenticatedExtendedCard: true (在根级别)和 securitySchemes。
-
客户端从公共卡识别所需的身份验证。 -
客户端在带外获取必要的凭证(例如,与 Google 一起执行 OAuth 2.0 流,从而产生访问令牌)。 -
客户端获取经过身份验证的扩展代理卡:
GET https://example.com/a2a/agent/authenticatedExtendedCard
Authorization: Bearer <obtained_access_token>
-
Server 对请求进行身份验证和授权。 -
服务器使用完整的代理卡进行响应:
9.2. 基本执行 (同步 / 轮询风格)¶
场景: 客户提出一个简单的问题,座席快速响应任务
客户端使用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": {}
}
}
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": {}
}
}
场景: 客户提出一个简单的问题,代理在没有任务的情况下快速响应
客户端使用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": {}
}
}
服务器处理请求,在没有任务的情况下快速响应
{
"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)¶
场景: 客户要求代理写一篇长篇论文,描述所附的图片。
客户端发送消息并使用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": {}
}
}
服务器使用 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. 多轮交互(需要输入)¶
场景: 客户想要预订航班,而代理需要更多信息。
客户端使用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"
}
}
服务器响应,任务状态为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"
}
}
客户端消息/发送( 使用相同的任务 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
}
}
}
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 收到通知。
使用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.
}
}
}
}
}
Server 确认任务(例如,状态submitted或working):
{
"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 ...
}
}
-
(稍后)A2A Server 完成任务并 POST 通知:https://client.example.com/webhook/a2a-notifications -
HTTP 标头可能包括:
Authorization: Bearer <server_jwt_for_webhook_audience>(如果服务器向 Webhook 进行身份验证)Content-Type: application/jsonX-A2A-Notification-Token: secure-client-token-for-task-aaa
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 ...
}
-
客户端的 Webhook 服务: -
接收 POST。
验证Authorization标头(如果适用)。
验证X-A2A-Notification-Token。
在内部处理通知(例如,更新应用程序状态、通知最终用户)。
9.6. 文件交换(上传和下载)¶
场景: 客户端发送图像进行分析,代理返回修改后的图像。
带有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"
}
}
}
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 格式的未结支持票证列表。
客户端消息/发送,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": {}
}
}
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 参数以及Message和Artifact部分中的数据内容/结构,以防止注入攻击或处理错误。
资源管理: 实施速率限制、并发控制和资源限制,以保护代理免受滥用或过载。
数据隐私: 遵守Message和Artifact部分中交换的数据的所有适用隐私法规。最大限度地减少敏感数据传输。
有关全面讨论,请参阅 Enterprise-Ready Features 指南 。