6. 与服务器交互¶
在 Helloworld A2A 服务器运行后,我们向它发送一些请求。SDK 包含一个客户端 (A2AClient),可以简化这些交互。
Helloworld 测试客户端¶
test_client.py 脚本演示了如何
- 从服务器获取代理卡。
- 创建
A2AClient实例。 - 发送非流式 (
message/send) 和流式 (message/stream) 请求。
打开一个新的终端窗口,激活您的虚拟环境,并导航到 a2a-samples 目录。
激活虚拟环境(请务必在创建虚拟环境的同一目录中执行此操作)
运行测试客户端
理解客户端代码¶
让我们看看 test_client.py 的关键部分
-
获取代理卡和初始化客户端:
base_url = 'https://:9999' async with httpx.AsyncClient() as httpx_client: # Initialize A2ACardResolver resolver = A2ACardResolver( httpx_client=httpx_client, base_url=base_url, # agent_card_path uses default, extended_agent_card_path also uses default )A2ACardResolver类是一个便利工具。它首先从服务器的/.well-known/agent-card.json端点(基于提供的基本 URL)获取AgentCard,然后用它初始化客户端。 -
发送非流式消息 (
send_message):client = A2AClient( httpx_client=httpx_client, agent_card=final_agent_card_to_use ) logger.info('A2AClient initialized.') send_message_payload: dict[str, Any] = { 'message': { 'role': 'user', 'parts': [ {'kind': 'text', 'text': 'how much is 10 USD in INR?'} ], 'messageId': uuid4().hex, }, } request = SendMessageRequest( id=str(uuid4()), params=MessageSendParams(**send_message_payload) ) response = await client.send_message(request) print(response.model_dump(mode='json', exclude_none=True))send_message_payload构建MessageSendParams的数据。- 这被封装在一个
SendMessageRequest中。 - 它包含一个
message对象,其中role设置为“user”,内容在parts中。 - Helloworld 代理的
execute方法将排队一个“Hello World”消息。DefaultRequestHandler将检索此消息并将其作为响应发送。 response将是一个SendMessageResponse对象,其中包含一个SendMessageSuccessResponse(以代理的Message作为结果)或一个JSONRPCErrorResponse。
-
处理任务 ID(Helloworld 的说明性注释):
Helloworld 客户端 (
test_client.py) 不会直接尝试get_task或cancel_task,因为当通过message/send调用时,简单的 Helloworld 代理的execute方法会导致DefaultRequestHandler返回直接的Message响应,而不是Task对象。更复杂的代理(如 LangGraph 示例)会明确管理任务,它们将从message/send返回一个Task对象,然后其id可以用于get_task或cancel_task。 -
发送流式消息 (
send_message_streaming):streaming_request = SendStreamingMessageRequest( id=str(uuid4()), params=MessageSendParams(**send_message_payload) ) stream_response = client.send_message_streaming(streaming_request) async for chunk in stream_response: print(chunk.model_dump(mode='json', exclude_none=True))- 此方法调用代理的
message/stream端点。DefaultRequestHandler将调用HelloWorldAgentExecutor.execute方法。 execute方法排队一个“Hello World”消息,然后事件队列关闭。- 客户端将接收此单个消息作为一次
SendStreamingMessageResponse事件,然后流将终止。 stream_response是一个AsyncGenerator。
- 此方法调用代理的
预期输出¶
当您运行 test_client.py 时,您将看到以下 JSON 输出:
- 非流式响应(一条“Hello World”消息)。
- 流式响应(一条“Hello World”消息作为一段,之后流结束)。
输出中的 id 字段每次运行都会有所不同。
// Non-streaming response
{"jsonrpc":"2.0","id":"xxxxxxxx","result":{"type":"message","role":"agent","parts":[{"type":"text","text":"Hello World"}],"messageId":"yyyyyyyy"}}
// Streaming response (one chunk)
{"jsonrpc":"2.0","id":"zzzzzzzz","result":{"type":"message","role":"agent","parts":[{"type":"text","text":"Hello World"}],"messageId":"wwwwwwww","final":true}}
(实际 ID,如 xxxxxxxx、yyyyyyyy、zzzzzzzz、wwwwwwww 将是不同的 UUID/请求 ID)
这证实您的服务器正在使用更新后的 SDK 结构正确处理基本的 A2A 交互!
现在,您可以通过在运行 __main__.py 的终端窗口中键入 Ctrl+C 来关闭服务器。