一文看懂Google的A2A协议以及与MCP的区别
谷歌最近发布了 Agent-to-Agent(A2A)开放协议,旨在实现智能体之间的互操作性,弥合不透明智能体系统之间的差距。此前,模型上下文协议(MCP)已经成为连接大型语言模型(LLM)与数据、资源和工具的新标准,简化了不同模型和框架之间的“功能调用”,并创建了一个工具服务生态系统,降低了智能体与工具之间连接的复杂性。随着越来越多的平台采用 MCP,这一趋势有望继续发展。如果还不了解MCP协议的同学,可查看我们上一篇文章一文读懂 MCP!大模型如何用它连接世界,打造更智能的 AI Agent?。
然而,A2A 解决的是另一个问题。作为一个应用层协议,A2A 使智能体能够以自然的方式协作,允许它们像用户一样进行沟通,而不是仅仅作为工具。我们期望 A2A 能作为 MCP 的补充,推动智能体生态系统的进一步发展。通过 A2A,智能体能够在不共享记忆、思维或工具的情况下为终端用户完成任务。它们通过各自的原生模态交换上下文、状态、指令和数据。
A2A 的关键原则
- 简单:复用现有标准
- 企业级准备:认证、安全、隐私、追踪、监控
- 异步优先:支持(非常)长时间运行的任务和人类参与流程
- 模态无关:支持文本、音频/视频、表单、iframe 等多种形式
- 不透明执行:智能体无需共享思维、计划或工具
A2A 概览
参与者(Actor)
A2A 协议涉及三个角色:
- 用户(User) 最终用户(可以是人类或服务),使用智能体系统完成任务。
- 客户端(Client) 代表用户向远程智能体发起操作请求的实体(可以是服务、智能体或应用程序)。
- 远程智能体(Remote Agent / Server) 不透明的“黑箱”智能体,作为 A2A 协议中的服务器端。
传输层(Transport)
A2A 协议使用 HTTP 作为客户端与远程智能体之间的传输方式。 根据客户端与远程智能体的能力,它们可以使用 SSE(Server-Sent Events)支持从服务器接收流式更新。
A2A 使用 JSON-RPC 2.0[1] 作为客户端与远程智能体之间通信的数据交换格式。
异步通信(async)
A2A 客户端与服务器可以使用标准的请求/响应模式,并通过轮询获取更新。 此外,A2A 还支持使用 SSE 进行流式更新(连接期间),以及在断开连接时接收推送通知[2]。
身份验证与授权(authentication-and-authorization)
A2A 将智能体建模为企业级应用程序(因为智能体是黑箱的,不共享工具和资源),从而使智能体互操作快速具备企业级能力。
A2A 遵循 OpenAPI 的认证规范[3]。重要的是,A2A 协议中智能体不交换身份信息。 相反,它们在 A2A 协议之外获取身份材料(如令牌),并通过 HTTP 头部传递这些材料,而非放入 A2A 消息体中。
虽然身份信息不在 A2A 协议中传输,但服务器会在 A2A 的响应消息中声明认证要求。最基本的做法是,服务器在其 Agent Card[4] 中发布认证要求。关于如何发现 Agent Card,请参见智能体发现[5]。
客户端应使用服务器提供的认证机制之一,来验证身份并获取认证材料。A2A 服务器应对每一个请求执行身份验证,对于无效请求应通过标准 HTTP 响应码(如 401、403)进行拒绝或挑战,并附带相应的认证头信息或响应体(如使用 WWW-Authenticate[6] 头,或在特定路径下提供 OIDC 发现文档)。更多细节见 企业级准备[7]。
注意:如果某个智能体在任务执行过程中需要客户端/用户提供额外认证信息(比如使用某个特定工具),智能体应返回
Input-Required
状态,并附带一个认证结构。此时客户端应再次通过 A2A 协议之外的方式获取认证材料。
智能体卡(Agent Card)
支持 A2A 协议的远程智能体必须以 JSON 格式发布一个Agent Card(智能体卡),用于描述该智能体的能力/技能以及其认证机制。 客户端会使用智能体卡中的信息来识别最适合执行特定任务的智能体,并通过 A2A 协议与其进行通信。
发现机制(Discovery)
建议智能体将其智能体卡托管在地址:
https://<base url>/.well-known/agent.json
。
这一做法兼容 DNS 模式:客户端可以通过 DNS 查找服务器 IP,然后发送 HTTP GET 请求获取智能体卡。 同时也考虑到系统可能会维护私有注册表(如“智能体目录”或私有市场等)。 更多关于智能体发现的讨论见本节文档[8]。
表示形式(Representation)
以下是智能体卡的推荐表示方式(JSON 结构):
代码语言:javascript代码运行次数:0运行复制// 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
interface AgentCard {
// Human readable name of the agent.
// (e.g. "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.
// (e.g. "Agent that helps users with recipes and cooking.")
description: string;
// A URL to the address the agent is hosted at.
url: string;
// The service provider of the agent
provider?: {
organization: string;
url: string;
};
// The version of the agent - format is up to the provider. (e.g. "1.0.0")
version: string;
// A URL to documentation for the agent.
documentationUrl?: string;
// Optional capabilities supported by the agent.
capabilities: {
streaming?: boolean; // true if the agent supports SSE
pushNotifications?: boolean; // true if the agent can notify updates to client
stateTransitionHistory?: boolean; //true if the agent exposes status change history for tasks
};
// Authentication requirements for the agent.
// Intended to match OpenAPI authentication structure.
authentication: {
schemes: string[]; // e.g. Basic, Bearer
credentials?: string; //credentials a client should use for private cards
};
// The set of interaction modes that the agent
// supports across all skills. This can be overridden per-skill.
defaultInputModes: string[]; // supported mime types for input
defaultOutputModes: string[]; // supported mime types for output
// Skills are a unit of capability that an agent can perform.
skills: {
id: string; // unique identifier for the agent's skill
name: string; //human readable name of the skill
// 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 (e.g. "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. (e.g. "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)
inputModes?: string[]; // supported mime types for input
outputModes?: string[]; // supported mime types for output
}[];
}
智能体间通信(Agent-to-Agent Communication)
客户端与远程智能体之间的通信以**任务完成(task completion)**为导向,智能体通过协作来完成终端用户的请求。 任务对象(Task)允许客户端与远程智能体围绕提交的任务进行协作。
任务可以由远程智能体立即完成,也可能是一个长时间运行的任务。对于长任务,客户端可以通过轮询的方式获取最新状态。 如果处于连接状态,智能体也可以通过 SSE 推送更新;断开连接时,则可通过外部通知服务发送更新。
核心对象(Core Objects)
任务(Task)
任务是一个有状态的实体,用于让客户端和远程智能体协同实现特定目标并生成结果。 在任务上下文中,客户端与远程智能体可以互换消息(Messages),而远程智能体会以**工件(Artifacts)**形式生成结果。
任务总是由客户端创建,而其状态始终由远程智能体决定。
如果客户端有需要,多个任务可以归属在同一个会话中(通过可选的 sessionId
实现)。客户端在创建任务时设置该 sessionId
。
智能体在接收到任务后可以:
- 立即完成请求
- 将任务调度到稍后执行
- 拒绝请求
- 协商更合适的交互模态
- 请求客户端提供更多信息
- 委派任务给其他智能体或系统执行
即使在目标已完成后,客户端仍可以在该任务上下文中请求更多信息或修改内容。 (例如:客户端:“画一只兔子”,智能体:“<图片>”,客户端:“把它变成红色的”)
任务还承担着**结果(Artifacts)和消息(Messages)**的传递通道,并维护一个状态记录和可选的消息/状态历史记录。
代码语言:javascript代码运行次数:0运行复制interface Task {
id: string; // unique identifier for the task
sessionId: string; // client-generated id for the session holding the task.
status: TaskStatus; // current status of the task
history?: Message[];
artifacts?: Artifact[]; // collection of artifacts created by the agent.
metadata?: Record<string, any>; // extension metadata
}
// TaskState and accompanying message.
interface TaskStatus {
state: TaskState;
message?: Message; //additional status updates for client
timestamp?: string; // ISO datetime value
}
// sent by server during sendSubscribe or subscribe requests
interface TaskStatusUpdateEvent {
id: string;
status: TaskStatus;
final: boolean; //indicates the end of the event stream
metadata?: Record<string, any>;
}
// sent by server during sendSubscribe or subscribe requests
interface TaskArtifactUpdateEvent {
id: string;
artifact: Artifact;
metadata?: Record<string, any>;
}
// Sent by the client to the agent to create, continue, or restart a task.
interface TaskSendParams {
id: string;
sessionId?: string; //server creates a new sessionId for new tasks if not set
message: Message;
historyLength?: number; //number of recent messages to be retrieved
// where the server should send notifications when disconnected.
pushNotification?: PushNotificationConfig;
metadata?: Record<string, any>; // extension metadata
}
type TaskState =
| "submitted"
| "working"
| "input-required"
| "completed"
| "canceled"
| "failed"
| "unknown";
工件(Artifact)
智能体会生成工件(Artifacts)作为任务的最终结果。工件是不可变的,可以命名,并且可以包含多个部分。流式响应可以将新部分附加到现有的工件上。
一个任务可以生成多个工件。例如,“创建一个网页”任务可能会生成单独的 HTML 和图片工件。
代码语言:javascript代码运行次数:0运行复制interface Artifact {
name?: string;
description?: string;
parts: Part[];
metadata?: Record<string, any>;
index: number;
append?: boolean;
lastChunk?: boolean;
}
消息(Message)
消息(Message)包含任何非工件(Artifact)的内容。这些内容可以包括智能体的思维、用户上下文、指令、错误、状态或元数据等。
所有来自客户端的内容都是以消息的形式发送的。智能体通过发送消息来传递状态或提供指令(而生成的结果则以工件的形式发送)。
一条消息可以包含多个部分,用以表示不同的内容。例如,用户请求可能包括一段来自用户的文本描述,接着是多个作为上下文的文件。
代码语言:javascript代码运行次数:0运行复制interface Message {
role: "user" | "agent";
parts: Part[];
metadata?: Record<string, any>;
}
部分(Part)
部分(Part)是客户端与远程智能体之间交换的完整内容单元,它是消息(Message)或工件(Artifact)的一部分。每个部分都有自己的内容类型和元数据。
代码语言:javascript代码运行次数:0运行复制interface TextPart {
type: "text";
text: string;
}
interface FilePart {
type: "file";
file: {
name?: string;
mimeType?: string;
// oneof {
bytes?: string; //base64 encoded content
uri?: string;
//}
};
}
interface DataPart {
type: "data";
data: Record<string, any>;
}
type Part = (TextPart | FilePart | DataPart) & {
metadata: Record<string, any>;
};
推送通知(Push Notifications)
A2A 支持一种安全的通知机制,智能体可以通过推送通知服务(PushNotificationService)在未连接会话的情况下通知客户端更新。在企业内部或跨企业的环境中,智能体必须验证通知服务的身份、对其进行认证,并提供一个标识符,将通知与正在执行的任务关联起来。
推送通知服务的目标服务器应被视为一个独立的服务,并且不保证(也不期望)它是直接的客户端。此推送通知服务负责认证和授权智能体,并将验证后的通知代理发送到适当的端点(该端点可以是发布/订阅队列、电子邮件收件箱或其他服务等)。
对于具有隔离的客户端-智能体配对的情境(例如,封闭虚拟私有网络中的本地服务网格等)或没有企业安全需求的隔离环境,客户端可以选择直接打开端口并充当自己的推送通知服务。任何企业级实现通常会有一个集中式服务,用于使用受信任的通知凭证认证远程智能体,并能够处理在线/离线场景。(这应类似于移动推送通知服务)。
代码语言:javascript代码运行次数:0运行复制interface PushNotificationConfig {
url: string;
token?: string; // token unique to this task/session
authentication?: {
schemes: string[];
credentials?: string;
};
}
interface TaskPushNotificationConfig {
id: string; //task id
pushNotificationConfig: PushNotificationConfig;
}
示例方法和 JSON 响应
智能体卡
此部分提供了关于如何获取和解析智能体卡(Agent Card)的示例方法和相应的 JSON 响应格式。这将帮助客户端理解如何通过智能体卡获得智能体的能力、认证信息等内容。
代码语言:javascript代码运行次数:0运行复制//agent card
{
"name": "Google Maps Agent",
"description": "Plan routes, remember places, and generate directions",
"url": ";,
"provider": {
"organization": "Google",
"url": ";
},
"version": "1.0.0",
"authentication": {
"schemes": "OAuth2"
},
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain", "application/html"],
"capabilities": {
"streaming": true,
"pushNotifications": false
},
"skills": [
{
"id": "route-planner",
"name": "Route planning",
"description": "Helps plan routing between two locations",
"tags": ["maps", "routing", "navigation"],
"examples": [
"plan my route from Sunnyvale to Mountain View",
"what's the commute time from Sunnyvale to San Francisco at 9AM",
"create turn by turn directions from Sunnyvale to Mountain View"
],
// can return a video of the route
"outputModes": ["application/html", "video/mp4"]
},
{
"id": "custom-map",
"name": "My Map",
"description": "Manage a custom map with your own saved places",
"tags": ["custom-map", "saved-places"],
"examples": [
"show me my favorite restaurants on the map",
"create a visual of all places I've visited in the past year"
],
"outputModes": ["application/html"]
}
]
}
发送任务
此方法允许客户端向远程智能体发送内容,以启动新任务、恢复中断的任务或重新开启已完成的任务。任务中断可能是由于智能体需要额外的用户输入或发生了运行时错误。
代码语言:javascript代码运行次数:0运行复制//Request
{
"jsonrpc": "2.0",
"id": 1,
"method":"tasks/send",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"message": {
"role":"user",
"parts": [{
"type":"text",
"text": "tell me a joke"
}]
},
"metadata": {}
}
}
//Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed",
},
"artifacts": [{
"name":"joke",
"parts": [{
"type":"text",
"text":"Why did the chicken cross the road? To get to the other side!"
}]
}],
"metadata": {}
}
}
获取任务
客户端可以使用此方法检索任务生成的工件(Artifacts)。智能体会根据其设定的保留时间窗口来处理之前提交的任务。对于已超出保留时间窗口的任务,或者那些生命周期较短且未由智能体持久化的任务,智能体可能会返回错误代码。
客户端还可以请求任务的最后 N 条历史记录,其中包含按顺序排列的所有客户端和智能体之间的消息。默认情况下,这个历史记录是 0(即不包含历史记录)。
代码语言:javascript代码运行次数:0运行复制//Request
{
"jsonrpc": "2.0",
"id": 1,
"method":"tasks/get",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"historyLength": 10,
"metadata": {}
}
}
//Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed"
},
"artifacts": [{
"parts": [{
"type":"text",
"text":"Why did the chicken cross the road? To get to the other side!"
}]
}],
"history":[
{
"role": "user",
"parts": [
{
"type": "text",
"text": "tell me a joke"
}
]
}
],
"metadata": {}
}
}
取消任务
客户端可以选择取消之前提交的任务,具体方法如下所示。
代码语言:javascript代码运行次数:0运行复制//Request
{
"jsonrpc": "2.0",
"id": 1,
"method":"tasks/cancel",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"metadata": {}
}
}
//Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": 1,
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "canceled"
},
"metadata": {}
}
}
设置任务推送通知
客户端可以配置一个推送通知 URL,以接收任务状态变化的更新。
代码语言:javascript代码运行次数:0运行复制//Request
{
"jsonrpc": "2.0",
"id": 1,
"method":"tasks/pushNotification/set",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"pushNotificationConfig": {
"url": ";,
"authentication": {
"schemes": ["jwt"]
}
}
}
}
//Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"pushNotificationConfig": {
"url": ";,
"authentication": {
"schemes": ["jwt"]
}
}
}
}
获取任务推送通知
客户端可以使用此方法检索当前为任务配置的推送通知设置。
代码语言:javascript代码运行次数:0运行复制//Request
{
"jsonrpc": "2.0",
"id": 1,
"method":"tasks/pushNotification/get",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64"
}
}
//Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"pushNotificationConfig": {
"url": ";,
"authentication": {
"schemes": ["jwt"]
}
}
}
}
多轮对话
如果任务需要额外的用户输入,它可能会暂停并在远程智能体上执行。当任务处于 input-required
状态时,客户端需要提供额外的输入,以便任务可以继续在远程智能体上处理。
在 input-required
状态下的消息必须包含指示客户端需要执行的操作的详细信息。例如,“填写表单”或“登录到 SaaS 服务 foo”。如果这些操作涉及结构化数据,指令应作为一个 Part
发送,结构化数据则作为第二个 Part
发送。
//Request - seq 1
{
"jsonrpc": "2.0",
"id": 1,
"method":"tasks/send",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"message": {
"role":"user",
"parts": [{
"type":"text",
"text": "request a new phone for me"
}]
},
"metadata": {}
}
}
//Response - seq 2
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "input-required",
"message": {
"parts": [{
"type":"text",
"text":"Select a phone type (iPhone/Android)"
}]
}
},
"metadata": {}
}
}
//Request - seq 3
{
"jsonrpc": "2.0",
"id": 2,
"method":"tasks/send",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"message": {
"role":"user",
"parts": [{
"type":"text",
"text": "Android"
}]
},
"metadata": {}
}
}
//Response - seq 4
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"id": 1,
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed"
},
"artifacts": [{
"name": "order-confirmation",
"parts": [{
"type":"text",
"text":"I have ordered a new Android device for you. Your request number is R12443"
}],
"metadata": {}
}],
"metadata": {}
}
}
流式支持
对于支持通过 HTTP 和 SSE 通信的客户端和远程智能体,客户端可以在创建新任务时使用 tasks/sendSubscribe
方法发送 RPC 请求。远程智能体可以通过一系列任务状态更新事件(TaskStatusUpdateEvents,传递状态变化或指令/请求)和任务工件更新事件(TaskArtifactUpdateEvents,流式传输生成的结果)进行响应。请注意,任务工件更新事件可以将新部分附加到现有的工件中。客户端可以使用 task/get
来检索整个工件,而不依赖于流式传输。
智能体必须在流的末尾设置 final: true
属性,或者在智能体中断并需要额外用户输入时设置该属性。
//Request
{
"method":"tasks/sendSubscribe",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"message": {
"role":"user",
"parts": [{
"type":"text",
"text": "write a long paper describing the attached pictures"
},{
"type":"file",
"file": {
"mimeType": "image/png",
"data":"<base64-encoded-content>"
}
}]
},
"metadata": {}
}
}
//Response
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": 1,
"status": {
"state": "working",
"timestamp":"2025-04-02T16:59:25.331844"
},
"final": false
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": 1,
"artifact": [
"parts": [
{"type":"text", "text": "<section 1...>"}
],
"index": 0,
"append": false,
"lastChunk": false
]
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": 1,
"artifact": [
"parts": [
{"type":"text", "text": "<section 2...>"}
],
"index": 0,
"append": true,
"lastChunk": false
]
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": 1,
"artifact": [
"parts": [
{"type":"text", "text": "<section 3...>"}
],
"index": 0,
"append": true,
"lastChunk": true
]
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": 1,
"status": {
"state": "completed",
"timestamp":"2025-04-02T16:59:35.331844"
},
"final": true
}
}
重新订阅任务
断开连接的客户端可以重新订阅支持流式传输的远程智能体,以通过 SSE 接收任务更新。
代码语言:javascript代码运行次数:0运行复制//Request
{
"method":"tasks/resubscribe",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"metadata": {}
}
}
//Response
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"artifact":[
"parts": [
{"type":"text", "text": "<section 2...>"}
],
"index": 0,
"append": true,
"lastChunk":false
]
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"artifact":[
"parts": [
{"type":"text", "text": "<section 3...>"}
],
"index": 0,
"append": true,
"lastChunk": true
]
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": 1,
"status": {
"state": "completed",
"timestamp":"2025-04-02T16:59:35.331844"
},
"final": true
}
}
非文本媒体
以下是客户端与智能体之间交互的示例,涉及非文本数据。
代码语言:javascript代码运行次数:0运行复制//Request - seq 1
{
"jsonrpc": "2.0",
"id": 9,
"method":"tasks/send",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"message": {
"role":"user",
"parts": [{
"type":"text",
"text": "Analyze the attached report and generate high level overview"
},{
"type":"file",
"file": {
"mimeType": "application/pdf",
"data":"<base64-encoded-content>"
}
}]
},
"metadata": {}
}
}
//Response - seq 2
{
"jsonrpc": "2.0",
"id": 9,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "working",
"message": {
"role": "agent",
"parts": [{
"type":"text",
"text":"analysis in progress, please wait"
}],
"metadata": {}
}
},
"metadata": {}
}
}
//Request - seq 3
{
"jsonrpc": "2.0",
"id": 10,
"method":"tasks/get",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"metadata": {}
}
}
//Response - seq 4
{
"jsonrpc": "2.0",
"id": 9,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed"
},
"artifacts": [{
"parts": [{
"type":"text",
"text":"<generated analysis content>"
}],
"metadata": {}
}],
"metadata": {}
}
}
结构化输出
客户端或智能体都可以要求对方提供结构化输出。
代码语言:javascript代码运行次数:0运行复制//Request
{
"jsonrpc": "2.0",
"id": 9,
"method":"tasks/send",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"message": {
"role":"user",
"parts": [{
"type":"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" }
}
}
}
}
}]
},
"metadata": {}
}
}
//Response
{
"jsonrpc": "2.0",
"id": 9,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "working",
"message": {
"role": "agent",
"parts": [{
"type":"text",
"text":"[{\"ticketNumber\":\"REQ12312\",\"description\":\"request for VPN access\"},{\"ticketNumber\":\"REQ23422\",\"description\":\"Add to DL - team-gcp-onboarding\"}]"
}],
"metadata": {}
}
},
"metadata": {}
}
}
错误处理
以下是服务器在处理客户端请求时遇到错误时向客户端响应的错误消息格式(ErrorMessage)。
代码语言:javascript代码运行次数:0运行复制interface ErrorMessage {
code: number;
message: string;
data?: any;
}
以下是服务器在错误场景中可以响应的标准 JSON-RPC 错误代码:
错误代码 | 消息 | 描述 |
---|---|---|
-32700 | JSON 解析错误 | 发送的 JSON 无效 |
-32600 | 无效请求 | 请求负载验证错误 |
-32601 | 找不到方法 | 不是有效的方法 |
-32602 | 无效的参数 | 方法参数无效 |
-32603 | 内部错误 | 内部 JSON-RPC 错误 |
-32000 至 -32099 | 服务器错误 | 保留用于特定实现的错误代码 |
-32001 | 找不到任务 | 使用提供的 ID 未找到任务 |
-32002 | 任务无法取消 | 远程智能体无法取消任务 |
-32003 | 不支持推送通知 | 智能体不支持推送通知 |
-32004 | 不支持的操作 | 操作不被支持 |
-32005 | 不兼容的内容类型 | 客户端和智能体之间的内容类型不兼容 |
参考资料
[1]
JSON-RPC 2.0:
[2]
推送通知:
[3]
OpenAPI 的认证规范: /
[4]
Agent Card:
[5]
智能体发现:
[6]
WWW-Authenticate:
[7]
企业级准备:
[8]
本节文档:
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-04-16,如有侵权请联系 cloudcommunity@tencent 删除客户端推送协议google服务