Python A2A: Google 的智能体到智能体协议的全面指南

简介

Python A2A 是 Google 的智能体到智能体 (Agent-to-Agent, A2A) 协议的实现,旨在标准化 AI 智能体之间的通信。该协议解决了 AI 生态系统中的一个主要挑战:使不同的 AI 服务能够无需自定义转换层即可无缝通信。

随着 AI 领域分化为各种专业服务,每种服务都有自己的 API 格式和参数,开发人员花费过多时间构建通信基础设施,而不是专注于 AI 逻辑。Python A2A 通过提供一种标准化的方式让 AI 智能体互相交流,解决了这个问题,无论它们的底层实现如何。

Python A2A 入门

安装

# 基本安装
pip install python-a2a

# 用于 OpenAI 集成
pip install "python-a2a[openai]"

# 用于 Anthropic Claude 集成
pip install "python-a2a[anthropic]"

# 安装所有可选依赖
pip install "python-a2a[all]"

核心概念

Python A2A 实现了 A2A 协议的几个关键概念:

  1. 1. 消息结构:定义了文本、函数调用和响应的格式
  2. 2. 对话线程:支持在多次交互中维护上下文
  3. 3. 函数调用:智能体暴露和调用函数的标准化方式
  4. 4. 错误处理:一致的错误格式

构建您的第一个 A2A 智能体

让我们从一个简单的回声智能体开始,它会响应消息:

from python_a2a import A2AServer, Message, TextContent, MessageRole, run_server

class EchoAgent(A2AServer):
    """一个简单的智能体,用前缀回显消息。"""

    def handle_message(self, message):
        if message.content.type == "text":
            return Message(
                content=TextContent(text=f"Echo: {message.content.text}"),
                role=MessageRole.AGENT,
                parent_message_id=message.message_id,
                conversation_id=message.conversation_id
            )

# 运行服务器
if __name__ == "__main__":
    agent = EchoAgent()
    run_server(agent, host="0.0.0.0", port=5000)

现在,让我们创建一个客户端来与我们的智能体交流:

from python_a2a import A2AClient, Message, TextContent, MessageRole

# 创建一个客户端来与我们的智能体交流
client = A2AClient("http://localhost:5000/a2a")

# 发送消息
message = Message(
    content=TextContent(text="Hello, is this thing on?"),
    role=MessageRole.USER
)
response = client.send_message(message)

# 打印响应
print(f"Agent says: {response.content.text}")

智能体之间的函数调用

A2A 的强大功能之一是标准化的函数调用。这是一个提供数学函数的计算器智能体:

import math
from python_a2a import (
    A2AServer, Message, TextContent, FunctionCallContent,
    FunctionResponseContent, FunctionParameter, MessageRole, run_server
)

class CalculatorAgent(A2AServer):
    """提供数学计算函数的智能体。"""

    def handle_message(self, message):
        if message.content.type == "text":
            return Message(
                content=TextContent(
                    text="我是一个计算器智能体。你可以调用我的函数:\n"
                         "- calculate: 基础算术 (operation, a, b)\n"
                         "- sqrt: 平方根 (value)"
                ),
                role=MessageRole.AGENT,
                parent_message_id=message.message_id,
                conversation_id=message.conversation_id
            )

        elif message.content.type == "function_call":
            function_name = message.content.name
            params = {p.name: p.value for p in message.content.parameters}

            try:
                if function_name == "calculate":
                    operation = params.get("operation", "add")
                    a = float(params.get("a", 0))
                    b = float(params.get("b", 0))

                    if operation == "add":
                        result = a + b
                    elif operation == "subtract":
                        result = a - b
                    elif operation == "multiply":
                        result = a * b
                    elif operation == "divide":
                        if b == 0:
                            raise ValueError("不能除以零")
                        result = a / b
                    else:
                        raise ValueError(f"未知操作: {operation}")

                    return Message(
                        content=FunctionResponseContent(
                            name="calculate",
                            response={"result": result}
                        ),
                        role=MessageRole.AGENT,
                        parent_message_id=message.message_id,
                        conversation_id=message.conversation_id
                    )

                elif function_name == "sqrt":
                    value = float(params.get("value", 0))
                    if value < 0:
                        raise ValueError("不能计算负数的平方根")

                    result = math.sqrt(value)
                    return Message(
                        content=FunctionResponseContent(
                            name="sqrt",
                            response={"result": result}
                        ),
                        role=MessageRole.AGENT,
                        parent_message_id=message.message_id,
                        conversation_id=message.conversation_id
                    )

            except Exception as e:
                return Message(
                    content=FunctionResponseContent(
                        name=function_name,
                        response={"error": str(e)}
                    ),
                    role=MessageRole.AGENT,
                    parent_message_id=message.message_id,
                    conversation_id=message.conversation_id
                )

