大家好,我是Edison。
上一篇,我们了解了A2A协议的基本概念,还通过A2A组件实现了一个Hello World的Demo,有了一个快速的感性认识。这一篇,我们来了解下A2A协议的三大角色、四大对象 以及 工作流程,有了这些基础的认知后会对我们全面认识A2A有所帮助。
A2A协议的三大角色
A2A 即 Agent-to-Agent,它定义了三个关键的角色,它们各司其职+互相配合,支撑多个Agent的运行。
那么,都是哪几个角色呢?下面告诉你:
角色1:用户(User)
即终端用户(可能是人类 或 服务),需要使用Agent来完成某个任务。
角色2:客户端(Client)
一个代表用户向 远程Agent 发送请求的实体,它发送的请求是严格按照A2A协议的。它的表现形式可以是一个应用程序、服务 或 一个Agent。
例如,我们在上一篇的Demo中开发的一个控制台应用程序通过引用A2A包来向远端的Agent发送请求。
角色3:远程Agent(Remote Agent)
一个执行实际任务的Agent(部署在某个远端Server上),对于客户端来说是“黑盒”一样的存在,仅仅通过Agent Card声明自己提供的接口或技能,但内部实现细节或工作机制是不透明的,即一个“黑盒”。
例如,我们在上一篇的Demo中开发的一个WebAPI项目EchoAgent,提供了一个ProcessMessage的技能 以及 声明了一个AgentCard公开了一些元数据。
A2A的四大对象
A2A中定义了一套完整的对象体系,其中最核心的就是下面这四个核心对象:
第一个对象:Agent Card(又称Agent名片)
每个A2A的远程Agent都需要发布一个JSON格式的名片,被称为“Agent Card”,用于描述这个Agent具有哪些技能 及其 认证机制,便于Client可以获得这些信息并选择合适的Agent来完成任务。
其实,它就和我们在做后端服务开发中的服务注册和发现的机制差不多,只不过这个注册的信息被标准化了,下面我们可以看看一个典型的Agent Card的JSON格式:- {
- "name": "Google Maps Agent",
- "description": "Plan routes, remember places, and generate directions",
- "url": "https://maps-agent.google.com",
- "provider": {
- "organization": "Google",
- "url": "https://google.com"
- },
- "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"
- ],
- "outputModes": ["application/html", "video/mp4"]
- }
- ]
- }
复制代码 这个JSON数据简要描述了一个名为"Google Maps Agent"的Agent定义。这个Agent的主要功能是规划路线、记住地点和生成导航指示。这个应用由Google提供,版本号是1.0.0,采用OAuth2身份验证。它支持文本和HTML格式的输入和输出,具有流媒体功能,但不支持推送通知。它的一个核心技能是"route-planner",可以帮助用户规划两个地点之间的路线,并输出HTML和视频格式的内容。
在A2A .NET SDK中,AgentCard的定义如下:- public class AgentCard
- {
- public string Name { get; set; } // 代理名称
- public string Description { get; set; } // 代理描述
- public string Url { get; set; } // 代理 URL
- public AgentProvider? Provider { get; set; } // 提供商信息
- public string Version { get; set; } // 版本信息
- public AgentCapabilities Capabilities { get; set; } // 代理能力
- public List Skills { get; set; } // 代理技能
- public List<string> DefaultInputModes { get; set; } // 默认输入模式
- public List<string> DefaultOutputModes { get; set; }// 默认输出模式
- }
复制代码 在上一篇的Demo中,我们在定义EchoAgent时,就实现了一个GetAgentCard方法,并将其注册到服务发现中最终被Client探索发现时就会以JSON格式输出给到Client:- public class EchoAgent
- {
- public void Attach(ITaskManager taskManager)
- {
- taskManager.OnMessageReceived = ProcessMessageAsync;
- taskManager.OnAgentCardQuery = GetAgentCardAsync;
- }
- private Task<Message> ProcessMessageAsync(MessageSendParams messageSendParams, CancellationToken cancellationToken)
- {
- ......
- }
- private Task GetAgentCardAsync(string agentUrl, CancellationToken cancellationToken)
- {
- return Task.FromResult(new AgentCard
- {
- Name = "Echo Agent",
- Description = "Echoes messages back to the user",
- Url = agentUrl,
- Version = "1.0.0",
- DefaultInputModes = ["text"],
- DefaultOutputModes = ["text"],
- Capabilities = new AgentCapabilities { Streaming = true }
- });
- }
- }
复制代码 与此同时,在Client中也可以主动进行服务发现,例如上一篇Demo中的Client示例代码:- // Discover agent and create client
- var cardResolver = new A2ACardResolver(new Uri("https://localhost:7243/"));
- var agentCard = await cardResolver.GetAgentCardAsync();
- var client = new A2AClient(new Uri(agentCard.Url));
复制代码 第二个对象:Task (任务)
Task 是 Client 和 远程Agent 之间协作的一个概念,很好理解,一个Task代表一个需要完成的任务,每个Task都有一个唯一的ID号,它通常包含了任务状态、历史记录 和 执行结果 等信息。
Task的主要具体状态有:submitted, working, completed, canceled, failed 等,下图展示了Task的状态机转换流。
在A2A .NET SDK中,AgentTask的定义如下:- public class AgentTask : A2AResponse
- {
- public string Id { get; set; } // 任务 ID
- public string? ContextId { get; set; } // 上下文 ID
- public AgentTaskStatus Status { get; set; } // 任务状态
- public List? Artifacts { get; set; } // 任务产出物
- public List<Message>? History { get; set; } // 消息历史
- public Dictionary<string, JsonElement>? Metadata { get; set; } // 元数据
- }
复制代码 第三个对象:Artifact(工件 或 成果)
Artifact 和我们在DevOps CI/CD流水线中的Artifact(即工件)的概念类似,它是 远程Agent执行完某个任务后生成输出的结果(即远程Agent返回的结果通过一个Artifact对象输出给Client),每个任务的结果可能都不一样。
一个Artifact可以包含多个部分(parts),每个部分(part)可以是:文本、文档、图像 等,涉及纯文本、文件 和 结构化数据。
第四个对象:Message(消息)
Message 也很好理解,它就是 Client 和 远程Agent 之间通信的 一个消息对象,它通常包含了 指令 和 状态更新 等内容。
同样的,一个Message对象也可以包含多个parts,用于传递如 文本、文件 或 结构化 等不同类型的内容。每个Message都有发送方设置的一个唯一的messageId,且通过一些关键词如"user"(代表Client发送的)或“agent”(代表服务端发送的)来区分角色。
在A2A .NET SDK中,Message的定义如下:- public class Message : A2AResponse
- {
- public MessageRole Role { get; set; } // 消息角色 (User/Agent)
- public List<Part> Parts { get; set; } // 消息部分
- public string? MessageId { get; set; } // 消息 ID
- public string? TaskId { get; set; } // 关联任务 ID
- public string? ContextId { get; set; } // 上下文 ID
- public Dictionary<string, JsonElement>? Metadata { get; set; } // 元数据
- }
复制代码 A2A协议的工作流程
这里我们来通过一个简单的例子看看A2A协议的 请求-响应 工作流程是怎么样的。
例如,有这样一个场景“招聘XX岗位候选人搜寻”:
Step1,用户在统一界面下向Client(假设它也是一个Agent)发送一个请求消息“请帮我寻找一个XX岗位的候选人”。
Step2,Client将用户的请求消息进行封装,并根据岗位需求依次调用一些远程Agent如 简历检索Agent、技能筛选Agent 等等。
例如,下面的请求示例展示了Client在检索了5位候选人简历之后通过A2A协议向远端技能筛选Agent发送的任务请求:- {
- "jsonrpc": "2.0",
- "id": 1,
- "method": "tasks/send",
- "params": {
- "id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
- "message": {
- "role": "user",
- "parts": [
- {
- "type": "text",
- "text": "请分析下面5位候选人是否符合岗位需求,并推荐最佳面试人选。"
- }
- ]
- },
- "metadata": {}
- }
- }
复制代码 Step3,各个远端Agent执行各自的任务,并返回给Client对应的Artifact对象结果(如候选人名单等),然后再由Client进行汇总和展示。- {
- "jsonrpc": "2.0",
- "id": 1,
- "result": {
- "id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
- "sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
- "status": {
- "state": "completed"
- },
- "artifacts": [
- {
- "name": "result",
- "parts": [
- {
- "type": "text",
- "text": "第三位候选人最符合你的需求!建议安排面试。"
- }
- ]
- }
- ],
- "metadata": {}
- }
- }
复制代码 Step4,后续Client可以陆续调用其他远端Agent如 面试安排Agent、背景调查Agent等,完成端到端的自动化招聘流程。
那么,该场景的整个工作流程便如下图所示:
除此之外,实际应用案例中通常是A2A与MCP两个协议一起使用,形成更广的应用范围。
例如,下图展示了一个汽车维修店的场景,店长智能体 和 机械师智能体 通过A2A协议完成任务移交(hand-off),店长可以处理常见问题,但机械师可以解决技术难题。机械师智能体再通过MCP协议完成内部工具使用完成具体任务,还可以通过A2A协议和零件供应商Agent完成外部协作。
由此可见,其实在企业客服 或 售后中心 等场景中,A2A协议可以被广泛应用于多Agent协作。
小结
本文介绍了A2A的三个主要角色(User、Client 和 Remote Agent)以及 四个核心对象(Agent Card、Task、Artifact 和 Message),并通过简单的例子介绍了A2A协议的典型工作流程,相信对于你加深了解A2A协议会有帮助。
下一篇,我们将以一个旅行规划的应用场景,结合LLM大模型来实现一个A2A协议的案例,它会涉及一个Client 和 三个Remote Agent,是一个拿来练手的好案例。
参考资料
sing1ee:《2025年完整指南:A2A协议 - AI智能体协作的新标准》
黄佳:《MCP & A2A前沿实战》
圣杰:《.NET+AI | Semantic Kernel入门到精通》
作者:爱迪生
出处:https://edisontalk.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |