A2A 协议实战:使用 Python SDK 构建你的第一个智能体

摘要

本文将手把手引导您使用 Agent2Agent (A2A) Python SDK 从零开始构建您的第一个 AI 智能体。我们将涵盖环境搭建、智能体核心概念、任务处理机制,以及智能体之间如何进行高效通信。通过丰富的代码示例和图表,您将能够快速掌握 A2A 协议的实际应用,为构建复杂的智能体协作系统打下坚实基础。

1. 引言

在 AI 应用开发领域,智能体之间的协同工作日益成为主流趋势。想象一下,一个智能体负责数据分析,另一个智能体负责报告生成,它们之间如何无缝协作?这就是 Agent2Agent (A2A) 协议的价值所在。A2A 协议提供了一套开放、标准化的通信机制,使得不同 AI 框架、不同部署环境下的智能体能够像人类团队成员一样协同完成复杂任务。

而 A2A Python SDK 则是帮助 Python 开发者快速接入 A2A 生态系统的强大工具。它封装了协议的底层细节,让您能够专注于智能体本身的业务逻辑。本文将通过实际案例,带您领略 A2A Python SDK 的魅力。

2. A2A Python SDK 快速入门

2.1 环境准备

在使用 A2A Python SDK 之前,请确保您的系统已安装 Python 3.8 或更高版本。

安装 A2A SDK 非常简单,只需运行以下 pip 命令:

pip install a2a-sdk

如果您需要额外安装一些异步 HTTP 客户端库(如 aiohttp),可以这样安装:

pip install a2a-sdk[aiohttp]

2.2 A2A 核心概念回顾

在开始编写代码之前,我们先快速回顾几个 A2A 协议中的关键概念,它们是理解 SDK 使用的基础:

  • 智能体 (Agent):A2A 世界中的一个独立实体,它封装了特定的能力或服务。例如,一个“文本分析智能体”或一个“日程管理智能体”。
  • 智能体卡片 (Agent Card):每个智能体的“名片”,公开了智能体的基本信息(如名称、版本)、它提供的能力列表 (Capabilities) 以及与它通信的接口地址 (Endpoint)。智能体通过发布 Agent Card 来实现自我发现。
  • 任务 (Task):智能体之间进行交互的基本单位。一个任务通常包含一个 task_type(任务类型,表示期望执行的操作)和 input_data(任务所需的输入数据)。
  • 技能 (Skill):智能体提供给外部使用的具体功能。在 A2A Python SDK 中,您可以通过定义任务处理函数来暴露智能体的技能。

3. 构建你的第一个 A2A 智能体:问候机器人

让我们从一个简单的“问候机器人”开始。这个智能体将提供一个“问候”技能,接收一个姓名,然后返回一句友好的问候语。

3.1 智能体定义与初始化

首先,我们需要导入 Agent 类并创建一个智能体实例。在初始化时,我们需要为智能体指定一个唯一的名称、版本以及它提供的能力列表。

# greet_agent.py

import asyncio
from a2a import Agent, AgentCard, A2AError
import logging

# 配置日志,以便观察智能体的运行状态
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

async def main():
    # 1. 定义智能体
    # name: 智能体的唯一标识
    # version: 智能体的版本号
    # capabilities: 智能体提供的能力列表,这些能力将在 Agent Card 中公开
    greeting_agent = Agent(
        name="GreetingAgent",
        version="1.0.0",
        capabilities=["greet"]
    )

    # 2. 注册智能体
    # 智能体需要注册到 A2A 注册中心,以便其他智能体能够发现它。
    # 注册成功后,智能体的 Agent Card 将被发布。
    try:
        await greeting_agent.register()
        logger.info(f"智能体 '{greeting_agent.name}' 注册成功。")
    except A2AError as e:
        logger.error(f"智能体注册失败: {e}")
        return

    # 3. 启动智能体服务
    # 启动一个 HTTP 服务器来监听传入的任务请求。
    # 通常,智能体会在一个异步事件循环中运行,等待任务。
    logger.info(f"智能体 '{greeting_agent.name}' 正在启动,等待任务... ")
    await greeting_agent.start()

