技术速递|使用 Semantic Kernel 与 A2A 协议构建多智能体解决方案

作者:卢建晖 - 微软高级云技术布道师

翻译/排版:Alan Wang

在快速发展的 AI 应用开发领域,能够协调多个智能体已成为构建复杂企业级解决方案的关键。虽然单个 AI 智能体擅长特定任务,但复杂的业务场景往往需要跨平台、跨框架甚至跨组织边界的专业智能体协同工作。这正是微软的 Semantic Kernel 编排功能与 A2A(Agent-to-Agent)协议相结合,构建真正互操作多智能体系统的重要基础。

理解 A2A 协议:超越传统工具集成

A2A 协议由 Google 于 2025 年 4 月推出,并得到了超过 50 家技术合作伙伴的支持,旨在解决 AI 生态系统中的一个核心难题:让智能体能够以对等的身份进行沟通与协作,而不仅仅是作为工具被调用。与侧重连接智能体与外部工具和数据源的 MCP(模型上下文协议)不同,A2A 构建了一个专门为智能体间交互设计的标准化通信层。

A2A 的核心能力

  • 通过 Agent 卡片发现智能体:每个支持 A2A 的智能体都会公开一个机器可读的 “Agent 卡片”,这是一个 JSON 文档,用于展示其能力、接入端点、支持的消息类型、认证要求及运行时元数据。这种发现机制使客户端智能体能够动态识别并选择最适合执行特定任务的远程智能体。

  • 通过生命周期跟踪进行任务管理:A2A 的所有交互都围绕有着明确生命周期的独立任务展开,这些任务可以即时完成,也可以持续较长时间,并提供实时状态更新,使该协议既适用于快速的 API 调用,也适用于可能耗时数小时或数天的复杂研究操作。

  • 丰富的消息交换:通信通过结构化消息进行,消息包含具有特定内容类型的“部分”。这使得智能体能够协商合适的交互方式,并交换多种类型的数据,包括文本、结构化 JSON、文件,甚至多媒体流。

  • 企业级安全保障:A2A 构建在常见的 Web 标准之上(如 HTTP、JSON-RPC 2.0、Server-Sent Events),并结合了企业级的身份验证与权限控制,支持 OpenAPI 的认证机制,在不暴露智能体内部状态或专有工具的前提下,实现安全的协作。

A2A 与 MCP:互为补充,而非竞争关系

一个常见的误解是 A2A 与 Anthropic 的模型上下文协议(MCP)存在竞争关系。实际上,这两个协议服务于智能体 AI 技术栈中的不同层面:

  • MCP 连接智能体与工具和数据 —— 使其能够访问外部 API、数据库、文件系统等结构化资源

  • A2A 连接智能体与其他智能体 —— 实现对等协作、任务委派和分布式问题解决

你可以把它理解为:MCP 是给智能体一把锤子,而 A2A 是教它如何与一个施工队协同工作。大多数复杂的应用程序都会同时利用这两种协议。

Semantic Kernel:编排引擎

微软的 Semantic Kernel 为构建支持 A2A 的多智能体系统提供了理想的基础。作为一个开源 SDK,Semantic Kernel 在以下方面表现出色:

  • 插件化架构:通过可复用插件轻松扩展智能体能力

  • 多模型支持:协调不同的 AI 模型以执行专门任务

  • 企业集成:无缝连接现有的企业系统与 API

  • 智能体框架:提供实验性但强大的多智能体协同能力

为什么要结合 Semantic Kernel 与 A2A?

  • 框架无关互操作性:Semantic Kernel 智能体可与 LangGraph、CrewAI、Google ADK 或其他 A2A 兼容框架智能体进行通信

  • 保留 Semantic Kernel 的优势:在享受 Semantic Kernel 插件生态与提示工程、企业能力的同时,实现跨平台兼容

  • 渐进迁移路径:现有 Semantic Kernel 应用可逐步采用 A2A,无需大规模重构

  • 云原生设计:支持认证、日志、可观测性,满足企业场景需求

