Google A2A (Agent-to-Agent) 协议实战 —— 用 Python 构建“智能体互联网”

📅 背景:迈向"智能体互联网" (IoA)

时间 :2025 年 4 月 9 日
事件 :Google DeepMind 与 Cloud 团队联合发布 A2A (Agent-to-Agent) 协议
愿景 :打破 AI 孤岛,建立一个去中心化、标准化的 "Internet of Agents"

在 ChatGPT 和 Claude 普及的时代,我们习惯了 人与 AI (User-to-Agent) 的对话。但在 Google 描绘的未来中,真正的爆发在于 AI 与 AI (Agent-to-Agent) 的协作。当你的"日程助理 Agent"能够自动找到"天气 Agent"查询数据,并与"订场 Agent"沟通预定篮球场时,生产力将发生质变。

本文将带你通过 Python + FastAPI ,亲手实现 Google A2A 协议的核心机制,构建两个协作的智能体:WeatherAgent(服务方)BasketBallAgent(消费方)


🏗️ A2A 协议架构图解

A2A 协议的核心哲学是 "自描述 (Self-Describing)""动态发现 (Dynamic Discovery)"

不同于传统的微服务(硬编码 API 路径),A2A 要求每个 Agent 在固定位置(/.well-known/agent.json)暴露一张 Agent Card(智能体名片)。调用方先看名片,再决定如何交互。


💻 代码实战

我们将实现两个独立的文件:服务端提供天气能力,客户端负责调用决策。

1. 服务端:WeatherAgent.py

这个 Agent 的核心是提供标准化的 /.well-known/agent.json,告诉外界:我是谁,我有什能力,怎么调用我

python 复制代码
from fastapi import FastAPI, HTTPException
from datetime import date
from pydantic import BaseModel
import uvicorn

app = FastAPI()

# ----------------------------------------------------
# 1. Agent Card 声明 (A2A 协议的核心)
# ----------------------------------------------------
# 这相当于 AI 界的 "OpenAPI/Swagger",但更面向机器理解
WEATHER_AGENT_CARD = {
    "name": "WeatherAgent",
    "version": "1.0",
    "description": "提供指定日期的天气数据查询",
    # 【关键】动态端点:调用者不需要死记硬背 API 路径,而是从这里读取
    "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-11-08": {"temperature": "25℃", "condition": "雷阵雨"},
    "2025-11-09": {"temperature": "18℃", "condition": "小雨转晴"},
    "2025-11-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__":
    print("🚀 WeatherAgent 正在启动 (Port: 8000)...")
    uvicorn.run(app, host="0.0.0.0", port=8000)

2. 客户端:BasketBallAgent.py

这个 Agent 展示了 A2A 的消费模式。注意看 check_weather 方法,它没有硬编码任务提交的 URL,而是先去查"名片"。

python 复制代码
import requests
import uuid

class BasketBallAgent:
    def __init__(self):
        # 在实际 A2A 网络中,这里可能是服务发现中心的地址
        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()), # 唯一的任务追踪 ID
            "params": {
                "date": target_date,
                "location": "北京"
            }
        }

    def check_weather(self, target_date: str) -> dict:
        """
        【核心逻辑】通过 A2A 协议动态发现并调用
        """
        try:
            # 1. 发现阶段 (Discovery)
            # 哪怕服务端把接口从 /api/tasks/weather 改成了 /v2/query,
            # 只要 agent.json 更新了,客户端代码无需修改即可自适应。
            print(f"[*] 正在握手: 获取 {self.weather_agent_url} 的 Agent Card...")
            agent_card = requests.get(
                f"{self.weather_agent_url}/.well-known/agent.json"
            ).json()
            
            submit_url = agent_card['endpoints']['task_submit']
            print(f"[*] 发现任务接口: {submit_url}")

            # 2. 执行阶段 (Execution)
            task = self._create_task(target_date)
            response = requests.post(
                f"{self.weather_agent_url}{submit_url}",
                json=task,
                headers={"Authorization": f"Bearer {self.api_key}"}
            )
            
            if response.status_code == 200:
                return response.json()["artifact"]
            else:
                raise Exception(f"天气查询失败: {response.text}")
                
        except Exception as e:
            print(f"[!] A2A 通信错误: {e}")
            raise

    def schedule_meeting(self, date: str):
        """综合决策逻辑"""
        print(f"\n--- 开始决策: {date} 是否去打球? ---")
        try:
            result = self.check_weather(date)
            condition = result["weather"]["condition"]
            temp = result["weather"]["temperature"]
            
            print(f"[*] 天气反馈: {temp}, {condition}")

            # 简单的业务规则
            if "雨" not in condition and "雪" not in condition:
                return {"decision": "✅ 去打球", "reason": f"天气不错 ({condition})"}
            else:
                return {"decision": "❌ 取消", "reason": f"天气恶劣 ({condition})"}
        except Exception as e:
            return {"status": "error", "detail": str(e)}