if __name__ == "__main__":
    # 在实际应用中,您可能希望将智能体运行在一个持久化的环境中。
    # 这里为了演示,我们简单地运行 main 函数。
    asyncio.run(main())

在上述代码中:

  • 我们首先导入了必要的模块。
  • greeting_agent = Agent(...) 创建了一个名为 GreetingAgent 的智能体实例,并声明它拥有 greet 能力。
  • await greeting_agent.register() 将智能体注册到 A2A 生态中,使其可被发现。
  • await greeting_agent.start() 启动智能体的服务器,使其能够接收任务。

3.2 实现智能体技能 (Task Handler)

智能体的核心在于它能够执行特定的任务。在 A2A Python SDK 中,您可以使用 @agent.task_handler() 装饰器来定义处理特定任务类型的函数。

让我们在 greet_agent.py 中添加 greet 技能的实现:

# greet_agent.py (在上述代码的基础上添加)

# ... existing code ...

# 定义一个异步函数来处理 'greet' 类型的任务
@greeting_agent.task_handler("greet")
async def handle_greet_task(task: dict) -> dict:
    """
    处理 'greet' 任务。接收一个包含 'name' 字段的字典作为输入,
    并返回一个包含问候语的字典。
    例如:输入 {'name': 'Alice'},返回 {'message': 'Hello, Alice!'}
    """
    logger.info(f"接收到 'greet' 任务: {task}")
    
    # 检查输入数据是否包含 'name' 字段
    if 'name' not in task.get('input', {}):
        logger.warning("'greet' 任务输入中缺少 'name' 字段。")
        # 抛出 A2AError 来表示任务处理失败
        raise A2AError("Missing 'name' in input data")
    
    name = task['input']['name']
    message = f"Hello, {name}! Welcome to A2A world!"
    logger.info(f"完成 'greet' 任务,返回: {{"message": "{message}"}}")
    return {"message": message}

# ... existing code ...

智能体任务处理流程图:

greet
成功
失败
接收任务请求
解析任务类型
调用 handle_greet_task
处理业务逻辑
返回任务结果
返回错误信息
发送响应

现在,您的第一个 A2A 智能体已经可以运行了!保存 greet_agent.py 文件,并在终端中运行它:

python greet_agent.py

您应该会看到智能体成功注册并启动的日志信息。它现在正在等待其他智能体发送“greet”任务。

4. 智能体之间的通信:调用问候机器人

一个智能体只有能够与其他智能体交互,才能发挥其最大的价值。现在,让我们创建一个简单的客户端脚本,模拟另一个智能体来调用 GreetingAgentgreet 技能。

4.1 执行任务 (Task Execution)

在 A2A Python SDK 中,您可以使用 agent.execute_task() 方法来向另一个智能体发送任务请求。

创建一个新文件 client_agent.py

# client_agent.py

import asyncio
from a2a import Agent, AgentCard, A2AError
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

async def main():
    # 1. 初始化一个客户端智能体实例
    # 即使只是为了发送请求,我们也需要一个 Agent 实例来管理连接和身份验证。
    # 这个智能体本身不提供任何服务,所以 capabilities 可以为空。
    client_agent = Agent(
        name="ClientAgent",
        version="1.0.0",
        capabilities=[]
    )

    # 2. 尝试调用 GreetingAgent 的 'greet' 技能
    target_agent_name = "GreetingAgent"
    task_type = "greet"
    input_data = {"name": "A2A 开发者"}

    logger.info(f"尝试向 '{target_agent_name}' 发送任务 '{task_type}'...")

    try:
        # execute_task 方法用于向目标智能体发送任务请求
        # target_agent: 目标智能体的名称(将通过注册中心查找)
        # task_type: 要执行的任务类型
        # input_data: 任务所需的输入数据
        response = await client_agent.execute_task(
            target_agent=target_agent_name,
            task_type=task_type,
            input_data=input_data
        )

        logger.info(f"收到 '{target_agent_name}' 的响应: {response}")
        print(f"智能体响应: {response.get('message', '无消息')}")

    except A2AError as e:
        logger.error(f"调用智能体 '{target_agent_name}' 失败: {e}")
    except Exception as e:
        logger.error(f"发生未知错误: {e}")

