一、开篇导语
我们对A2A已经有了初步的了解,但对具体使用可能还充满了很多疑问,今天我们结合具体的实例来加深对A2A实际应用的理解,想象这样一个场景:我们要组织一场户外篮球赛,需要同时考虑天气状况、场地预约、参与人员时间安排等多个因素。在传统模式下,这需要我们分别查看天气预报、联系场地管理员、逐个确认参与者时间——一个典型的多系统、多步骤的繁琐过程。
而现在,通过A2A智能代理协议,这一切变得相当简单,只需要一个简单的请求,就告诉我们是否可以如期举行,这背后发生的,是一场智能代理的协同交响曲:天气代理提供精准预报,场地代理检查可用性,日历代理协调参与者时间,最后通知代理发送确认信息。每个代理各司其职,又完美配合,共同完成一个复杂决策。
二、A2A的简单回顾
1. 什么是A2A协议
- 定义阐述:Agent-to-Agent协议的标准化通信框架
- 核心特征:松耦合、可发现、自描述、可组合的智能体交互模式
- 核心组件:
- 服务发现机制:通过标准端点实现代理能力的自动识别
- 任务描述语言:统一的JSON Schema定义输入输出规范
- 状态管理:完整的任务生命周期跟踪和管理
- 安全认证:基于令牌的身份验证和授权机制
2. A2A与传统API的对比优势
- 动态性对比:
- 传统API:静态接口,需要预先知道端点地址和参数
- A2A协议:动态发现,代理可运行时识别彼此能力
- 语义化程度:
- 传统API:通常缺乏机器可读的语义描述
- A2A协议:完整的JSON Schema提供丰富的语义信息
- 自治能力:
- 传统API:被动响应,无自主决策能力
- A2A协议:代理具有自主性和智能决策能力
3. 协议的核心技术特性
- 标准化服务发现
- 通过/.well-known/agent.json端点暴露代理能力
- 自动化的代理注册和发现机制,动态的能力协商和版本管理
- 统一的任务模型
- 标准化的任务提交格式,统一的结果返回结构,完整的错误处理规范
- 安全通信机制
- 基于令牌的身份验证,端到端的加密通信,细粒度的权限控制
4. A2A协议的生态系统价值
- 互操作性:不同厂商、不同技术的代理无缝协作
- 可扩展性:新代理服务的即插即用式集成
- 维护性:独立部署、升级不影响整体系统运行
三、单智能体决策系统
这是一个基于天气条件自动决定篮球会议是否举行的智能代理系统,遵循A2A通信协议,首先要声明一个提供指定日期天气数据查询的 RESTful API 服务,并且要遵循智能代理(Agent)的标准规范。
1. 天气服务的Agent
1.1 Agent Card 声明
WEATHER_AGENT_CARD = {
"name": "WeatherAgent",
"version": "1.0",
"description": "提供指定日期的天气数据查询",
"endpoints": {
"task_submit": "/api/tasks/weather",
"sse_subscribe": "/api/tasks/updates"
},
"input_schema": {
"type": "object",
"properties": {
"date": {"type": "string", "format": "date"},
"location": {"type": "string", "enum": ["北京"]}
},
"required": ["date"]
},
"authentication": {"methods": ["API_Key"]}
}
- 作用:定义代理的元数据,遵循 .well-known/agent.json 标准
- name/version/description: 代理的基本信息
- endpoints: 定义任务提交和更新订阅的API端点
- input_schema: 定义输入参数的JSON Schema
- authentication: 声明认证方式
1.2 数据模型
class WeatherTaskRequest(BaseModel):
task_id: str
params: dict
- 作用:定义任务请求的数据结构
- task_id: 任务唯一标识符
- params: 包含查询参数(日期、位置)
1.3 模拟数据存储
weather_db = {
"2025-05-08": {"temperature": "25℃", "condition": "雷阵雨"},
"2025-05-09": {"temperature": "18℃", "condition": "小雨转晴"},
"2025-05-10": {"temperature": "22℃", "condition": "多云转晴"}
}
- 作用:模拟数据库,存储预设日期的天气数据
1.4 Agent Card 发现端点
@app.get("/.well-known/agent.json")
async def get_agent_card():
return WEATHER_AGENT_CARD
- 功能:提供代理的标准发现接口,让其他系统能够自动发现和了解这个代理的能力
1.5 天气查询任务处理端点
@app.post("/api/tasks/weather")
async def handle_weather_task(request: WeatherTaskRequest):
target_date = request.params.get("date")
if not target_date or target_date not in weather_db:
raise HTTPException(status_code=400, detail="无效日期参数")
return {
"task_id": request.task_id,
"status": "completed",
"artifact": {
"date": target_date,
"weather": weather_db[target_date]
}
}
- 接收天气查询任务
- 验证日期参数
- 返回对应日期的天气信息
- 返回标准化的任务响应格式
1.5 服务提供的完整功能
1.5.1 代理发现
- 通过标准路径 /.well-known/agent.json 提供代理能力描述
1.5.2 天气查询
- 输入:指定日期(必需)和位置(可选,目前只支持北京)
- 输出:温度信息和天气状况
- 示例查询日期:2025-05-08、2025-05-09、2025-05-10
1.5.3 标准化响应
返回统一格式的任务响应:
{
"task_id": "任务ID",
"status": "completed",
"artifact": {
"date": "查询日期",
"weather": {"temperature": "温度", "condition": "天气状况"}
}
}
1.5.4 错误处理
- 参数验证:检查日期是否存在且有效
- 错误响应:返回标准HTTP错误码和描述
1.6. 使用示例
1.6.1 发现代理能力
GET http://localhost:8000/.well-known/agent.json
1.6.2 查询天气
POST http://localhost:8000/api/tasks/weather
Content-Type: application/json
{
"task_id": "task_123",
"params": {
"date": "2025-05-08"
}
}
1.6.3 相应结果
{
"task_id": "task_123",
"status": "completed",
"artifact": {
"date": "2025-05-08",
"weather": {
"temperature": "25℃",
"condition": "雷阵雨"
}
}
}
1.6.4 服务启动示例
这个服务可以作为更大的AI系统或工作流中的一个组件,专门负责天气信息查询功能。
WeatherAgent完整参考:
from fastapi import FastAPI, HTTPException
from datetime import date
from pydantic import BaseModel
import uvicorn
app = FastAPI()
# Agent Card声明(通过/.well-known/agent.json暴露)
WEATHER_AGENT_CARD = {
"name": "WeatherAgent",
"version": "1.0",
"description": "提供指定日期的天气数据查询",
"endpoints": {
"task_submit": "/api/tasks/weather",
"sse_subscribe": "/api/tasks/updates"
},
"input_schema": {
"type": "object",
"properties": {
"date": {"type": "string", "format": "date"},
"location": {"type": "string", "enum": ["北京"]}
},
"required": ["date"]
},
"authentication": {"methods": ["API_Key"]}
}
# 任务请求模型
class WeatherTaskRequest(BaseModel):
task_id: str
params: dict
# 模拟天气数据存储
weather_db = {
"2025-05-08": {"temperature": "25℃", "condition": "雷阵雨"},
"2025-05-09": {"temperature": "18℃", "condition": "小雨转晴"},
"2025-05-10": {"temperature": "22℃", "condition": "多云转晴"}
}
@app.get("/.well-known/agent.json")
async def get_agent_card():
return WEATHER_AGENT_CARD
@app.post("/api/tasks/weather")
async def handle_weather_task(request: WeatherTaskRequest):
"""处理天气查询任务"""
target_date = request.params.get("date")
# 参数验证
if not target_date or target_date not in weather_db:
raise HTTPException(status_code=400, detail="无效日期参数")
return {
"task_id": request.task_id,
"status": "completed",
"artifact": {
"date": target_date,
"weather": weather_db[target_date]
}
}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
2. 篮球会议安排代理
2.1 类初始化
class BasketBallAgent:
def __init__(self):
self.weather_agent_url = "http://localhost:8000"
self.api_key = "SECRET_KEY" # 实际应通过安全方式存储
- 设置天气代理服务的URL
- 配置API密钥(实际应用中应从安全存储获取)
2.2 任务创建方法
def _create_task(self, target_date: str) -> dict:
"""创建A2A标准任务对象"""
return {
"task_id": str(uuid.uuid4()),
"params": {
"date": target_date,
"location": "北京"
}
}
- 生成符合A2A协议标准的任务对象
- 使用UUID确保任务ID的唯一性
- 封装查询参数(日期和位置)
2.3 天气查询核心方法
def check_weather(self, target_date: str) -> dict:
"""通过A2A协议查询天气"""
# 获取天气智能体能力描述
agent_card = requests.get(
f"{self.weather_agent_url}/.well-known/agent.json"
).json()
# 构造任务请求
task = self._create_task(target_date)
# 发送任务请求
response = requests.post(
f"{self.weather_agent_url}{agent_card['endpoints']['task_submit']}",
json=task,
headers={"Authorization": f"Bearer {self.api_key}"}
)
if response.status_code == 200:
return response.json()["artifact"]
else:
raise Exception(f"天气查询失败: {response.text}")
- 作用:完整的A2A协议交互流程
- 服务发现:首先获取天气代理的能力描述
- 任务构造:创建标准格式的任务请求
- API调用:向任务提交端点发送请求
- 结果处理:提取并返回天气数据
2.4 决策逻辑方法
def schedule_meeting(self, date: str):
"""综合决策逻辑"""
try:
result = self.check_weather(date)
if "雨" not in result["weather"]["condition"] and "雪" not in result["weather"]["condition"]:
return {"status": "confirmed", "weather": result["weather"]}
else:
return {"status": "cancelled", "reason": "恶劣天气"}
except Exception as e:
return {"status": "error", "detail": str(e)}
- 作用:基于天气条件做出智能决策
- 确认举行:天气状况不含"雨"或"雪"
- 取消会议:出现恶劣天气条件
- 错误处理:处理查询失败的情况
2.5 系统协议流程
2.5.1 A2A协议实现
BasketBallAgent (客户端) → WeatherAgent (服务端)
↓ ↓
决策代理 能力代理
- 服务发现:动态获取代理能力
- 标准通信:统一的任务格式和响应格式
- 松耦合:代理间独立部署和升级
2.5.2 智能决策流程
输入日期 → 查询天气 → 分析条件 → 输出决策
↓ ↓ ↓ ↓
"2025-05-08" → 雷阵雨 → 包含"雨" → 取消会议
"2025-05-10" → 多云转晴 → 无恶劣天气 → 确认举行
2.6 使用示例
2.6.1 测试案例1:雨天取消
result = meeting_agent.schedule_meeting("2025-05-08")
# 输出: 篮球安排结果: {'status': 'cancelled', 'reason': '恶劣天气'}
2.6.2 测试案例2:晴天确认
result = meeting_agent.schedule_meeting("2025-05-10")
# 输出: 篮球安排结果: {'status': 'confirmed', 'weather': {'temperature': '22℃', 'condition': '多云转晴'}}
2.6.3 运行结果示例
BasketBallAgent 参考:
import requests
import uuid
class BasketBallAgent:
def __init__(self):
self.weather_agent_url = "http://localhost:8000"
self.api_key = "SECRET_KEY" # 实际应通过安全方式存储
def _create_task(self, target_date: str) -> dict:
"""创建A2A标准任务对象"""
return {
"task_id": str(uuid.uuid4()),
"params": {
"date": target_date,
"location": "北京"
}
}
def check_weather(self, target_date: str) -> dict:
"""通过A2A协议查询天气"""
# 获取天气智能体能力描述
agent_card = requests.get(
f"{self.weather_agent_url}/.well-known/agent.json"
).json()
# 构造任务请求
task = self._create_task(target_date)
# 发送任务请求
response = requests.post(
f"{self.weather_agent_url}{agent_card['endpoints']['task_submit']}",
json=task,
headers={"Authorization": f"Bearer {self.api_key}"}
)
if response.status_code == 200:
return response.json()["artifact"]
else:
raise Exception(f"天气查询失败: {response.text}")
def schedule_meeting(self, date: str):
"""综合决策逻辑"""
try:
result = self.check_weather(date)
# print('result=', result)
if "雨" not in result["weather"]["condition"] and "雪" not in result["weather"]["condition"]:
return {"status": "confirmed", "weather": result["weather"]}
else:
return {"status": "cancelled", "reason": "恶劣天气"}
except Exception as e:
return {"status": "error", "detail": str(e)}
# 使用示例
if __name__ == "__main__":
meeting_agent = BasketBallAgent()
result = meeting_agent.schedule_meeting("2025-05-08")
# result = meeting_agent.schedule_meeting("2025-05-10")
print("篮球安排结果:", result)
四、多代理协作系统
基于以上示例扩展为多代理协作系统,新增了场地代理、日历代理以及通知代理
1. 系统特点
1.1 多代理协作架构
BasketBallAgent (协调者)
├── WeatherAgent (天气查询)
├── VenueAgent (场地管理)
├── CalendarAgent (日程检查)
└── NotificationAgent (通知发送)
1.2 新增代理功能
- **场地代理 (VenueAgent):**检查室内/室外场地可用性、处理场地维护状态、支持不同运动类型
- **日历代理 (CalendarAgent):**检查参与者时间冲突、计算可用率、提供详细可用性信息
- **通知代理 (NotificationAgent):**发送会议确认/取消通知、支持多种通知类型、跟踪通知状态
1.3 智能决策逻辑
- 决策流程:
- 天气检查 → 恶劣天气则取消
- 场地检查 → 场地不可用则取消
- 参与者检查 → 可用率<60%则取消
- 发送通知 → 确认后自动通知
1.4 升级的架构设计
- 四层架构模型:
- 客户端层:用户交互界面
- 协调层:BasketBallAgent决策引擎
- 能力层:天气、场地、日历等专业代理
- 数据层:各代理的专有数据存储
1.5 代理职责边界划分
- WeatherAgent:专注天气数据查询与预报
- VenueAgent:管理场地资源与可用性状态
- CalendarAgent:处理参与者时间冲突检测
- NotificationAgent:负责多通道消息推送
- BasketBallAgent:协调决策与业务流程编排
1.6 数据流与状态管理
- 请求流程:客户端→协调器→能力代理的链式调用
- 响应聚合:多源数据在协调层的智能融合
- 状态追踪:基于task_id的全链路任务状态管理
- 错误处理:分级故障隔离与优雅降级策略
1.7 决策机制
1.7.1 分布式决策流程设计
- 并行检查机制:天气、场地、日程的并发验证
- 决策树逻辑:基于优先级的条件判断序列
- 阈值配置:可调节的通过标准(如60%参与者可用率)
- 上下文传递:决策过程中状态信息的完整传递
1.7.2 智能推荐引擎
- 多因素综合分析:天气状况、场地类型、参与度权重计算
- 个性化建议生成:基于历史数据和用户偏好的智能推荐
- 备选方案提供:自动建议替代时间或场地选项
- 风险评估:基于概率的会议成功可能性预测
1.7.3 冲突解决策略
- 优先级仲裁:关键条件(安全因素)的否决权设置
- 权重平衡:不同代理反馈结果的权重分配算法
- 协商机制:代理间的条件协商与妥协方案生成
- 人工干预:复杂情况的转人工决策流程
2. 执行流程图
3. 流程详细说明
3.1 阶段一:客户端请求接收与初始化
3.1.1 请求接收过程
客户端向高级篮球代理系统提交会议安排请求,请求中包含会议日期、参与者列表、场地类型等关键信息。系统接收到请求后,首先创建决策上下文对象,用于在整个处理流程中跟踪和记录所有检查结果、决策状态和原因说明。
3.1.2 上下文初始化
系统初始化一个结构化的决策上下文,该上下文将作为整个决策过程的数据载体。它包含原始请求信息、各个代理的检查结果集合、最终决策状态以及决策原因列表。初始状态下,决策状态设置为待处理,等待后续检查结果的填充。
3.2 阶段二:多代理并行检查执行
3.2.1 并行调用策略
系统采用并行执行策略,同时向三个专业代理服务发起检查请求。这种并行处理方式显著减少了总体响应时间,提高了系统效率。每个代理服务都运行在独立的端口上,具有专门的功能领域。
3.2.2 天气代理检查流程
3.2.2.1 服务发现与连接
系统首先通过标准化的服务发现机制定位天气代理服务。通过访问预定义的服务描述端点,获取天气代理的能力描述和接口规范,确保调用的准确性和兼容性。
3.2.2.2 天气数据查询
向天气代理提交包含目标日期和位置的查询请求。天气代理接收到请求后,在其内部天气数据库中检索指定日期的详细天气信息,包括温度、天气状况、湿度、风速、降水概率等多个维度的数据。
3.2.2.3 天气适宜性分析
天气代理不仅返回原始天气数据,还进行专业的适宜性分析。通过分析温度范围、降水情况、风速等因素,计算得出篮球活动的天气适宜性评分,识别潜在的风险因素,并生成具体的活动建议。
3.2.3 场地代理检查流程
3.2.3.1 场地状态验证
系统向场地代理查询指定日期和场地类型的可用性状态。场地代理检查其管理的场地数据库,验证目标场地在请求时间段内是否可用,是否存在预定冲突或维护安排。
3.2.3.2 场地详情获取
除了基本的可用性状态,场地代理还提供场地的详细信息,包括场地名称、容纳人数、设施配置、收费标准等。这些信息有助于了解场地的具体条件。
3.2.3.3 冲突检测处理
如果检测到场地冲突,场地代理会明确说明冲突类型(已被占用、维护中、已被预订等),为后续决策提供充分的依据。
3.2.4 日历代理检查流程
3.2.4.1 参与者时间冲突检测
日历代理接收参与者列表和目标日期,逐个检查每位参与者的个人日历安排。通过比对请求时间段与参与者已有日程,识别是否存在时间冲突。
3.2.4.5 可用性统计分析
日历代理统计可用参与者的数量,计算总体可用率,并分析关键参与者的可用情况。这些统计信息为会议安排决策提供重要参考。
3.2.4.6 冲突详情报告
对于存在时间冲突的参与者,日历代理提供详细的冲突事件信息,包括冲突事件的标题、时间范围和优先级,帮助理解冲突的性质和严重程度。
3.3 阶段三:检查结果聚合与智能决策
3.3.1 结果收集与整合
系统等待所有并行检查完成,收集各个代理返回的检查结果。将这些结果统一整合到决策上下文中,形成完整的检查结果数据集。
3.3.2 分级决策逻辑执行
系统按照预设的优先级顺序执行决策逻辑:
3.3.2.1 第一级:安全条件检查
首先评估天气条件的安全性。系统检查天气状况中是否包含雨、雪、雷暴、大风等不利于户外篮球活动的因素。如果检测到恶劣天气条件,立即做出取消决策,并记录具体的天气原因。
3.3.2.2 第二级:资源条件检查
如果天气条件通过,接着检查场地可用性。验证请求的场地在目标时间段内是否处于可用状态。如果场地不可用,做出取消决策,并说明具体的场地状态原因。
3.3.2.3 第三级:人员条件检查
如果前两级检查都通过,最后评估参与者可用性。检查可用参与者比例是否达到预设阈值(如60%)。如果参与率不足,做出取消决策,并报告具体的参与率数据。
3.3.3 最终确认决策
只有当所有三级检查都满足条件时,系统才做出会议确认的最终决策。
3.4 阶段四:通知处理与确认
3.4.1 条件性通知触发
仅当会议获得确认时,系统才会触发通知流程。这种条件性执行避免了不必要的通知发送,提高了系统效率。
3.4.2 通知代理调用
系统向通知代理发送会议确认通知请求,包含所有收件人列表、通知类型以及完整的会议决策数据。通知代理根据通知类型选择相应的模板,填充具体的会议信息。
3.4.3 多通道通知发送
通知代理通过配置的通信通道(如邮件、短信等)向所有参与者发送格式化的会议确认通知。通知内容包含会议详情、天气信息、场地信息和参与建议等。
3.4.4 通知结果记录
通知代理记录每次通知发送的详细结果,包括发送时间、接收者列表、发送状态等信息,这些信息被返回并记录在决策上下文中。
3.5 阶段五:最终响应生成与返回
3.5.1 结果格式化处理
系统将决策上下文中的所有信息整合生成标准化的响应格式。响应中包含系统生成的唯一会议标识符、最终决策状态、决策时间戳、决策原因说明、详细的检查结果汇总以及针对性的活动建议。
3.5.2 智能建议生成
根据最终的决策状态和具体的检查结果,系统生成个性化的建议信息。对于确认的会议,提供天气适应的活动建议;对于取消的会议,根据取消原因提供改期或调整的替代方案。
3.5.3 完整响应返回
将格式化后的最终响应返回给客户端,完成整个会议安排决策流程。客户端获得包含所有决策依据和详细信息的完整响应,便于用户理解系统决策并采取相应行动。
4. 启动说明
要运行完整的系统,需要在不同的终端中分别启动这四个服务:
# 终端1 - WeatherAgent
python WeatherAgent.py
# 终端2 - VenueAgent
python VenueAgent.py
# 终端3 - NotificationAgent
python NotificationAgent.py
# 终端4 - CalendarAgent
python CalendarAgent.py
# 终端5 - 运行测试客户端
python MultiAgent2.py
每个Agent都提供了完整的REST API接口,支持服务发现、任务处理和健康检查,共同构成了一个完整的分布式智能代理系统。
5. 示例参考
WeatherAgent示例:
from fastapi import FastAPI, HTTPException
from datetime import date
from pydantic import BaseModel
import uvicorn
from enum import Enum
from typing import Dict, Optional
app = FastAPI(title="WeatherAgent", version="1.0.0")
class WeatherCondition(str, Enum):
SUNNY = "晴"
CLOUDY = "多云"
RAIN = "雨"
SNOW = "雪"
THUNDERSTORM = "雷阵雨"
LIGHT_RAIN = "小雨"
CLEAR = "晴转多云"
class WeatherTaskRequest(BaseModel):
task_id: str
agent_type: str
timestamp: str
params: dict
# 详细的天气数据库
weather_db = {
"2025-05-08": {
"temperature": "25℃",
"condition": WeatherCondition.THUNDERSTORM,
"humidity": "85%",
"wind_speed": "15km/h",
"precipitation_probability": "90%",
"uv_index": "2",
"air_quality": "良"
},
"2025-05-09": {
"temperature": "18℃",
"condition": WeatherCondition.LIGHT_RAIN,
"humidity": "78%",
"wind_speed": "12km/h",
"precipitation_probability": "60%",
"uv_index": "1",
"air_quality": "优"
},
"2025-05-10": {
"temperature": "22℃",
"condition": WeatherCondition.CLEAR,
"humidity": "65%",
"wind_speed": "8km/h",
"precipitation_probability": "10%",
"uv_index": "5",
"air_quality": "优"
},
"2025-05-11": {
"temperature": "28℃",
"condition": WeatherCondition.SUNNY,
"humidity": "55%",
"wind_speed": "6km/h",
"precipitation_probability": "5%",
"uv_index": "8",
"air_quality": "良"
}
}
# 智能天气分析
class WeatherAnalyzer:
@staticmethod
def analyze_weather_suitability(weather_data: dict, activity_type: str = "basketball") -> dict:
"""分析天气对活动的适宜性"""
score = 100
# 温度适宜性 (15-30度最佳)
temp = int(weather_data["temperature"].replace("℃", ""))
if 15 <= temp <= 30:
temp_score = 100
elif 10 <= temp < 15 or 30 < temp <= 35:
temp_score = 70
else:
temp_score = 30
score = score * 0.3 + temp_score * 0.7
# 降水影响
if "雨" in weather_data["condition"] or "雪" in weather_data["condition"]:
score *= 0.3
elif weather_data["precipitation_probability"] > "50%":
score *= 0.7
# 风速影响
wind_speed = int(weather_data["wind_speed"].replace("km/h", ""))
if wind_speed > 20:
score *= 0.5
elif wind_speed > 15:
score *= 0.8
return {
"suitability_score": round(score),
"recommendation": "适宜进行" if score >= 70 else "不适宜进行",
"risk_factors": WeatherAnalyzer._identify_risk_factors(weather_data)
}
@staticmethod
def _identify_risk_factors(weather_data: dict) -> list:
"""识别天气风险因素"""
risks = []
if "雨" in weather_data["condition"]:
risks.append("地面湿滑")
if "雷" in weather_data["condition"]:
risks.append("雷电危险")
if int(weather_data["temperature"].replace("℃", "")) > 30:
risks.append("高温中暑风险")
if int(weather_data["wind_speed"].replace("km/h", "")) > 15:
risks.append("大风影响")
return risks
WEATHER_AGENT_CARD = {
"name": "WeatherAgent",
"version": "2.0.0",
"description": "提供详细的天气数据查询和分析服务",
"endpoints": {
"task_submit": "/api/tasks/weather",
"health_check": "/health"
},
"input_schema": {
"type": "object",
"properties": {
"date": {"type": "string", "format": "date", "description": "查询日期"},
"location": {"type": "string", "description": "地理位置"},
"detailed": {"type": "boolean", "description": "是否返回详细分析"}
},
"required": ["date"]
},
"capabilities": {
"weather_forecast": True,
"suitability_analysis": True,
"risk_assessment": True
},
"authentication": {"methods": ["API_Key"]}
}
@app.get("/.well-known/agent.json")
async def get_agent_card():
return WEATHER_AGENT_CARD
@app.get("/health")
async def health_check():
return {"status": "healthy", "service": "WeatherAgent"}
@app.post("/api/tasks/weather")
async def handle_weather_task(request: WeatherTaskRequest):
"""处理天气查询任务"""
target_date = request.params.get("date")
location = request.params.get("location", "北京")
detailed = request.params.get("detailed", False)
# 参数验证
if not target_date:
raise HTTPException(status_code=400, detail="缺少日期参数")
if target_date not in weather_db:
# 模拟未来日期的天气预测
simulated_weather = {
"temperature": "23℃",
"condition": WeatherCondition.CLOUDY,
"humidity": "70%",
"wind_speed": "10km/h",
"precipitation_probability": "30%",
"uv_index": "4",
"air_quality": "良"
}
weather_data = simulated_weather
else:
weather_data = weather_db[target_date]
# 构建响应
response = {
"task_id": request.task_id,
"status": "completed",
"artifact": {
"date": target_date,
"location": location,
"weather": weather_data
}
}
# 如果请求详细分析,添加适宜性分析
if detailed:
analysis = WeatherAnalyzer.analyze_weather_suitability(weather_data)
response["artifact"]["analysis"] = analysis
return response
@app.get("/api/weather/history")
async def get_weather_history(days: int = 7):
"""获取历史天气数据(模拟)"""
return {
"historical_data": weather_db,
"summary": {
"total_days": len(weather_db),
"rainy_days": len([w for w in weather_db.values() if "雨" in w["condition"]])
}
}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, log_level="info")
2. VenueAgent示例:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import uvicorn
from datetime import datetime, timedelta
from enum import Enum
from typing import Dict, List
import uuid
app = FastAPI(title="VenueAgent", version="1.0.0")
class VenueStatus(str, Enum):
AVAILABLE = "available"
OCCUPIED = "occupied"
MAINTENANCE = "maintenance"
RESERVED = "reserved"
class SportType(str, Enum):
BASKETBALL = "basketball"
FOOTBALL = "football"
TENNIS = "tennis"
SWIMMING = "swimming"
class VenueTaskRequest(BaseModel):
task_id: str
agent_type: str
timestamp: str
params: dict
# 场地数据库
venue_db = {
"basketball": {
"outdoor": {
"2025-05-08": VenueStatus.AVAILABLE,
"2025-05-09": VenueStatus.MAINTENANCE,
"2025-05-10": VenueStatus.AVAILABLE,
"2025-05-11": VenueStatus.RESERVED
},
"indoor": {
"2025-05-08": VenueStatus.OCCUPIED,
"2025-05-09": VenueStatus.AVAILABLE,
"2025-05-10": VenueStatus.AVAILABLE,
"2025-05-11": VenueStatus.AVAILABLE
}
},
"football": {
"outdoor": {
"2025-05-08": VenueStatus.AVAILABLE,
"2025-05-09": VenueStatus.AVAILABLE
}
}
}
# 场地详细信息
venue_details = {
"basketball_outdoor": {
"name": "室外篮球场A区",
"capacity": 20,
"facilities": ["灯光", "休息区", "饮水机"],
"hourly_rate": 50,
"location": "体育馆东侧"
},
"basketball_indoor": {
"name": "室内篮球馆主场地",
"capacity": 50,
"facilities": ["空调", "更衣室", "淋浴间", "专业地板"],
"hourly_rate": 150,
"location": "体育馆主馆"
}
}
class VenueManager:
@staticmethod
def check_availability(sport_type: str, venue_type: str, date: str) -> Dict:
"""检查场地可用性"""
if sport_type not in venue_db:
return {
"status": VenueStatus.OCCUPIED,
"message": "不支持的体育类型"
}
if venue_type not in venue_db[sport_type]:
return {
"status": VenueStatus.OCCUPIED,
"message": "不支持的场地类型"
}
date_availability = venue_db[sport_type][venue_type]
if date in date_availability:
status = date_availability[date]
message = VenueManager._get_status_message(status)
else:
status = VenueStatus.AVAILABLE
message = "场地可用"
return {
"status": status,
"message": message,
"details": venue_details.get(f"{sport_type}_{venue_type}", {})
}
@staticmethod
def _get_status_message(status: VenueStatus) -> str:
messages = {
VenueStatus.AVAILABLE: "场地可用",
VenueStatus.OCCUPIED: "场地已被占用",
VenueStatus.MAINTENANCE: "场地维护中",
VenueStatus.RESERVED: "场地已被预订"
}
return messages.get(status, "场地状态未知")
@staticmethod
def reserve_venue(sport_type: str, venue_type: str, date: str, duration: int) -> Dict:
"""预订场地"""
availability = VenueManager.check_availability(sport_type, venue_type, date)
if availability["status"] != VenueStatus.AVAILABLE:
return {
"success": False,
"message": f"无法预订: {availability['message']}",
"reservation_id": None
}
# 模拟预订过程
reservation_id = str(uuid.uuid4())[:8]
venue_db[sport_type][venue_type][date] = VenueStatus.RESERVED
return {
"success": True,
"message": "预订成功",
"reservation_id": reservation_id,
"details": availability["details"]
}
VENUE_AGENT_CARD = {
"name": "VenueAgent",
"version": "1.0.0",
"description": "提供场地管理和预订服务",
"endpoints": {
"task_submit": "/api/tasks/venue/check",
"reservation": "/api/tasks/venue/reserve",
"health_check": "/health"
},
"input_schema": {
"type": "object",
"properties": {
"date": {"type": "string", "format": "date"},
"venue_type": {"type": "string", "enum": ["outdoor", "indoor"]},
"sport_type": {"type": "string", "enum": ["basketball", "football", "tennis"]}
},
"required": ["date", "venue_type"]
},
"capabilities": {
"availability_check": True,
"reservation_management": True,
"venue_information": True
},
"authentication": {"methods": ["API_Key"]}
}
@app.get("/.well-known/agent.json")
async def get_agent_card():
return VENUE_AGENT_CARD
@app.get("/health")
async def health_check():
return {"status": "healthy", "service": "VenueAgent"}
@app.post("/api/tasks/venue/check")
async def check_venue_availability(request: VenueTaskRequest):
"""检查场地可用性"""
date = request.params.get("date")
venue_type = request.params.get("venue_type")
sport_type = request.params.get("sport_type", "basketball")
if not date or not venue_type:
raise HTTPException(status_code=400, detail="缺少必要参数")
availability = VenueManager.check_availability(sport_type, venue_type, date)
return {
"task_id": request.task_id,
"status": "completed",
"artifact": {
"date": date,
"venue_type": venue_type,
"sport_type": sport_type,
"status": availability["status"],
"message": availability["message"],
"details": availability["details"]
}
}
@app.post("/api/tasks/venue/reserve")
async def reserve_venue(request: VenueTaskRequest):
"""预订场地"""
date = request.params.get("date")
venue_type = request.params.get("venue_type")
sport_type = request.params.get("sport_type", "basketball")
duration = request.params.get("duration", 2)
if not date or not venue_type:
raise HTTPException(status_code=400, detail="缺少必要参数")
reservation_result = VenueManager.reserve_venue(sport_type, venue_type, date, duration)
return {
"task_id": request.task_id,
"status": "completed",
"artifact": reservation_result
}
@app.get("/api/venue/types")
async def get_venue_types(sport_type: str = "basketball"):
"""获取可用的场地类型"""
if sport_type in venue_db:
return {
"sport_type": sport_type,
"available_venue_types": list(venue_db[sport_type].keys()),
"details": {f"{sport_type}_{vt}": venue_details.get(f"{sport_type}_{vt}")
for vt in venue_db[sport_type].keys()}
}
else:
raise HTTPException(status_code=404, detail="不支持的体育类型")
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8001, log_level="info")
MultiAgent2示例:
文档内容字符有限,有需要可留言
6. 系统特性体现
- 高效并行处理:通过同时执行多个代理检查,显著优化了系统响应时间。
- 分级决策机制:按照安全、资源、人员的优先级顺序执行决策,确保关键因素优先考虑。
- 条件性操作执行:通知等后续操作仅在特定决策条件下触发,避免不必要的资源消耗。
- 完整溯源能力:通过详细的检查结果记录和决策原因说明,提供完整的决策过程溯源。
- 弹性容错设计:单个代理服务的故障不会导致整个系统崩溃,具备优雅降级能力。
五、总结
从简单的天气查询代理到复杂的多代理协同决策系统,我们见证了A2A智能代理协议如何重塑分布式人工智能的架构范式。这个演进过程不仅仅是技术栈的升级,更是思维模式的根本转变——从追求单体智能的极致性能转向构建智能体间的协同生态。
通过篮球会议安排系统的完整示例,我们看到了A2A协议的核心价值:标准化的服务发现机制让代理能够自主识别彼此能力,语义化的任务描述确保跨系统的准确理解,自治性的决策逻辑使每个代理都能发挥专业优势。这种架构带来的不仅是技术上的松耦合和可扩展性,更是业务层面的敏捷响应和智能升级。
更重要的是,这个系统展现了分布式智能的乘法效应:单个代理或许只能解决特定领域的问题,但当它们通过A2A协议协同工作时,产生的集体智能远远超出各部分能力的简单叠加。天气代理的专业预报、场地代理的资源管理、日历代理的时间协调、通知代理的沟通触达——每个代理专注本职,却共同完成了一个需要多维度考量的复杂决策。