A2A 支持系统的架构模式

在使用 Semantic Kernel 和 A2A 设计多智能体系统时,我们的实现架构展示了几个关键模式:

使用 Azure AI Foundry 的集中路由

我们采用的主要模式是使用由 Azure AI Foundry 驱动的中央路由智能体,智能地将任务委派给各个专业的远程智能体:
在这里插入图片描述

关键组件

  • 主机智能体:基于 Azure AI Agents 的中央路由系统,负责智能决策

  • A2A 协议:标准化的智能体间通信机制

  • Semantic Kernel:集成 MCP 的高级智能体框架

  • 远程智能体:使用不同通信协议的专业任务执行者

优势

  • 通过 Azure AI Foundry 的线程实现集中式对话状态管理

  • 基于智能体能力和用户意图进行智能任务委派

  • 在不同智能体交互中提供一致的用户体验

  • 明确的审计记录和完善的错误处理机制

多协议智能体通信

系统展示了不同通信协议如何实现共存:
在这里插入图片描述

通信模式:

  • A2A HTTP/JSON-RPC:适用于具备标准化发现能力的通用工具型智能体

  • STDIO:用于基于进程的智能体,如 Playwright 自动化

  • Server-Sent Events(SSE):用于 Azure 中的无服务器 MCP 函数

MCP 与 A2A 的混合集成

我们的架构展示了 MCP 协议与 A2A 协议如何相互补充:
在这里插入图片描述

  • 面向工具的 MCP:直接集成 Azure Functions、开发工具和数据源

  • 面向智能体的 A2A:实现智能体间通信与任务委派

  • Semantic Kernel:作为编排层,桥接两种协议

实施详解

项目结构与组件

我们的多智能体系统采用模块化架构:
在这里插入图片描述

开发环境设置

要构建这个支持 A2A 的 Semantic Kernel 系统,我们需要:

# Initialize Python project with uv (recommended)
uv init multi_agent_system
cd multi_agent_system
# Core dependencies for Semantic Kernel and Azure integration
uv add semantic-kernel[azure]
uv add azure-identity
uv add azure-ai-agents
uv add python-dotenv
# A2A protocol dependencies
uv add a2a-client
uv add httpx
# MCP integration dependencies
uv add semantic-kernel[mcp]
# Web interface dependencies
uv add gradio
# Development dependencies
uv add --dev pytest pytest-asyncio

环境配置

配置以下环境变量:

# Azure AI Foundry configuration
AZURE_AI_AGENT_ENDPOINT=https://your-ai-foundry-endpoint.azure.com
AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME=Your AI Foundry Model Deployment Name
# Remote agent endpoints
PLAYWRIGHT_AGENT_URL=http://localhost:10001
TOOL_AGENT_URL=http://localhost:10002
# Optional: MCP server configuration
MCP_SSE_URL=http://localhost:7071/runtime/webhooks/mcp/sse

创建中央路由智能体

我们系统的核心是利用 Azure AI Foundry 实现智能任务委派的路由智能体:

