谷歌Agent2Agent(A2A)深度解析:4个关键问题与1个实战Demo

这不很多人MCP还没拎得清楚,A2A又来了,关键这俩长的还有点像,今天就来仔细说说这个谷歌的新玩意 - Agent2Agent(A2A)协议。

  • 为什么会诞生A2A?

  • A2A到底是什么?

  • A2A架构是怎样的?

  • A2A和MCP什么关系?

  • A2A的Demo新体验

01

为什么会诞生A2A?

让我们假想一个简单的场景:你开发了某个Agent(比如Web自动化机器人或AI研究员),现在我在开发一个新的Agent系统,希望可以把部分任务交给你的Agent来完成,我们会怎么做呢?

  • 最简单的,你可以把Agent代码交给我,我把这个Agent转化成一个函数工具为我的Agent使用,这是可行的(甚至可以用上MCP):

    图片

  • 我还可以借助多Agent开发框架,直接构建分布式多Agent系统。这也是可行的,比如利用AutoGen框架:

图片

    但是这样的集成一方面需要大量代码级的改造,另一方面耦合度太高了。且不论不同的开发平台和框架可能的兼容性问题,后期更新维护就是大问题。

    所以一个更简单的办法就是开放API,于是协商了下接口参数,很快做成了这样:

图片

现在这个方案貌似还不错,可能也是一些有前后台的Agent系统的方案。包括一些Agent构建平台也支持这种模式,比如你可以借助API调用Coze/Dify上创建的Agent。但如果把这样的需求泛化到更多的任务场景,仍然会面临新的挑战:

  • 如果扩展到多个Agent,这些Agent有不同的供应商、不同的平台、不同的开发框架,它们之间有协作的需求。那么就会面临和MCP之前一样的问题:你需要去做大量的API集成,不同的消息格式与通信协议,需要你来做“粘合”。

  • Agent系统的真实任务场景复杂度往往较高,简单的无状态API无法满足。比如:

    * 一个需要很长时间运行的任务

    * 多轮对话的问题,Human-in-the-loop工作流

    * 流式输出的问题

    * 不同供应商之间的Agent之间的互信问题

这种需要让不同类型的AI Agent之间(也可以是其他应用与Agent之间)实现更标准的通信与互操作的需求,就是A2A诞生的原因。

02

A2A到底是什么?

A2A(Agent2Agent)是一种开放协议,旨在实现不透明Agent之间的通信和互操作。其主要作用就是为不同的Agent提供一种共同的“语言”标准,在它们需要“交流”的时候可以更加简单、高效与安全,实现信息共享与任务分配,从而更快的完成任务,即使它们的底层平台完全不同:

图片

整体上而言,A2A提供的价值与MCP是类似的:

  • 降低异构Agent之间的集成复杂性:你无需了解对端Agent的细节。

  • 提高Agent能力的可复用性:你可以把某个任务交给更擅长它的Agent。

  • 更好的扩展性以适应变化:Agent的内部逻辑变化可以被A2A所隔离。

A2A协议对Agent之间集成的如下方面进行标准化:

  • 集成架构与关键组件

  • 消息与通信机制(JSON-RPC2.0与HTTP)

  • 服务端与客户端的功能规范

  • 安全验证与授权机制

03

A2A架构是怎样的?

也就是“基于A2A规范的Agent集成架构”,大致描述如下:

图片

几个关键的组件构成如下:

  • Agent Card:这是Agent的“名片”,代表“我有怎样的任务完成能力“。

  • A2A Server:访问对端Agent的的入口,基于Web Server运行,提供端点供客户端发起各种请求并给予响应;也会通过连接发起主动通知、任务结果给客户端。

  • A2A Client:访问A2A Server的其他Agent或定制应用。所以Client与Server是相对的,一个客户端Agent同时也可以是其他Agent的服务端。

  • Task(任务):这是客户端交给服务端Agent需要完成的工作任务。任务过程可能需要客户端的协作;任务结果可以同步等待也可以异步获取。

  • Artifact(工件):服务端Agent的最终产出被称为Artifact。比如一段文字、一个报告、一个图片或者视频;一次任务可以产生多个Artifact。

  • Messages(消息):是指的客户端与服务端Agent之间的多轮沟通内容,存在两个角色:user和agent,内容包括各种上下文、指令、中间状态等。客户端向Agent发送的所有内容都是消息;Agent也可以发送消息给客户端传递状态或指令(比如要求客户端补充信息),但服务端Agent的最终结果则是用Artifact来表示。

  • Notifications(通知):服务端Agent向客户端主动推送的信息,比如一个长期任务的中间运行状态,一个任务有了新的产出等。客户端可以设置通知处理回调。

    所以基本的运行过程就是:

  • 服务端Agent启动Server,通过Agent Card展示能力

  • 客户端Agent/应用连接服务端,并查看Agent Card

  • 根据Agent Card可以把后续的任务发送给服务端Agent

  • 服务端Agent处理任务,必要的时候会输出中间结果,或者要求客户端补充信息

  • 客户端可以等待任务完成;也可以根据任务ID异步获取任务结果

  • 客户端也可以设置通知回调,及时获得任务的进展与工作成果