if __name__ == "__main__":
    agent = CalculatorAgent()
    run_server(agent, host="0.0.0.0", port=5001)

以下是如何调用计算器智能体的函数:

from python_a2a import (
    A2AClient, Message, FunctionCallContent,
    FunctionParameter, MessageRole
)

client = A2AClient("http://localhost:5001/a2a")

# 创建一个函数调用消息
function_call = Message(
    content=FunctionCallContent(
        name="calculate",
        parameters=[
            FunctionParameter(name="operation", value="add"),
            FunctionParameter(name="a", value=5),
            FunctionParameter(name="b", value=3)
        ]
    ),
    role=MessageRole.USER
)

response = client.send_message(function_call)

if response.content.type == "function_response":
    result = response.content.response.get("result")
    if result is not None:
        print(f"Result: {result}")  # 输出: Result: 8

基于 LLM 的智能体

Python A2A 包含了与流行 LLM 提供商的即用型集成。这是一个由 OpenAI 驱动的智能体:

import os
from python_a2a import OpenAIA2AServer, run_server

# 创建一个由 OpenAI 驱动的智能体
agent = OpenAIA2AServer(
    api_key=os.environ["OPENAI_API_KEY"],
    model="gpt-4",
    system_prompt="你是一个有帮助的 AI 助手。"
)

# 运行服务器
if __name__ == "__main__":
    run_server(agent, host="0.0.0.0", port=5002)

同样,您可以创建一个由 Anthropic Claude 驱动的智能体:

import os
from python_a2a import ClaudeA2AServer, run_server

# 创建一个由 Anthropic Claude 驱动的智能体
agent = ClaudeA2AServer(
    api_key=os.environ["ANTHROPIC_API_KEY"],
    model="claude-3-opus-20240229",
    system_prompt="你是一个有帮助的 AI 助手。"
)

# 运行服务器
if __name__ == "__main__":
    run_server(agent, host="0.0.0.0", port=5003)

多智能体工作流

A2A 的真正威力在于连接多个智能体。让我们构建一个研究助手工作流:

from python_a2a import (
    A2AClient, Message, TextContent, MessageRole, Conversation
)

def research_workflow(query):
    # 连接到专业智能体
    llm_client = A2AClient("http://localhost:5002/a2a")     # LLM 智能体
    search_client = A2AClient("http://localhost:5003/a2a")  # 搜索智能体
    summarize_client = A2AClient("http://localhost:5004/a2a")  # 总结智能体

    # 在对话中跟踪整个工作流
    conversation = Conversation()
    conversation.create_text_message(
        text=f"研究问题: {query}",
        role=MessageRole.USER
    )

    # 步骤 1: 生成搜索查询
    print("生成搜索查询...")
    search_request = Message(
        content=TextContent(
            text=f"基于这个研究问题: '{query}', "
                 f"生成 3 个特定的搜索查询,以帮助找到相关信息。"
        ),
        role=MessageRole.USER
    )
    search_queries_response = llm_client.send_message(search_request)
    conversation.add_message(search_queries_response)

    # 步骤 2: 检索信息
    print("检索信息...")
    search_message = Message(
        content=TextContent(
            text=f"搜索信息以回答: {query}\n\n"
                 f"使用这些查询:\n{search_queries_response.content.text}"
        ),
        role=MessageRole.USER
    )
    search_results = search_client.send_message(search_message)
    conversation.add_message(search_results)

    # 步骤 3: 综合信息
    print("综合信息...")
    summarize_message = Message(
        content=TextContent(
            text=f"综合这些信息来回答问题: '{query}'\n\n"
                 f"信息:\n{search_results.content.text}"
        ),
        role=MessageRole.USER
    )
    summary_response = summarize_client.send_message(summarize_message)
    conversation.add_message(summary_response)

    # 将最终答案添加到对话中
    conversation.create_text_message(
        text=f"你的研究问题的答案:\n\n{summary_response.content.text}",
        role=MessageRole.AGENT
    )

    return conversation

# 使用示例
if __name__ == "__main__":
    query = input("你的研究问题是什么? ")
    result = research_workflow(query)
    print("\n研究完成!")
    print("=" * 50)
    print(result.messages[-1].content.text)

高级示例:使用 A2A 进行天气和行程规划

这是一个示例,展示了 A2A 如何简化智能体之间的通信:

