简介(未完成)
人与人之间可以通过各种各样的方式沟通:对话,眼神,肢体动作,画作等,这些可以帮助不同的人之间相互了解对方,并做出正确的动作,共同推动人类社会的发展,那么Agent之间沟通协作呢?Google给出了自己的答案:A2A 。
A2A 作为一个开放协议,充分考虑了 Agent 在和用户、企业打通的过程中所面临的一些挑战,其主要功能特性有以下四点:
- 安全协作(Secure Collaboration):通过引入认证/授权机制,保证 Agent 之间的身份互信。
- 任务状态管理(Task and state mgmt):实现了 Agent 之间互操作任务以及任务状态的可管理性。
- 用户体验协商(UX negotiation):不同的 Agent 通过协商的方式,对用户提供无缝的体验。
- 功能发现(Capability discovery):提供了 Agent 之间相互发现各自能力的机制。 除此之外,A2A 也在企业的无缝接入、简化集成方面,有比较好的考量。
Agent 相互之间的发现、了解和交互调用,是一个发展趋势。
- 首先,企业基于当前业务,都在探索、建立各种各样的 领域Agent 。在内部的各种 领域Agent 之间的沟通协作,是必须要面对和解决的一个问题。
- 其次,对于对外提供 Agent 服务的提供商来说,我如何让其他 Agent 主动发现我,就像SEO,吸引更多的流量,也是一个需要思考的问题。
概念
A2A(Agent2Agent) 简介 A2A 中包含三个核心的参与者:
- User,主要的作用是用于 认证&授权
- Client Agent,指的是任务发起者
- Remote Agent,指的是任务的执行者。
Client 和 Server 之间的通信,可以理解为就是一个个简单的请求和结果的响应,只不过这个请求是一个个的任务。一个 Agent 既可以是 Client 也可以是 Server。Client Agent 和 Server Agent 交互的过程中,主要涉及到的一些Entity:AgentCard、Task 、Artifact 、Message、Part。
- AgentCard 是 Server Agent 的名片,它主要描述了 Server Agent 的能力、认证机制等信息。Client Agent通过获取不同 Server Agent 的 AgentCard,了解不同 Server Agent 的能力,来决断具体的任务执行应该调用哪个 Server Agent 。
interface AgentCard { name: string; description: string; url: string; provider?: { organization: string; url: string; }; version: string; documentationUrl?: string; capabilities: { streaming?: boolean; pushNotifications?: boolean; stateTransitionHistory?: boolean; }; authentication: { schemes: string[]; credentials?: string; }; defaultInputModes: string[]; defaultOutputModes: string[]; skills: { id: string; name: string; description: string; tags: string[]; examples?: string[]; inputModes?: string[]; outputModes?: string[]; }[]; }
- Task 是一个具有状态的实体,由Client Agent创建,其状态由Server Agent维护。一个Task用于达到特定的目标或者结果。Agent Client和Server Client在Task中交换Mesaage,Server Agent生成的结果叫做Artifact。除此之外,每个Task有一个唯一的sessionId,多个Task可以使用一个sessionId,表明多个Task属于同一个会话的一部分。
interface Task { id: string; sessionId: string; status: TaskStatus; history?: Message[]; artifacts?: Artifact[]; metadata?: Record<string, any>; } interface TaskStatus { state: TaskState; message?: Message; timestamp?: string; } interface TaskStatusUpdateEvent { id: string; status: TaskStatus; final: boolean; //indicates the end of the event stream metadata?: Record<string, any>; } interface TaskArtifactUpdateEvent { id: string; artifact: Artifact; metadata?: Record<string, any>; } interface TaskSendParams { id: string; sessionId?: string; message: Message; historyLength?: number; pushNotification?: PushNotificationConfig; metadata?: Record<string, any>; // extension metadata } type TaskState = | "submitted" | "working" | "input-required" | "completed" | "canceled" | "failed" | "unknown";
- Artifacts:Server Agent 在执行任务后生成的目标结果叫做 Artifact,一个 Task 可能生成一个或者多个 Artifact。
Artifacts 是不可变的,可以命名,并且可以有多个部分。流式响应可以分批次,将结果附加到现有 Artifacts上。
interface Artifact { name?: string; description?: string; parts: Part[]; metadata?: Record<string, any>; index: number; append?: boolean; lastChunk?: boolean; }
- 在 Task执行过程中,Server Agent和Client Agent之间是通过Message完成交流的,当然,这不包括Artifact。它可以包括:Agent的思考、用户上下文、指令、错误、状态或元数据。一个Message可以包含多个Part,每个Part携带不同的内容。
interface Message { role: "user" | "agent"; parts: Part[]; metadata?: Record<string, any>; }
Part 是 Message 和 Artifact 的核心组成部分,代表了其携带的主要内容。每个 Part 都标识了内容类型和具体内容。
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>; };
通信
ClientAgent 和ServerAgent之间通过HTTP协议进行通信,使用经典的C/S模式,支持SSE流式数据传输,数据格式为JSON-RPC2.0。PS:可以理解为定义了有哪些api endpoint 以及endpoint 的入参出参schema
A2A遵循Open API规范进行身份验证。A2A不会在协议中交换身份信息。相反,它们会在带外获取材料(如令牌),并在HTTP 头中传输。
Client Agent 和 Server Agent 之间协同工作需要经过以下几个关键步骤:
- Server Agent 在指定站点托管自己的 AgentCard;官方建议将 AgentCard 托管在
https://${host}/.well-known/agent.json
。叫做 Open Discovery,除此之外,还有另外两种方式:Curated Discovery 和 Private Discovery。Agent Client 可以通过请求https://${host}/.well-known/agent.json
,获取到指定的 AgentCard,并集成到自己的提示词或者工具集中。 - Client Agent 主动发现 AgentCard;
- Client Agent 发起一个 Task;以启动新任务、恢复中断的任务或重新打开已完成的任务。
{ "jsonrpc": "2.0", "id": 1, "method":"tasks/send", "params": { "id": "de38c76d-d54c-436c-8b9f-4c2703648d64", "message": { "role":"user", "data": [{ "type":"text", "text": "tell me a joke" }] }, "metadata": {} } }
- Client Agent 设置任务通知监听;ClientAgent 可以设置一个方法,给到 ServerAgent,当 ServerAgent 修改 Task 状态后,同步调用 ClientAgent 的监听方法。
//Request { "jsonrpc": "2.0", "id": 1, "method":"tasks/pushNotification/set", "params": { "id": "de38c76d-d54c-436c-8b9f-4c2703648d64", "pushNotificationConfig": { "url": "https://example.com/callback", "authentication": { "schemes": ["jwt"] } } } } //Response { "jsonrpc": "2.0", "id": 1, "result": { "id": "de38c76d-d54c-436c-8b9f-4c2703648d64", "pushNotificationConfig": { "url": "https://example.com/callback", "authentication": { "schemes": ["jwt"] } } } }
- Server Agent 执行任务,返回 Artifact;
{ "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": {} } }
- Client Agent 获取 Artifact。这里需要注意的是,Client Agent 需要通过获取 Task 的方式,获取到Artifact
A2A vs MCP
MCP 还是传统的工程思维,A2A则是站在人的思维来看待世界。我们要理解MCP的定位:提供一个规范的方式,向LLMs/Agent提供上下文。MCP强调的是LLMs/Agent为主体,MCPServer为附属的模式。而A2A强调的是Agent和Agent之间的相互操作,协议双端是对等的。