# 使用示例
if __name__ == "__main__":
    meeting_agent = BasketBallAgent()
    
    # 测试 Case 1: 2025-11-08 (雷阵雨)
    res1 = meeting_agent.schedule_meeting("2025-11-08")
    print(f"最终结果: {res1}\n")
    
    # 测试 Case 2: 2025-11-10 (多云转晴)
    res2 = meeting_agent.schedule_meeting("2025-11-10")
    print(f"最终结果: {res2}")

🔍 原理深度解析

为什么 Google A2A 要这么设计?相比直接写死 API 调用,这种模式带来了三大变革:

1. 解耦与进化 (Decoupling)

在上面的代码中,BasketBallAgent 并不假设 WeatherAgent 的 API 路径是 /api/tasks/weather。它是通过读取 endpoints 字典动态获取的。

这意味着,服务方可以随意重构后端路由,甚至升级版本,只要更新 agent.json,所有的调用方(Clients)都不需要重新部署代码。

2. 语义标准化 (Semantic Standardization)

input_schema 使用了标准的 JSON Schema。

在未来,BasketBallAgent 可能不仅仅是一个 Python 脚本,而是一个 LLM(大模型) 。LLM 可以阅读 agent.json 中的 descriptionschema,自动理解:"哦,调用这个工具需要传一个 date 格式的字符串",从而实现 Zero-Shot Tool Use(零样本工具调用)

3. 互操作性 (Interoperability)

A2A 协议旨在成为 AI 界的 HTTP。无论你的 Agent 是基于 LangChain、AutoGPT 还是 CrewAI 开发的,只要大家都遵守 /.well-known/agent.json 的规范,就能无缝连接,形成真正的"智能体互联网"。


🏃‍♂️ 运行步骤

  1. 安装依赖

    bash 复制代码
    pip install fastapi uvicorn requests pydantic
  2. 启动服务端

    打开终端窗口 A,运行:

    bash 复制代码
    python WeatherAgent.py

    输出:Uvicorn running on http://0.0.0.0:8000

  3. 运行客户端

    打开终端窗口 B,运行:

    bash 复制代码
    python BasketBallAgent.py
  4. 观察输出


🔮 总结

Google A2A 协议的出现,标志着 AI 应用开发从 Prompt Engineering(提示词工程) 转向 Agent Choreography(智能体编排)

通过本文的实战,我们构建了一个最基础的 A2A 单元。虽然代码简单,但它展示了未来 AI 社会的基本协作单元------每个 Agent 都是一个独立的 Web 服务,通过通用的协议相互连接,共同完成人类无法独立完成的复杂任务。

觉得有帮助?欢迎点赞、收藏、关注,获取更多 AI 前沿实战干货! 🌟

相关推荐
zoujiahui_201844 分钟前
使用venv命令创建和使用python环境
开发语言·python
资深低代码开发平台专家1 小时前
Python自动化:一键搞定“文件批量重命名”
python
追光天使1 小时前
Python的后端框架
python
姚华军1 小时前
利用Python算法,解析PDF文件并生成文档分块Chunks,追加到RagFlow知识库
开发语言·python·pdf·chunks·ragflow
dagouaofei1 小时前
AI自动生成你的年度报告PPT
人工智能·python·powerpoint
嫂子的姐夫1 小时前
01-selenium
爬虫·python·selenium·自动化
m0_661279181 小时前
学习笔记-安装并启动 Jupyter Noteboo
开发语言·python
xwill*1 小时前
3D-GENERALIST: Vision-Language-Action Models for Crafting 3D Worlds
人工智能·pytorch·python·深度学习