7. 流式传输与多轮交互(LangGraph 示例)¶
Hello World 示例演示了 A2A 的基本机制。对于更高级的功能,例如健壮的流式传输、任务状态管理以及由 LLM 驱动的多轮对话,我们将转向位于 a2a-samples/samples/python/agents/langgraph/ 的 LangGraph 示例。
此示例包含一个“货币代理”,它通过 LangChain 和 LangGraph 使用 Gemini 模型来回答货币换算问题。
设置 LangGraph 示例¶
-
如果您还没有 Gemini API 密钥,请创建一个。
-
环境变量
在
a2a-samples/samples/python/agents/langgraph/目录中创建一个.env文件将
YOUR_API_KEY_HERE替换为您的实际 Gemini API 密钥。 -
安装依赖项(如果尚未涵盖)
langgraph示例有自己的pyproject.toml,其中包含langchain-google-genai和langgraph等依赖项。当您从a2a-samples根目录使用pip install -e .[dev]安装 SDK 时,这也应该安装工作区示例的依赖项,包括langgraph-example。如果您遇到导入错误,请确保从根目录成功安装了主 SDK。
运行 LangGraph 服务器¶
在终端中导航到 a2a-samples/samples/python/agents/langgraph/app 目录,并确保您的虚拟环境(来自 SDK 根目录)已激活。
启动 LangGraph 代理服务器
这将启动服务器,通常在 https://:10000 上。
与 LangGraph 代理交互¶
打开一个新的终端窗口,激活您的虚拟环境,并导航到 a2a-samples/samples/python/agents/langgraph/app。
运行其测试客户端
现在,您可以通过在运行 __main__.py 的终端窗口中键入 Ctrl+C 来关闭服务器。
演示的主要功能¶
langgraph 示例展示了几个重要的 A2A 概念
-
LLM 集成:
agent.py定义了CurrencyAgent。它使用ChatGoogleGenerativeAI和 LangGraph 的create_react_agent来处理用户查询。- 这演示了真实的 LLM 如何为代理的逻辑提供支持。
-
任务状态管理:
-
samples/langgraph/__main__.py使用InMemoryTaskStore初始化DefaultRequestHandler。httpx_client = httpx.AsyncClient() push_config_store = InMemoryPushNotificationConfigStore() push_sender = BasePushNotificationSender(httpx_client=httpx_client, config_store=push_config_store) request_handler = DefaultRequestHandler( agent_executor=CurrencyAgentExecutor(), task_store=InMemoryTaskStore(), push_config_store=push_config_store, push_sender= push_sender ) server = A2AStarletteApplication( agent_card=agent_card, http_handler=request_handler ) uvicorn.run(server.build(), host=host, port=port) -
当
DefaultRequestHandler调用CurrencyAgentExecutor(在samples/langgraph/agent_executor.py中)的execute方法时,它与包含当前任务(如果有)的RequestContext交互。 - 对于
message/send,DefaultRequestHandler使用TaskStore在交互过程中持久化和检索任务状态。如果代理的执行流涉及多个步骤或导致持久任务,则message/send的响应将是一个完整的Task对象。 test_client.py的run_single_turn_test演示了获取Task对象,然后使用get_task查询它。
-
-
使用
TaskStatusUpdateEvent和TaskArtifactUpdateEvent进行流式传输:CurrencyAgentExecutor中的execute方法负责处理非流式和流式请求,由DefaultRequestHandler进行协调。- 当 LangGraph 代理处理请求时(可能涉及调用
get_exchange_rate等工具),CurrencyAgentExecutor会将不同类型的事件排入EventQueueTaskStatusUpdateEvent:用于中间更新(例如,“正在查询汇率...”,“正在处理汇率...”)。这些事件上的final标志为False。TaskArtifactUpdateEvent:当最终答案准备好时,它会作为工件排队。lastChunk标志为True。- 发送一个带有
state=TaskState.completed和final=True的最终TaskStatusUpdateEvent,以表示流式传输任务的结束。
test_client.py的run_streaming_test函数将打印从服务器接收到的这些单独的事件块。
-
多轮对话 (
TaskState.input_required):- 如果查询不明确(例如,用户询问“100 美元是多少?”),
CurrencyAgent可以要求澄清。 - 发生这种情况时,
CurrencyAgentExecutor将将TaskStatusUpdateEvent入队,其中status.state为TaskState.input_required,status.message包含代理的问题(例如,“您想转换为哪种货币?”)。此事件将对当前交互流具有final=True。 test_client.py的run_multi_turn_test函数演示了这一点- 它发送一个初始的模糊查询。
- 代理(通过
DefaultRequestHandler处理入队事件)以一个状态为input_required的Task响应。 - 然后客户端发送第二条消息,其中包括来自第一轮
Task响应的taskId和contextId,以提供缺失的信息(“in GBP”)。这会继续相同的任务。
- 如果查询不明确(例如,用户询问“100 美元是多少?”),
探索代码¶
花点时间查看这些文件
__main__.py:使用A2AStarletteApplication和DefaultRequestHandler进行服务器设置。请注意AgentCard定义包含capabilities.streaming=True。agent.py:带有 LangGraph、LLM 模型和工具定义的CurrencyAgent。agent_executor.py:实现execute(和cancel)方法的CurrencyAgentExecutor。它使用RequestContext来理解正在进行的任务,并使用EventQueue来发送各种事件(TaskStatusUpdateEvent、TaskArtifactUpdateEvent,如果不存在任务,则隐式通过第一个事件发送新的Task对象)。test_client.py:演示各种交互模式,包括检索任务 ID 并将其用于多轮对话。
此示例更丰富地说明了 A2A 如何促进代理之间复杂、有状态和异步的交互。