04

A2A与MCP什么关系?

A2A在诞生动机、架构甚至协议方面都与MCP非常相似,但它们之间的关系与区别还是很清楚的:

MCP解决的是Agent与外部工具/数据之间的集成,是Agent的“内部事务”;A2A解决的是Agent与Agent之间的集成,属于更高层次的集成关系。

它们之间是可以共存与协作的,比如:

图片

在这样的架构中Agent通过MCP使用工具,Agent与Agent之间则通过A2A产生互动与协作。

我们对两者做个简单的对比:

协议

A2A(Google发起)

MCP(Anthropic发起)

相同

开放标准

面向AI应用中的集成挑战

Client/Server架构

以HTTP为基础远程协议

JSON-RPC 2.0消息协议

动机

智能体与智能体之间的互操作问题

智能体与外部工具/数据的集成问题

架构

连接单个智能体与其他智能体

连接单个智能体与外部工具和数据

通信

只有远程(HTTP)

远程(HTTP)或

本地(stdio)

服务能力

暴露

查询智能体卡片

agent card

查询工具、资源、提示

list_tools/resources等

05

A2A的Demo新体验

A2A还没有完整的官方SDK放出,但是谷歌公司在项目中给出了几个帮助理解A2A的示例,我们对其中一个做了简单修改以演示A2A的能力。

【首先准备一个Agent】

这是一个LangGraph开发的智能体,可以独立运行。你需要实现的主要接口是invoke与stream,分别用于非流式与流式调用(在返回消息格式上有特殊处理)。其“轮廓”长这样,内部逻辑无论你是用ReAct Agent还是定义Workflow都不影响:

...
@tool
def search_tavily(query: str, search_depth: str = "basic") -> Dict[str, Any]:
    ...

class ResponseFormat(BaseModel):
    """以这种格式回应用户。"""
    status: Literal["input_required""completed""error"] = "input_required"
    message: str

class SearchAgent:

    SYSTEM_INSTRUCTION = (
        "你是一个专门进行网络搜索的助手。"
        "你的主要目的是使用'search_tavily'工具来回答用户问题,提供最新、最相关的信息。"
        "如果需要用户提供更多信息来进行有效搜索,将响应状态设置为input_required。"
        "如果处理请求时发生错误,将响应状态设置为error。"
        "如果请求已完成并提供了答案,将响应状态设置为completed。"
    )
     
    def __init__(self):
        ...
    def invoke(self, query, sessionId) -> str:
        ...

    async def stream(self, query, sessionId) -> AsyncIterable[Dict[str, Any]]:
        ... 

先写个本地程序对Agent做测试,确保可用:

图片

【启动A2A Server】

现在给这个Agent增加一个前置A2A Server,让它可以对外提供服务,主要逻辑长这样:

def main(host, port):
    
    try:
        capabilities = AgentCapabilities(streaming=True, pushNotifications=True)
        skill = AgentSkill(
            id="search_web",
            name="搜索工具",
            description="搜索web上的相关信息",
            tags=["Web搜索""互联网搜索"],
            examples=["请搜索最新的黑神话悟空的消息"],
        )

        agent_card = AgentCard(
            name="搜索助手",
            description="搜索Web上的相关信息",
            url=f"http://{host}:{port}/",
            version="1.0.0",
            defaultInputModes=SearchAgent.SUPPORTED_CONTENT_TYPES,
            defaultOutputModes=SearchAgent.SUPPORTED_CONTENT_TYPES,
            capabilities=capabilities,
            skills=[skill],
        )

        notification_sender_auth = PushNotificationSenderAuth()
        notification_sender_auth.generate_jwk()
        server = A2AServer(
            agent_card=agent_card,
            task_manager=AgentTaskManager(agent=SearchAgent(), notification_sender_auth=notification_sender_auth),
            host=host,
            port=port,
        )

        server.app.add_route(
            "/.well-known/jwks.json", notification_sender_auth.handle_jwks_endpoint, methods=["GET"]
        )

        logger.info(f"正在启动服务器,地址:{host}:{port}")
        server.start()
    except MissingAPIKeyError as e:
        logger.error(f"错误:{e}")
        exit(1)
    except Exception as e:
        logger.error(f"服务器启动过程中发生错误:{e}")
        exit(1)