import json
import os
import time
import uuid
from typing import Any, Dict, List
import httpx
from a2a.client import A2ACardResolver
from azure.ai.agents import AgentsClient
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv
class RoutingAgent:"""Central routing agent powered by Azure AI Foundry."""def __init__(self):self.remote_agent_connections = {}self.cards = {}self.agents_client = AgentsClient(endpoint=os.environ["AZURE_AI_AGENT_ENDPOINT"],credential=DefaultAzureCredential(),)self.azure_agent = Noneself.current_thread = Noneasync def initialize(self, remote_agent_addresses: list[str]):"""Initialize with A2A agent discovery."""# Discover remote agents via A2A protocolasync with httpx.AsyncClient(timeout=30) as client:for address in remote_agent_addresses:try:card_resolver= A2ACardResolver(client, address)card = await card_resolver.get_agent_card()from remote_agent_connection import RemoteAgentConnectionsremote_connection = RemoteAgentConnections(agent_card=card, agent_url=address)self.remote_agent_connections[card.name] = remote_connectionself.cards[card.name] = cardexcept Exception as e:print(f'Failed to connect to agent at {address}: {e}')# Create Azure AI agent for intelligent routingawait self._create_azure_agent()async def _create_azure_agent(self):"""Create Azure AI agent with function calling capabilities."""instructions = self._get_routing_instructions()# Define function for task delegationtools = [{"type": "function","function": {"name": "send_message","description": "Delegate task to specialized remote agent","parameters": {"type": "object","properties": {"agent_name": {"type": "string"},"task": {"type": "string"}},"required": ["agent_name", "task"]}}}]model_name = os.environ.get("AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME", "gpt-4")self.azure_agent = self.agents_client.create_agent(model=model_name,name="routing-agent",instructions=instructions,tools=tools)self.current_thread = self.agents_client.threads.create()print(f"Routing agent initialized: {self.azure_agent.id}")def _get_routing_instructions(self) -> str:"""Generate context-aware routing instructions."""agent_info = [{'name': card.name, 'description': card.description}for card in self.cards.values()]return f"""You are an intelligent routing agent for a multi-agent system.
Available Specialist Agents:
{json.dumps(agent_info, indent=2)}

路由指引:

  • 网页自动化、截图、浏览器任务 → Playwright 智能体

  • 开发任务、文件操作、代码库管理 → 工具智能体

  • 委派任务时务必提供完整的任务上下文

  • 向用户说明哪个智能体正在处理他们的请求

构建集成 MCP 的专业智能体

我们的远程智能体利用 Semantic Kernel 的 MCP 集成,实现可扩展能力:

from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings
from semantic_kernel.connectors.mcp import MCPStdioPlugin, MCPSsePlugin
from azure.identity.aio import DefaultAzureCredential
class SemanticKernelMCPAgent:"""Specialized agent with MCP plugin integration."""def __init__(self):self.agent = Noneself.client = Noneself.credential = Noneself.plugins = []async def initialize_playwright_agent(self):"""Initialize with Playwright automation via MCP STDIO."""try:self.credential= DefaultAzureCredential()self.client = await AzureAIAgent.create_client(credential=self.credential).__aenter__()# Create Playwright MCP pluginplaywright_plugin = MCPStdioPlugin(name="Playwright",command="npx",args=["@playwright/mcp@latest"],)await playwright_plugin.__aenter__()self.plugins.append(playwright_plugin)# Create specialized agentagent_definition = await self.client.agents.create_agent(model=AzureAIAgentSettings().model_deployment_name,name="PlaywrightAgent",instructions=("You are a web automation specialist. Use Playwright to ""navigate websites, take screenshots, interact with elements, ""and perform browser automation tasks."),)self.agent = AzureAIAgent(client=self.client,definition=agent_definition,plugins=self.plugins,)except Exception as e:await self.cleanup()raiseasync def initialize_tools_agent(self, mcp_url: str):"""Initialize with development tools via MCP SSE."""try:self.credential= DefaultAzureCredential()self.client = AzureAIAgent.create_client(credential=self.credential)# Create development tools MCP plugintools_plugin = MCPSsePlugin(name="DevTools",url=mcp_url,)await tools_plugin.__aenter__()self.plugins.append(tools_plugin)agent_definition = await self.client.agents.create_agent(model=AzureAIAgentSettings().model_deployment_name,name="DevAssistant",instructions=("You are a development assistant. Help with repository ""management, file operations, opening projects in VS Code, ""and other development tasks."),)self.agent = AzureAIAgent(client=self.client,definition=agent_definition,plugins=self.plugins,)except Exception as e:await self.cleanup()raiseasync def invoke(self, user_input: str) -> dict[str, Any]:"""Process tasks through the specialized agent."""if not self.agent:return{'is_task_complete': False,'content': 'Agent not initialized.',}try:responses = []async for response in self.agent.invoke(messages=user_input,thread=self.thread,):responses.append(str(response))self.thread = response.threadreturn {'is_task_complete': True,'content': "\n".join(responses) or "No response received.",}except Exception as e:return {'is_task_complete': False,'content': f'Error: {str(e)}',}