if __name__ == "__main__":
    asyncio.run(main())

智能体间任务执行时序图:

ClientAgent A2ARegistry GreetingAgent 查询 GreetingAgent 的 Agent Card 返回 GreetingAgent 的 Endpoint 执行任务 (task_type: greet, input: {name: '...'}) 处理 greet 技能 返回任务结果 ({message: '...'}) ClientAgent A2ARegistry GreetingAgent

运行示例:

  1. 确保 greet_agent.py 正在运行。
  2. 打开一个新的终端,运行 client_agent.py
    python client_agent.py
    

您将看到 ClientAgent 发送请求,GreetingAgent 接收并处理请求,最后 ClientAgent 收到并打印出问候语。这展示了两个 A2A 智能体之间一次完整的任务交互过程。

5. 最佳实践与注意事项

5.1 错误处理与异常捕获

健壮的智能体应用离不开完善的错误处理。A2A Python SDK 在遇到协议相关错误时会抛出 A2AError 及其子类。始终使用 try-except 块来捕获这些异常,并进行适当的日志记录或错误恢复。

# 错误处理示例
from a2a import A2AError, AgentNotFoundError, TaskExecutionError

async def call_agent_safely(agent_instance, target_name, task_type, input_data):
    try:
        response = await agent_instance.execute_task(
            target_agent=target_name,
            task_type=task_type,
            input_data=input_data
        )
        return response
    except AgentNotFoundError:
        logger.error(f"目标智能体 '{target_name}' 未找到。请检查其是否已注册并正在运行。")
    except TaskExecutionError as e:
        logger.error(f"任务 '{task_type}' 执行失败,目标智能体返回错误: {e.details}")
    except A2AError as e:
        logger.error(f"A2A 通信错误: {e}")
    except Exception as e:
        logger.error(f"发生未知异常: {e}")
    return None

5.2 日志记录

良好的日志记录是调试和监控智能体应用的关键。使用 Python 标准的 logging 模块,为您的智能体操作(如任务接收、处理、发送请求、错误等)添加详细的日志信息。

5.3 代码结构与模块化

随着智能体功能的增长,将代码合理地划分为不同的模块和函数至关重要。例如,将智能体的定义、任务处理函数和客户端逻辑分离到不同的文件中,可以提高代码的可读性和可维护性。

5.4 异步编程

A2A Python SDK 是基于 asyncio 构建的,因此您在编写智能体代码时会大量使用 asyncawait 关键字。理解 Python 的异步编程模型对于有效利用 SDK 至关重要。

6. 总结

通过本文的学习,您已经成功迈出了 A2A 协议实践的第一步。您不仅了解了 A2A Python SDK 的基本用法,还亲手构建了一个能够接收和处理任务的智能体,并学会了如何让它与其他智能体进行通信。我们涵盖了:

  • A2A Python SDK 的安装与环境配置。
  • 智能体定义、注册和启动的完整流程。
  • 使用 @agent.task_handler() 装饰器实现智能体技能。
  • 通过 agent.execute_task() 方法实现智能体间的任务调用。
  • 错误处理、日志记录等最佳实践。

这只是 A2A 协议强大功能的冰山一角。接下来,您可以尝试更复杂的任务类型、处理流式数据,或探索 A2A 协议的安全特性。

7. 参考资料

  1. A2A 官方文档
  2. A2A 协议规范
  3. A2A Python SDK GitHub 仓库
  4. A2A 示例代码

8. 扩展阅读

  • A2A 协议高级特性:探索流式通信 (SSE) 和异步推送通知。
  • 深入理解 Agent Card:如何设计和发布更丰富的智能体能力描述。
  • 智能体部署与管理:在生产环境中如何高效部署和监控 A2A 智能体。
  • A2A 安全机制:身份验证、授权和数据加密。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CarlowZJ

我的文章对你有用的话,可以支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值