PS:这期本来想介绍一款Agent的框架–Agently,个人感觉挺好用的,感兴趣的可以从这里进行阅读
AI的技术现在风头正盛并且极速向成熟落地的方向发展。Google推出了Agent2Agent(A2A)协议来解决这一问题,这是一个开放标准,旨在解决异构系统的通信难题。还是老样子,结合Python项目实例,分享如何构建多Agent协作系统。
一、智能代理协作的痛点与挑战
企业级AI应用开发过程中,常见的痛点包括:
- 用LangChain写的文档分析Agent无法和用CrewAI构建的团队协作Agent正常对话
- 不同厂商出品的智能代理没有共享一套对话协议,彼此之间像说着不同方言
- 在不同代理之间传递图片、视频这种多模态内容存在巨大挑战
- 跨平台跨语言的Agent系统集成需要大量定制开发工作
这些问题的影响不容小觑。据行业调研数据显示,78%的企业级AI项目因为Agent之间配合不畅导致延期交付。有的开发团队甚至在多代理系统集成上消耗了超过40%的开发时间,严重影响开发效率。
二、A2A协议:智能代理通信的"HTTP协议"
面对这些问题,Google推出的A2A协议的目标很明确 —— 做智能代理之间的"HTTP协议",让不同体系的Agent之间有个统一的交流语言。
2.1 核心概念与架构
A2A协议的核心概念设计简洁而实用:
- Agent Card:相当于代理的"身份证",是个JSON文件,通常放在
/.well-known/agent.json
目录下,描述代理的能力、技能和认证需求 - A2A服务器:负责接收任务的代理,提供HTTP端点实现A2A协议方法
- A2A客户端:发送任务的一方,可以是应用程序也可以是其他代理
- 任务(Task):工作单元,有自己的ID,会经历不同状态
- 消息(Message):客户端和代理之间传递的内容
- 部分(Part):消息的组成部分,可以是文本、文件或结构化数据
这种设计既保证了通用性,又不失灵活性。
2.2 技术原理深度解析
技术细节上,A2A协议基于JSON-RPC 2.0实现,用HTTP(S)传输,既支持同步请求/响应,也支持服务器发送事件(SSE)的流式传输。核心数据结构设计精巧:
# A2A核心数据结构示例
class TaskState(str, Enum):
SUBMITTED = "submitted" # 任务已接收,尚未开始
WORKING = "working" # 任务正在处理中
INPUT_REQUIRED = "input-required" # 需要进一步用户输入
COMPLETED = "completed" # 任务成功完成
CANCELED = "canceled" # 任务被取消
FAILED = "failed" # 任务失败
UNKNOWN = "unknown" # 状态未知
class Message(BaseModel):
role: Literal["user", "agent"] # 消息发送者角色
parts: List[Part] # 消息内容部分
metadata: dict[str, Any] | None = None # 元数据
典型的A2A工作流程包括以下几步:
- 发现:客户端从服务器的公共URL获取Agent Card,了解对方能提供哪些服务
- 初始化:客户端发送
tasks/send
请求,带上初始消息和任务ID - 处理:服务器处理任务并返回结果(或者流式地更新状态)
- 交互:如果任务进入
input-required
状态,客户端需要补充信息 - 完成:任务最终会到达某个终止状态(完成、失败或取消)
这个设计符合实际工作流程,相比某些过度设计的协议更容易落地实施。
三、多框架A2A实现:从LangGraph到CrewAI
A2A协议的最大优势在于能够连接各种不同的Agent框架。下面是几个主流框架的A2A实现示例:
3.1 LangGraph Agent实现
LangGraph是基于有向图的Agent框架,特别适合构建复杂推理流程。LangGraph实现A2A接口的核心代码如下:
# LangGraph Agent的A2A接口实现
from samples.python.common.server import A2AServer, InMemoryTaskManager
from samples.python.common.types import TaskState, Message, TextPart
from langgraph.graph import StateGraph
# 构建LangGraph图(简化版)
def build_currency_graph():
workflow = StateGraph(CurrencyState)
workflow.add_node("convert_currency", currency_converter)
workflow.add_node("generate_response", generate_final_response)
workflow.add_edge("convert_currency", "generate_response")
return workflow.compile()
# 包装为A2A服务器
class LangGraphAgent(A2AServer):
def __init__(self):
super().__init__(
name="Currency Conversion Agent",
description="可以执行货币换算的智能代理",
task_manager=InMemoryTaskManager(),
skills=[{
"id": "currency_conversion",
"name": "货币换算",
"description": "可以转换不同国家的货币汇率"
}]
)
self.graph = build_currency_graph()
async def process_task(self, task_id, message):
# 处理用户输入并通过图执行
result = await self.graph.ainvoke({"query": message.parts[0].text})
return TaskState.COMPLETED, Message(
role="agent",
parts=[TextPart(text=result["response"])]
)
这段代码的核心逻辑很简单 - 就是将LangGraph的工作流包装为A2A接口,暴露出标准的任务处理方法。在汇率换算等项目中采用这种方式,可以获得很好的效果。
3.2 CrewAI Agent实现
CrewAI框架特别适合多智能体协作场景。在设计稿生成等项目中,CrewAI实现的A2A接口如下:
# CrewAI的A2A适配器核心代码
from crewai import Agent, Crew, Task
from samples.python.common.server import A2AServer
class ImageGenerationAgent(A2AServer):
def __init__(self):
super().__init__(
name="Image Generation Agent",
description="创建个性化图像的代理",
task_manager=InMemoryTaskManager(),
capabilities={"streaming": True},
skills=[{
"id": "generate_image",
"name": "图像生成",
"outputModes": ["text", "file"]
}]
)
# 创建CrewAI代理和任务
self.artist = Agent(
role="艺术家",
goal="创建高质量、个性化的图像",
backstory="你是一位经验丰富的数字艺术家",
tools=[ImageGenerationTool()]
)
async def process_task(self, task_id, message):
# 提取提示并通过CrewAI处理
prompt = message.parts[0].text
# 创建任务并执行
image_task = Task(
description=f"根据以下描述创建图像: {prompt}",
agent=self.artist
)
crew = Crew(agents=[self.artist], tasks=[image_task])
result = crew.kickoff()
# 返回结果,包含生成的图像
return self._prepare_response_with_image(result, task_id)
这里的关键是如何处理CrewAI生成的图像结果并通过A2A协议正确传递。在处理图像文件传输时可能会遇到一些挑战,但A2A的Part机制提供了优雅的解决方案。
3.3 Google ADK Agent实现
Google的Agent Development Kit (ADK)在表单处理方面有独到之处,适用于费用报表等项目:
# ADK的A2A集成
from google.ai.generativelanguage import Part
from google.ai.generativelanguage import FunctionDeclaration
from google.generativeai.types import content_types
import google.generativeai as genai
class ExpenseAgent(A2AServer):
def __init__(self):
super().__init__(
name="Expense Report Agent",
description="帮助填写和管理费用报告",
task_manager=InMemoryTaskManager(),
skills=[{
"id": "expense_form",
"name": "费用表单填写",
"inputModes": ["text", "data"],
"outputModes": ["text", "data"]
}]
)
self.model = genai.GenerativeModel(
model_name="gemini-1.5-pro",
tools=[FunctionDeclaration(
name="create_expense_form",
description="创建费用报告表单",
parameters={...} # 表单字段定义
)]
)
不同框架各有所长,但通过A2A协议,它们可以组合使用。当LangGraph的分析代理和CrewAI的协作代理能够无缝对接时,能够产生极为强大的协同效应。
四、构建A2A多代理通信系统实战
接下来通过一个完整的实战案例,演示如何构建基于A2A协议的多代理协作系统。这个系统能够处理复杂查询,将任务分派给不同专业领域的Agent协同工作。
4.1 项目架构设计
系统架构包含以下几个组件:
- 主机代理:相当于"总经理",负责接收用户请求,分析意图,指挥其他专业代理
- 远程代理:各个"专家",提供文档分析、代码生成、数据可视化等能力
- A2A通信层:负责消息传递、状态同步和内容转换的基础设施
- Web界面:提供用户交互界面,展示多代理协作的全过程
相比微服务架构,基于A2A协议的设计更加简洁,也更容易扩展。
4.2 系统核心代码实现
4.2.1 主机代理实现
主机代理是整个系统的核心,实现如下:
# host_agent.py
import asyncio
from typing import Dict, List
class HostAgent:
"""主机代理,负责协调多个专业代理"""
def __init__(self):
self.remote_agents = {}
self.conversations = {}
async def register_agent(self, agent_url: str) -> Dict:
"""注册新的远程代理"""
client = A2AClient()
agent_card = await client.fetch_agent_card(agent_url)
# 添加到已知代理列表
agent_id = agent_card.get("name")
self.remote_agents[agent_id] = {
"card": agent_card,
"client": client,
"url": agent_url
}
return {"status": "success", "agent_id": agent_id}
async def process_request(self, user_query: str, conversation_id: str = None) -> Dict:
"""处理用户请求,协调远程代理"""
if not conversation_id:
conversation_id = f"conv_{len(self.conversations) + 1}"
self.conversations[conversation_id] = []
# 分析查询并确定合适的代理
intent, target_agents = await self._analyze_query(user_query)
# 并行分发任务给选定的代理
tasks = []
for agent_id in target_agents:
if agent_id in self.remote_agents:
task = self._delegate_to_agent(
self.remote_agents[agent_id]["client"],
user_query,
conversation_id
)
tasks.append(task)
# 等待所有代理响应
results = await asyncio.gather(*tasks)
# 合成最终响应
final_response = await self._synthesize_responses(results, intent)
# 记录对话历史
self.conversations[conversation_id].append({
"role": "user",
"content": user_query
})
self.conversations[conversation_id].append({
"role": "agent",
"content": final_response
})
return {
"conversation_id": conversation_id,
"response": final_response
}
async def _analyze_query(self, query: str) -> (str, List[str]):
"""分析查询意图,确定需要调用的代理"""
# 实际项目中,这里可以使用更复杂的语义分析
intent = "general"
target_agents = []
if "代码" in query or "编程" in query:
intent = "code_generation"
target_agents.append("代码生成器")
if "图片" in query or "图像" in query:
intent = "image_generation"
target_agents.append("图像生成器")
if "数据" in query or "分析" in query:
intent = "data_analysis"
target_agents.append("数据分析器")
# 如果没有明确意图,使用通用代理
if not target_agents:
target_agents = ["通用助手"]
return intent, target_agents
async def _delegate_to_agent(self, client, query: str, conversation_id: str):
"""委托任务给特定代理"""
task_id = f"{conversation_id}_{client.agent_name}"
# 创建A2A任务
response = await client.tasks_send({
"id": task_id,
"message": {
"role": "user",
"parts": [{"type": "text", "text": query}]
}
})
return response
async def _synthesize_responses(self, results, intent):
"""合成多个代理的响应"""
# 实际项目中,可以更智能地组合结果
combined_response = ""
for result in results:
if result.get("status", {}).get("state") == "completed":
message = result.get("status", {}).get("message", {})
for part in message.get("parts", []):
if part.get("type") == "text":
combined_response += part.get("text", "") + "\n\n"
return combined_response or "抱歉,处理您的请求时遇到了问题。"
在编写此类代码时的一个常见挑战是并发任务处理,特别是在高负载情况下。使用asyncio.gather并发处理可以显著提升性能。另一个实用技巧是按意图动态路由请求,这样能大幅提升用户体验。
4.2.2 通用A2A客户端实现
# a2a_client.py
import aiohttp
import json
import uuid
from typing import Dict, Any, Optional
class A2AClient:
"""A2A协议客户端"""
def __init__(self, base_url: str = None):
self.base_url = base_url
self.agent_card = None
self.agent_name = None
async def fetch_agent_card(self, agent_url: str) -> Dict:
"""获取代理卡片信息"""
if not agent_url.endswith('/'):
agent_url += '/'
card_url = f"{agent_url}.well-known/agent.json"
async with aiohttp.ClientSession() as session:
async with session.get(card_url) as response:
if response.status == 200:
self.agent_card = await response.json()
self.agent_name = self.agent_card.get("name")
self.base_url = self.agent_card.get("url")
return self.agent_card
else:
raise Exception(f"Failed to fetch agent card: {response.status}")
async def tasks_send(self, params: Dict) -> Dict:
"""发送任务请求"""
if not self.base_url:
raise ValueError("Base URL not set. Call fetch_agent_card first.")
request_id = str(uuid.uuid4())
payload = {
"jsonrpc": "2.0",
"id": request_id,
"method": "tasks/send",
"params": params
}
async with aiohttp.ClientSession() as session:
async with session.post(self.base_url, json=payload) as response:
if response.status == 200:
result = await response.json()
return result.get("result", {})
else:
error_text = await response.text()
raise Exception(f"Error sending task: {response.status}, {error_text}")
async def tasks_sendSubscribe(self, params: Dict) -> aiohttp.ClientResponse:
"""发送流式任务请求"""
if not self.base_url:
raise ValueError("Base URL not set. Call fetch_agent_card first.")
# 检查代理是否支持流式处理
if not self.agent_card.get("capabilities", {}).get("streaming", False):
raise Exception("Agent does not support streaming")
request_id = str(uuid.uuid4())
payload = {
"jsonrpc": "2.0",
"id": request_id,
"method": "tasks/sendSubscribe",
"params": params
}
session = aiohttp.ClientSession()
response = await session.post(
self.base_url,
json=payload,
headers={"Accept": "text/event-stream"}
)
if response.status != 200:
error_text = await response.text()
await session.close()
raise Exception(f"Error in streaming request: {response.status}, {error_text}")
return response, session
4.3 构建Web界面
为了让多代理系统更易于交互,我们使用Flask构建一个简单的Web界面:
# app.py
from flask import Flask, render_template, request, jsonify
import asyncio
from host_agent import HostAgent
app = Flask(__name__)
host_agent = HostAgent()
# 使用一个字典存储当前活跃的对话
active_conversations = {}
@app.route('/')
def index():
"""渲染主页"""
return render_template('index.html')
@app.route('/api/register_agent', methods=['POST'])
def register_agent():
"""注册新代理API"""
data = request.json
agent_url = data.get('agent_url')
if not agent_url:
return jsonify({"error": "Missing agent_url parameter"}), 400
result = asyncio.run(host_agent.register_agent(agent_url))
return jsonify(result)
@app.route('/api/chat', methods=['POST'])
def chat():
"""处理用户聊天请求"""
data = request.json
user_query = data.get('query')
conversation_id = data.get('conversation_id')
if not user_query:
return jsonify({"error": "Missing query parameter"}), 400
# 处理请求并返回结果
result = asyncio.run(host_agent.process_request(user_query, conversation_id))
return jsonify(result)
@app.route('/api/conversations', methods=['GET'])
def get_conversations():
"""获取所有对话历史"""
return jsonify({
"conversations": host_agent.conversations
})
if __name__ == '__main__':
app.run(debug=True, port=5000)
前端模板(简化版):
<!-- notes/模块四_Python高级并发与异步编程/9.6/csdn/codes/templates/index.html -->
<!DOCTYPE html>
<html>
<head>
<title>A2A多代理通信系统</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
<style>
.chat-container {
height: 70vh;
overflow-y: auto;
border: 1px solid #ddd;
border-radius: 5px;
padding: 15px;
margin-bottom: 15px;
}
.user-message {
background-color: #f0f7ff;
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
max-width: 80%;
margin-left: auto;
}
.agent-message {
background-color: #f0f0f0;
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
max-width: 80%;
}
</style>
</head>
<body>
<div class="container mt-5">
<h1>A2A多代理通信系统</h1>
<div class="row mt-4">
<div class="col-md-8">
<div id="chat-container" class="chat-container"></div>
<div class="input-group">
<input type="text" id="user-input" class="form-control" placeholder="输入您的问题...">
<button class="btn btn-primary" id="send-btn">发送</button>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
注册代理
</div>
<div class="card-body">
<div class="input-group mb-3">
<input type="text" id="agent-url" class="form-control" placeholder="代理URL">
<button class="btn btn-success" id="register-btn">注册</button>
</div>
</div>
</div>
<div class="card mt-3">
<div class="card-header">
已注册代理
</div>
<div class="card-body">
<ul id="agent-list" class="list-group">
<!-- 代理列表将在这里动态显示 -->
</ul>
</div>
</div>
</div>
</div>
</div>
<script>
// 这里是前端JavaScript代码
// 实际项目中应使用更完善的前端框架
let currentConversationId = null;
document.getElementById('send-btn').addEventListener('click', async () => {
const userInput = document.getElementById('user-input');
const query = userInput.value.trim();
if (!query) return;
// 在界面上显示用户消息
addMessage('user', query);
userInput.value = '';
// 发送请求到后端
try {
const response = await fetch('/api/chat', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
query: query,
conversation_id: currentConversationId
})
});
const result = await response.json();
currentConversationId = result.conversation_id;
// 显示代理响应
addMessage('agent', result.response);
} catch (error) {
console.error('Error:', error);
addMessage('agent', '处理请求时出错');
}
});
document.getElementById('register-btn').addEventListener('click', async () => {
const agentUrl = document.getElementById('agent-url').value.trim();
if (!agentUrl) return;
try {
const response = await fetch('/api/register_agent', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({agent_url: agentUrl})
});
const result = await response.json();
if (result.status === 'success') {
// 添加代理到列表
const agentList = document.getElementById('agent-list');
const li = document.createElement('li');
li.className = 'list-group-item';
li.textContent = result.agent_id;
agentList.appendChild(li);
// 清空输入
document.getElementById('agent-url').value = '';
} else {
alert('注册代理失败: ' + result.error);
}
} catch (error) {
console.error('Error:', error);
alert('注册代理时出错');
}
});
function addMessage(role, content) {
const chatContainer = document.getElementById('chat-container');
const messageDiv = document.createElement('div');
messageDiv.className = role === 'user' ? 'user-message' : 'agent-message';
messageDiv.textContent = content;
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
</script>
</body>
</html>
Demo的实际界面有些简陋,别挑~ 问就是不会前端…
稍微修改了一下,反正就这样吧~:
4.4 运行与测试
启动系统:
cd A2A多代理通信系统
pip install -r requirements.txt
python app.py # 实际代码中启动入口脚本有修改, python start_all.py 一键启动并注册Agent代理
访问http://localhost:5001
即可使用系统。
五、A2A协议实战应用场景
接下来介绍几个A2A协议的实际应用场景,这些场景已经在实际项目中得到验证:
5.1 智能客服矩阵
传统客服机器人不够智能的主要问题是单一Agent能力有限。采用多Agent协作架构的智能客服系统包括:
- 一线咨询Agent:负责"接待",明确用户的真实需求
- 产品专家Agent:了解每款产品的细节参数和使用体验
- 技术支持Agent:负责处理故障排查这类技术性问题
- 销售Agent:处理价格、折扣、库存等商业咨询
这几类Agent通过A2A协议无缝衔接,互相配合处理问题。用户完全感知不到背后是多个AI在协同工作。
5.2 多模态内容创作平台
现代内容创作不仅仅是生成文字,还需要图像、视频等多模态内容。基于A2A的多模态内容创作系统包括:
- 文本创作Agent:负责生成文章、脚本、产品描述等文字内容
- 图像生成Agent:根据文字描述生成配图
- 视频合成Agent:将文字内容和图片合成简单视频
- 编辑优化Agent:对整体内容进行审核和优化
营销团队使用这套系统做产品介绍,可以一键从文字到视频全流程生成。最大的优势是各模态内容的风格一致性极高,像是出自同一个创作者之手。
5.3 企业知识引擎
单Agent很难应对企业内复杂的知识获取需求。基于A2A的企业知识引擎架构包括:
- 文档分析Agent:负责处理Word、PDF、PPT等文档
- 数据查询Agent:连接企业数据库和BI系统
- Web采集Agent:从内外网获取最新资讯
- 综合推理Agent:整合各种信息形成完整答案
这种系统可以突破传统单Agent的上下文窗口限制,同时保持较高的准确性。
六、A2A协议的性能优化与最佳实践
通过多个A2A项目的实践,总结并预测了以下实用的优化技巧:
6.1 任务粒度与分发策略
任务粒度和分发策略直接影响系统效率:
- 合理拆分任务:任务粒度过细会增加通信开销,过粗则降低并行度,需要找到平衡点
- 负载感知路由:根据每个代理的实时负载情况动态调整任务分发,避免瓶颈
- 亲和性调度:相关任务优先分配给曾处理过相似问题的代理,可提高准确率
6.2 多模态内容处理优化
处理图片、视频等大型内容时的经验:
- 内联vs引用传递:大文件应避免使用Base64编码直接内联,改用URI引用方式传递,效率更高
- 渐进式传输:对于长时间运行的任务,采用流式传输方式让用户尽快看到部分结果
- 内容协商:客户端应明确告知服务器支持的内容类型,服务器据此优化响应格式
6.3 安全与认证最佳实践
多代理系统的攻击面更大,安全防护措施必不可少:
- JWT认证:使用带时效的JWT令牌验证代理身份,防止冒充
- 细粒度权限:不同代理能访问的资源和API应有明确界限
- 内容验证:代理间传递的内容必须经过安全检查,防止注入攻击
安全配置示例:
# 安全配置示例代码
from jose import jwt
import datetime
# 创建JWT令牌
def create_agent_token(agent_id, secret_key, expiry_minutes=60):
payload = {
"sub": agent_id,
"iat": datetime.datetime.utcnow(),
"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=expiry_minutes)
}
return jwt.encode(payload, secret_key, algorithm="HS256")
# 验证JWT令牌
def verify_agent_token(token, secret_key):
try:
payload = jwt.decode(token, secret_key, algorithms=["HS256"])
return payload["sub"] # 返回代理ID
except jwt.JWTError:
return None # 令牌无效
在实际项目中,合适的认证机制对于保证系统安全性至关重要。安全方面的投入通常能够避免更大的风险和损失。
七、未来展望与技术趋势
A2A协议的未来发展方向还是挺清晰的:
7.1 Agent自组织能力
下一代A2A协议很可能会支持Agent的自主组织能力,类似于细胞自动机。具体来说,就是根据任务需要自动组建最佳团队,无需人工干预。
Google内部已经在探索"Agent即服务"的概念,未来部署AI解决方案可能会变得极为简便 —— 需要什么能力就调用对应的Agent,它们会自行协商如何合作完成任务。
7.2 多源LLM协作框架
这是一个市场驱动的需求。市面上各家大模型各有所长,OpenAI擅长代码,Anthropic擅长长文本理解,Google擅长知识问答…如果能在同一个系统里混用这些模型,充分发挥各自优势,效果将会有质的飞跃。
A2A协议在这方面有天然优势,它本来就设计用来连接异构系统。目前已有项目尝试让基于不同大模型的Agent协同工作,初步效果显示出巨大潜力。
7.3 人机混合团队支持
当前最有前景的发展方向是支持人机混合团队。多个创新项目正在探索如何让人类专家无缝参与到Agent协作流程中,形成"人类+AI"的混合智能团队。
这个方向具有重要的实用价值。纯AI系统再强大,也有判断失误的时候;而人类专家时间有限,无法面面俱到。结合双方优势,是最具可行性的方案。A2A协议未来很可能在人机协作领域取得重大突破。
八、总结
A2A协议从目前来看解决了企业级AI应用的互操作性难题,让不同代理系统能够无障碍沟通,还有很大的延伸挖掘的可能性。
实战案例中展示了如何用Python搭建基于A2A的多代理协作系统,以及如何将这项技术应用到实际项目中。
几点个人建议,想吐槽赶快来评论区 :
-
保留现有AI投资:A2A最大的价值在于能整合现有系统,不必从零开始。。
-
技术框架混搭:不同场景适合不同框架,CrewAI适合多智能体交互,LangGraph适合复杂推理,ADK适合表单处理,通过A2A协议可以将它们组合使用。
-
循序渐进:建议从小规模试点开始,逐步扩展,降低风险。成功的项目通常从单一业务场景起步,验证可行后再横向扩展到其他部门。
-
紧跟技术趋势:AI技术正在向协作、分布式、混合模式发展,A2A协议正好顺应这个大趋势。
随着企业AI应用从概念验证走向规模化部署,A2A协议在2025年很可能成为构建企业级多代理系统的核心技术标准。及早掌握这项技术,无论是个人还是企业,都能在未来竞争中占得先机。
参考资料
- Google A2A:https://github.com/google/A2A
- A2A示例代码库:https://github.com/google/A2A