基于 Gradio 的 Web 界面

系统提供了由 Gradio 驱动的现代聊天界面:

import asyncio
import gradio as gr
from routing_agent import RoutingAgent
async def get_response_from_agent(message: str, history: list[gr.ChatMessage]
) -> gr.ChatMessage:"""Process user messages through the routing system."""global ROUTING_AGENTtry:response= 
awaitROUTING_AGENT.process_user_message(message)return gr.ChatMessage(role="assistant", content=response)except Exception as e:return gr.ChatMessage(role="assistant",content=f"❌ Error: {str(e)}")
async def main():"""Launch the multi-agent system."""# Initialize routing agentglobal ROUTING_AGENTROUTING_AGENT= 
awaitRoutingAgent.create([os.getenv('PLAYWRIGHT_AGENT_URL', 'http://localhost:10001'),os.getenv('TOOL_AGENT_URL', 'http://localhost:10002'),])ROUTING_AGENT.create_agent()# Create Gradio interfacewith gr.Blocks(theme=gr.themes.Ocean()) as demo:gr.Markdown("# 🤖 Azure AI Multi-Agent System")gr.ChatInterface(get_response_from_agent,title="Chat with AI Agents",examples=["Navigate to github.com/microsoft and take a screenshot","Clone repository https://github.com/microsoft/semantic-kernel","Open the cloned project in VS Code",])demo.launch(server_name="0.0.0.0", server_port=8083)

部署与运维

本地开发环境:

# Start MCP server (Azure Functions)
cd mcp_sse_server/MCPAzureFunc
func start
​
# Start remote agents in separate terminals
cd remote_agents/playwright_agent && uv run .
cd remote_agents/tool_agent && uv run .# Start the host agent with web interface
cd host_agent && uv run .

生产环境注意事项:

  • 将每个智能体作为独立微服务部署,推荐使用 Azure Container Apps

  • 利用 Azure Service Bus 实现可靠的智能体发现与通信

  • 使用 Azure Application Insights 实施全面的日志记录

  • 配置合适的身份验证和网络安全措施

实际应用示例

基于我们的实现,以下是多智能体系统处理不同类型请求的实用示例:

示例一:网页自动化任务

User: "Navigate to github.com/microsoft and take a screenshot"
Flow:
1. Host Agent (Azure AI) analyzes the request
2. Identifies this as a web automation task  
3. Delegates to Playwright Agent via A2A protocol
4. Playwright Agent uses MCP STDIO to execute browser automation
5. Returns screenshot and navigation details to user

示例二:开发工作流

User: "Clone https://github.com/microsoft/semantic-kernel and open it in VS Code"
Flow:
1. Host Agent recognizes repository management + IDE operation
2. Delegates to Tool Agent via A2A protocol  
3. Tool Agent uses MCP SSE connection to Azure Functions
4. Executes git clone and VS Code launch commands
5. Reports success status back to user

注意:你可以点击 链接 获取这一示例。

未来展望与路线图

随着 Semantic Kernel 和 A2A 协议的持续发展,以下几个方向值得关注:

新增功能

  • 增强流媒体支持:提升智能体间实时流交互的能力

  • 多模态通信:扩展对音频、视频及其他丰富媒体类型的支持

  • 动态用户体验协商:智能体能够在对话过程中协商并调整交互方式

  • 改进客户端主动方法:在基本任务管理之上更好地支持客户端发起的高级操作

集成机会

  • Azure AI Foundry 集成:在 Azure AI 平台中原生支持 A2A

  • Copilot Studio 兼容:与微软低代码智能体构建平台无缝集成

  • 企业服务集成:加强与企业身份认证和治理系统的结合