if __name__ == "__main__":
    main()

基本过程是声明Agent的能力->发布成Agent卡片->启动A2AServer(uvicorn)。其核心是一个借助于Agent来完成任务的task_manager。

现在启动这个Server:

图片

【客户端应用测试】

用官方提供的客户端命令行来测试这个Server。可以看到,客户端启动时会读取服务端的Agent卡片,了解到Agent的能力与特性(比如Streaming代表支持流式):

图片

现在向这个Agent发送一个任务:

图片

客户端采用了Streaming输出,所以这里可以看到一些中间输出。这些输出可以帮助理解A2A协议的一些标准,比如:

  • 中间过程都是用message来传递,发送的角色是agent

  • 最终的任务输出则是artifact,代表这是任务的最后产出

  • 不管是message还是artifact,具体内容都是有多个part组成

我们来测试几个能力:

* 多轮连续对话

我们输入“我要搜索”,可以看到收到的消息状态是"input-required",这是A2A协议规定的任务状态之一,代表需要补充信息。通过这种方式,你后续的消息会被追加进入任务输入(这也需要Agent支持),实现多轮对话:

图片

* 服务端通知消息

在客户端可以启用通知推送,这时候会在客户端启动一个Server用来等待服务端的通知消息,服务端可以会通过post把任务消息推送到客户端:

图片

* 异步任务结果获取

A2A的任务可以完全异步,即使客户端断开也不影响获取任务结果。为了证明这一点,我们另写了一个简单的根据task_id轮询任务结果的程序。然后执行如下步骤:

1. 在Agent中增加一段sleep时间,模拟很长的任务执行时间;然后启动Server;

2. 在官方客户端中启动一个新任务,然后很快强行退出客户端:

图片

3. 拷贝出任务ID(任务ID是客户端生成的,可以直接在客户端打印出来)。

4. 启动我们编写的轮询客户端(带上任务ID),会看到如下结果:

图片

可以看到,尽管发起任务的客户端已经退出,但不会影响你获取任务结果。

这个Demo很好的演示了A2A的一些原理与能力,包括能力发布、流式处理、多轮对话、异步任务等。显然,你也可以把A2A Server作为企业智能体系统的前后端通信的方式(取代FastAPI),可以减少很多复杂问题的工作量。

 

 如何学习AI大模型?

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。


👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。


1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