from python_a2a import A2AClient, Message, TextContent, MessageRole

# 使用 A2A: 任何智能体 -> 任何其他智能体
def plan_trip(location):
    # 连接到专业智能体 - 都使用相同的协议
    weather_client = A2AClient("http://localhost:5001/a2a")
    openai_client = A2AClient("http://localhost:5002/a2a")

    # 询问天气智能体
    weather_message = Message(
        content=TextContent(text=f"请问{location}的天气预报如何?"),
        role=MessageRole.USER
    )
    weather_response = weather_client.send_message(weather_message)

    # 询问 OpenAI 智能体,包括天气信息
    planning_message = Message(
        content=TextContent(
            text=f"我正在计划前往{location}的旅行。天气预报: {weather_response.content.text}"
                 f"请推荐一些活动。"
        ),
        role=MessageRole.USER
    )
    planning_response = openai_client.send_message(planning_message)

    return planning_response.content.text

# 这适用于任何兼容 A2A 的智能体 - 无需自定义适配器!

管理对话

Python A2A 提供了一个 Conversation 类来管理多轮交互:

from python_a2a import Conversation, MessageRole, A2AClient

# 创建一个新对话
conversation = Conversation()

# 添加用户消息
conversation.create_text_message(
    text="今天天气怎么样?",
    role=MessageRole.USER
)

# 连接到一个智能体
weather_agent = A2AClient("http://localhost:5001/a2a")

# 发送对话中的最后一条消息
last_message = conversation.messages[-1]
response = weather_agent.send_message(last_message)

# 将响应添加到对话中
conversation.add_message(response)

# 继续对话
conversation.create_text_message(
    text="谢谢!我需要带伞吗?",
    role=MessageRole.USER
)

# 发送新消息,包括对话历史
response = weather_agent.send_message(
    conversation.messages[-1],
    conversation_id=conversation.conversation_id
)

# 也添加这个响应
conversation.add_message(response)

# 打印整个对话
for msg in conversation.messages:
    role = "用户" if msg.role == MessageRole.USER else "智能体"
    print(f"{role}: {msg.content.text}")

错误处理

Python A2A 提供标准化的错误处理:

from python_a2a import A2AClient, Message, TextContent, MessageRole

client = A2AClient("http://localhost:5001/a2a")

try:
    message = Message(
        content=TextContent(text="你好"),
        role=MessageRole.USER
    )
    response = client.send_message(message)

except ConnectionError as e:
    print(f"连接错误: {e}")

except TimeoutError as e:
    print(f"超时错误: {e}")

except Exception as e:
    print(f"意外错误: {e}")

创建自定义 A2A 智能体

以下是创建您自己的 A2A 兼容智能体的模板:

from python_a2a import A2AServer, Message, TextContent, MessageRole, run_server

class MyCustomAgent(A2AServer):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 在这里初始化您的智能体特定组件

    def handle_message(self, message):
        """处理收到的消息并返回响应。

        这是处理智能体消息的主要入口点。
        """
        if message.content.type == "text":
            # 处理文本消息
            user_text = message.content.text

            # 生成您的响应(替换为您的逻辑)
            response_text = f"你说: {user_text}"

            return Message(
                content=TextContent(text=response_text),
                role=MessageRole.AGENT,
                parent_message_id=message.message_id,
                conversation_id=message.conversation_id
            )

        elif message.content.type == "function_call":
            # 处理函数调用(如果您的智能体支持)
            # ...
            pass

        # 如果没有其他条件匹配,返回默认响应
        return Message(
            content=TextContent(text="我不知道如何处理这种消息类型。"),
            role=MessageRole.AGENT,
            parent_message_id=message.message_id,
            conversation_id=message.conversation_id
        )

# 运行您的智能体
if __name__ == "__main__":
    my_agent = MyCustomAgent()
    run_server(my_agent, host="0.0.0.0", port=5005)

结论

Python A2A 提供了一种标准化的方式让 AI

智能体进行通信,使构建多智能体系统变得更加容易。通过采用这个协议,您可以:

  1. 1. 减少在通信基础设施上花费的开发时间
  2. 2. 轻松切换和升级智能体实现
  3. 3. 构建模块化、可扩展的 AI 系统
  4. 4. 利用专业智能体完成不同任务

A2A 协议及其 Python 实现正在帮助构建一个未来,在这个未来中,AI 系统可以像乐高积木一样组合,让专业智能体无缝合作。

欲了解更多信息,请查看 Python A2A 的 GitHub 仓库、PyPI 页面和文档。

Python A2A: Google 的智能体到智能体协议的全面指南

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值