社区与生态

A2A 协议获得了超过 50 家技术合作伙伴的强力支持。随着生态的成熟,预期将出现:

  • 更完善的工具链和 SDK 支持

  • 针对常见多智能体场景的标准化模式

  • 加强的互操作性测试和认证项目

  • 不断增长的可复用 A2A 兼容智能体库

总结

Semantic Kernel 强大的编排能力与谷歌 A2A 协议的结合,标志着构建真正互操作多智能体系统的重要进步。该集成让开发者能够:

  • 打破不同 AI 框架和平台间的孤岛效应

  • 利用已有的 Semantic Kernel 投资,同时实现跨平台兼容

  • 构建具备企业级安全性和可观测性的可扩展多智能体解决方案

  • 采用智能体通信的开放标准,保障应用的未来适应性

随着智能体 AI 领域的快速演进,构建灵活且可互操作的系统变得愈发重要。通过结合 Semantic Kernel 的编排能力与 A2A 的标准通信功能,开发者可以打造既强大又具可移植性的多智能体应用。

真正协作型 AI 系统的旅程才刚刚开始,本文展示的工具和模式为构建下一代智能应用奠定了坚实的基础。无论是增强现有的 Semantic Kernel 应用,还是从零构建新的多智能体系统,这些技术的融合都为打造更强大、更灵活、更可互操作的 AI 解决方案指明了方向。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/92508.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/92508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端跨域请求原理及实践

在前端开发中,"跨域"是一个绕不开的话题。当我们的页面尝试从一个域名请求另一个域名的资源时,浏览器往往会抛出类似Access to fetch at xxx from origin xxx has been blocked by CORS policy的错误。下面将深入探讨跨域请求的底层原理&#…

SpringBoot07-数据层的解决方案:SQL

一、内置数据源 1-1、【回顾】Druid数据源的配置 druid的两种导入格式 1-2、springboot提供的3种内置数据源的配置 若是不配置Druid, springboot提供了3中默认的数据源配置,它们分别是: 1. HikariCP(默认) 从 Spring…

前端自动化埋点:页面模块级行为跟踪与问题定位系统​​的技术设计方案

一、核心设计目标​​精细化监控​​:定位到页面中​​单个模块​​的曝光、点击等行为。​​低侵入性​​:业务代码与埋点逻辑解耦,降低开发维护成本。​​链路可追踪​​:串联用户从曝光到操作的完整行为路径。​​实时性​​&a…

Node.js 与 Java 性能对比