<think>好的,用户之前已经询问过CBS算法如何学习,现在他们希望我以算法专家的身份详细讲解CBS的具体过程。首先,我需要确认用户的需求层次。他们可能已经了解了一些基础知识,现在想深入理解算法的工作原理,而不仅仅是学习路径。 接下来,我需要回忆CBS算法的核心机制,包括高层和底层的结构。用户可能对冲突检测解决的具体步骤感兴趣,比如如何生成约束并重新规划路径。此外,用户可能希望了解算法的工作流程,最好用步骤分解的方式,让他们能逐步理解。 还要考虑用户的实际应用场景,比如他们可能在研究多机器人路径规划,或者在开发相关项目。这时候,举例说明会很有帮助,比如用网格世界的例子来演示CBS的执行过程,这样用户能更直观地理解。 同时,需要注意用户可能的疑问点,比如为什么需要高层协作,或者约束树是如何扩展的。需要解释清楚高层节点和约束之间的关系,以及如何通过不断解决冲突来找到可行解。 最后,用户可能想知道CBS的优缺点,以及适用场景,这样他们能评估是否适合他们的项目。所以总结部分要简明扼要,突出关键点,帮助用户做决策。 整体结构应该包括算法框架、流程步骤、实例演示和总结,确保逻辑清晰,由浅入深。避免使用过多术语,必要时用类比或比喻,比如把约束树比作解决问题的不同分支。同时,检查之前回复的内容,确保这次讲解更深入,而不是重复之前的信息。</think>好的,我来从算法原理的角度详细拆解**CBS(Conflict-Based Search)**的核心流程,结合其**双层搜索结构**和**约束传播机制**,帮助你深入理解它的工作逻辑。 --- ### **一、CBS算法框架** CBS是一种**双层搜索算法**,分为**高层(CTNode树)**和**底层(单智能体路径规划)**: - **高层(Constraint Tree)**:管理冲突约束,通过树形结构分支解决冲突 - **底层(Individual Planner)**:为每个智能体在约束下进行路径规划(通常使用A*等算法) --- ### **二、核心步骤分解** #### **1. 初始化顶层根节点** - **根节点属性**: - **路径集合**:每个智能体的**无约束最优路径**(例如用A*计算各自最短路径) - **约束集合**:初始为空(无任何冲突约束) - **总成本**:所有路径的成本总和(如时间步数之和) #### **2. 冲突检测(Conflict Detection)** 遍历所有智能体路径的**时空坐标**(位置+时间步),检测三种冲突类型: - **顶点冲突**:两智能体在同一时间占据同一位置 - **边冲突**:两智能体在相邻时间步交换位置(相向而行穿越彼此) - **跟随冲突**:同一路径中后续智能体超越前方智能体(动态环境特有) **示例检测逻辑**: ```python def detect_conflict(paths): for t in max_timestep: for i in range(n_agents): for j in range(i+1, n_agents): # 顶点冲突检测 if paths[i][t] == paths[j][t]: return VertexConflict(i, j, t, paths[i][t]) # 边冲突检测 if t>0 and (paths[i][t-1] == paths[j][t] and paths[i][t] == paths[j][t-1]): return EdgeConflict(i, j, t-1, t) return None ``` #### **3. 约束生成分支(Constraint Branching)** 当检测到冲突`(a_i, a_j, t, loc)`时,**分裂当前CTNode为两个子节点**: - **子节点1**:添加约束`a_i不能在时间t出现在loc` → 重新规划a_i的路径 - **子节点2**:添加约束`a_j不能在时间t出现在loc` → 重新规划a_j的路径 **约束的数学表达**: 每个约束可表示为元组`(agent_id, time, location, is_positive)` (注:CBS通常使用**负约束**,即禁止某时空状态) #### **4. 底层重规划(Low-Level Planning)** 对受约束的智能体使用**带约束的A***算法(如Space-Time A*): - **状态扩展**:每个状态包含`(x,y,t)`坐标 - **约束检查**:跳过被禁止的时空状态 - **启发函数**:通常用曼哈顿距离或欧氏距离的时态扩展 #### **5. 优先队列管理** 使用优先队列(通常是最小堆)管理CTNode,排序依据: - **总路径成本**(Sum of Costs) - **冲突数量**(辅助排序) - **启发式估计**(可选) 每次从队列中取出**成本最小的节点**进行扩展,保证最优性。 --- ### **三、算法流程图示** ``` 初始化根节点 → 加入优先队列 While 队列不为空: 取出最小成本节点 检测路径冲突 If 无冲突 → 返回当前路径作为解 Else: 生成约束分支 对每个分支进行底层重规划 若重规划成功 → 生成新节点加入队列 ``` --- ### **四、实例演示(网格世界)** 假设两个智能体A1和A2在3x3网格中: - **初始路径**: A1: (0,0)(0,1)(0,2) A2: (2,2)(1,2)(0,2) **冲突检测**:在t=2时,两者在(0,2)发生顶点冲突 **分支处理**: - 分支1:禁止A1在t=2出现在(0,2) → A1新路径:(0,0)(1,0)(1,1)(0,2) - 分支2:禁止A2在t=2出现在(0,2) → A2新路径:(2,2)(2,1)(1,1)(0,2) 继续检测新路径中的潜在冲突,直到找到无冲突解。 --- ### **五、算法特性分析** | 特性 | 说明 | |---------------------|--------------------------------------------------------------------| | **完备性** | 保证找到解(如果存在) | | **最优性** | 在Sum of Costs指标下是最优的 | | **时间复杂度** | 最差情况指数级,但实际中约束剪枝效率较高 | | **空间复杂度** | CT树深度相关 | | **适用场景** | 中小规模MAPF问题(通常≤50智能体),对路径质量要求高的场景 | --- ### **六、优化方向** 1. **启发式策略**:在高层搜索中使用`ICTS`(Increasing Cost Tree Search)启发式 2. **冲突优先**:优先处理关键冲突(如最早发生的冲突) 3. **对称剪枝**:识别并跳过等效约束分支 4. **动态重规划**:局部调整路径而非全局重计算 如果想深入算法实现细节,推荐阅读Sharon et al.的原始论文,并结合Python实现一个最小化CBS demo(约300行代码即可完成核心逻辑)。需要进一步讨论某个具体环节可以告诉我!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值