一、核心架构与任务模型对比Node.js 单线程事件循环 非阻塞I/O 通过V8引擎执行JavaScript,采用事件驱动模型,所有I/O操作(如网络请求、文件读写)均为非阻塞。单线程处理所有请求,但通过事件循环(Event Loo…

Python3常见接口函数

Python3常见接口函数一、基础内置函数 输入输出 print():输出内容input():读取用户输入 类型转换 int()、float()、str()、bool():基础类型转换list()、tuple()、set()、dict():容器类型转换bin()、hex()、oct():进制转…

《P4092 [HEOI2016/TJOI2016] 树》

题目描述在 2016 年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树,根为 1 ,有以下两种操作:标记操作:对某个结点打上标记。(在最开始,只有结…

TCP头部

TCP头部字段详解1. 源端口和目的端口(各16位)功能:标识发送和接收应用程序范围:0-65535(0-1023为知名端口)技术细节:客户端通常使用临时端口(1024-65535)服务端使用固定端…

LinkedList与链表(单向)(Java实现)

引入链表结构:在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后 搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。因此:java集合中又引入…

网络--VLAN技术

目录 VLAN实验报告 一、实验拓扑 二、实验要求 三、实验思路 1、实验准备 2. VLAN 3. DHCP 自动分配 4、 全网可达验证 四、实验步骤 (一)交换机配置- VLAN 创建与接口划分 (二)路由器配置(R1&#xff0c…

网络基础17--设备虚拟化

一、传统MSTPVRRP的不足传统MSTPVRRP设计:规划复杂:需要详细规划VRRP多实例的Master归属、MSTP的VLAN和生成树实例归属,以及IP网段。收敛速度慢:故障恢复速度一般在秒级,VRRP收敛时间至少需要3秒,故障恢复速…

深入解析Hadoop资源隔离机制:Cgroups、容器限制与OOM Killer防御策略

Hadoop资源隔离机制概述在分布式计算环境中,资源隔离是保障多任务并行执行稳定性的关键技术。Hadoop作为主流的大数据处理框架,其资源管理能力直接影响集群的吞吐量和任务成功率。随着YARN架构的引入,Hadoop实现了计算资源与存储资源的解耦&a…

static 关键字的 特殊性

static 关键字的 “特殊性” 主要体现在其与类、对象的绑定关系,以及由此带来的一些反常规规则,具体如下:生命周期与内存位置特殊静态成员(变量 / 方法)随类加载而创建,随类卸载而销毁,生命周期…

win10系统Apache以 FastCGI方式运行PHP

文件下载及官方网站 VC运行库Latest下载页:Latest supported Visual C Redistributable downloads | Microsoft Learnapache httpd官网:Welcome! - The Apache HTTP Server Project下载页:Apache VS17 binaries and modules downloadphp官网:PHP: Hypertext Preprocessor下载页…

MCP与企业数据集成:ERP、CRM、数据仓库的统一接入

MCP与企业数据集成:ERP、CRM、数据仓库的统一接入 🌟 Hello,我是摘星! 🌈 在彩虹般绚烂的技术栈中,我是那个永不停歇的色彩收集者。 🦋 每一个优化都是我培育的花朵,每一个特性都是我…

【milvus检索】milvus检索召回率

Milvus中两种核心查询方式:暴力搜索(Brute-force Search) 和 近似最近邻搜索(Approximate Nearest Neighbor, ANN)。 逐一计算相似度:这是暴力搜索,能保证100%找到最相似的向量,但速…

docker Neo4j

Day 1 :Docker Desktop 基础熟悉 运行官方 hello-world 测试: docker -run hello-world 运行 Nginx 体验容器暴露端口: docker run -d -p 8080:80 nginx -d --detach 以 分离模式 运行容器 -p --publish 设置 宿主机与容器的端口映射。…

Win10_Qt6_C++_YOLO推理 -(1)MingW-opencv编译

先上效果图: 因为是一个为了尝试跑通的demo,美观、功能都先忽略哈。 一、环境 库版本下载链接备注cmakecmake-4.1.0-rc2-windows-x86_64.msihttps://cmake.org/download/make x86_64-15.1.0-release-posix-seh-ucrt-rt_v12-rev0.7zhttps://github.com/…

day060-zabbix监控各种客户端

文章目录0. 老男孩思想-一个人的背书1. zabbix各种客户端1.1 Windows Server监控1.2 网络设备监控1.3 java应用监控1.4 前端监控java程序故障2. 相关项监控3. 思维导图0. 老男孩思想-一个人的背书 学历、能力、态度、特长、人品、口碑(身边的人、领导) …

OpenCV 官翻 2 - 图像处理

文章目录色彩空间转换目标色彩空间转换目标追踪如何确定要追踪的HSV值?练习图像的几何变换目标变换缩放翻译旋转仿射变换透视变换其他资源图像阈值处理目标简单阈值化自适应阈值化大津二值化法Otsu二值化算法原理其他资源练习图像平滑处理目标二维卷积(图…

动态路由协议基础

一、动态路由协议简介2.动态路由协议的基本功能二、动态路由协议分类对比项距离矢量(如 RIP)链路状态(如 OSPF)信息来源只听直接邻居说收集全网链路状态,自己建 “地图”计算逻辑邻居给的距离 1,简单累加用…