使用说明
A2A,MCP作为注册表
利用模型上下文协议(MCP)作为发现和检索Google A2A代理卡的标准化机制,使用A2A实现动态代理交互。
目录
目标
利用模型上下文协议(MCP)作为发现和检索Google A2A代理卡的标准化机制。这实现了动态代理交互,特别是对于利用A2A协议的规划和编排代理。
背景
A2A协议
代理到代理(A2A)协议规范了代理之间的运行时通信。它定义了:
- 代理卡: 描述代理身份、功能(动作/功能)和交互端点的JSON模式。
- 消息格式和交互流程: 例如
ExecuteTask用于直接的代理间交互。
模型上下文协议(MCP)
MCP为应用程序(包括AI模型)定义了一种发现、访问和利用上下文信息的标准方式,称为“工具”、“资源”等。
核心提案
核心思想是使用MCP服务器作为A2A代理卡的集中式可查询存储库。
存储代理卡
- 每个A2A代理卡(JSON)都被存储(例如,作为JSON文件)。
- MCP服务器将这些代理卡作为资源公开。
- 底层存储系统可以是文件系统、数据库甚至矢量存储。此示例使用存储在文件系统中的代理卡,生成嵌入并使用它们来查找匹配项。
通过MCP发现代理
- 客户端查询MCP服务器的资源API(
list_resources)以发现可用的代理卡。 - 可以使用附加元数据(例如。,
streaming支持,标签如currency conversion),尽管本示例中没有明确涵盖。
检索代理卡
- 请求代理使用资源URI(从发现中获得)通过MCP服务器API获取完整的JSON代理卡。
为任务寻找代理
- 请求代理可以使用MCP服务器上公开的工具为特定查询找到最相关的代理。
启动A2A通信
- 一旦检索到代理卡,发出请求的代理就会在A2AClient中使用它们。
- 需要合作者的代理(如规划代理)然后使用标准A2A协议直接与目标代理通信。
- 发现后,MCP不参与这种直接的运行时交互。
用例:编排任务执行
该系统支持专业代理动态协作的工作流。
核心概念
- 编排: 计划器和执行器代理管理用户查询的整体流程。
- 专业化: 任务代理是特定类型任务的专家。
- 动态发现: MCP服务器允许灵活添加、删除或更新任务代理,而无需修改执行器。
- 标准化沟通: A2A协议确保了可靠的代理间通信。
建筑构件
- 用户界面(UI)/应用程序网关: 用户查询的入口点。
- 编排器代理:
- 从Planner Agent接收结构化计划。
- 迭代任务。
- 对于每项任务:
- 向MCP服务器查询合适的基于任务代理的任务(其他功能)。
- 通过A2A连接并向任务代理发送任务详细信息。
- 通过A2A从任务代理接收结果。
- 管理任务状态和错误。
- 验证结果,并可能根据需要触发重新规划。
- 将结果综合、总结并格式化为连贯的用户响应。
- 规划师代理:
- 接收原始用户查询。
- 将查询分解为结构化的任务计划(可能是DAG),为每个任务指定所需的功能。
- 模型上下文协议(MCP)服务器:
- 充当任务代理的注册表,托管其代理卡。
- 为执行器代理提供查询代理的接口。
- 为执行器代理提供查询工具的接口。
- 任务代理(池/舰队):
- 独立的专业代理(例如搜索代理、计算代理)。
- 暴露A2A兼容端点。
- 执行任务并通过A2A将结果返回给执行器。
- A2A通信层: 代理间通信的底层协议。
flowchart LR
subgraph s1["User Facing Layer"]
UI["User Interface / Gateway"]
end
subgraph s3["Agent / Tool Discovery"]
MCP["MCP Server (Agent / Tool Registry)"]
end
subgraph s4["Task Execution Layer"]
T1["Task Agent 1 (e.g., Air Tickets)"]
T2["Task Agent 2 (e.g., Hotel Reservation)"]
T3["Task Agent N (e.g., Car Rental Reservation)"]
end
UI --> E["Orchestrator Agent"]
E --> P["Planner Agent"] & MCP & A["Summary Agent"] & T1 & T2 & T3 & UI
T2 --> E & MCP
T3 --> E & MCP
T1 --> MCP
T1:::taskAgent
T1:::Sky
T2:::taskAgent
T2:::Sky
T3:::taskAgent
T3:::Sky
classDef taskAgent fill:#f9f,stroke:#333,stroke-width:2px
classDef a2aLink stroke-width:2px,stroke:#0077cc,stroke-dasharray: 5 5
classDef Sky stroke-width:1px, stroke-dasharray:none, stroke:#374D7C, fill:#E2EBFF, color:#374D7C
示例流程:旅行社
- 用户请求旅行计划。
- 编排器代理 接收请求。
- 查找 规划师代理的卡通过MCP连接。
- 调用Planner Agent以获取详细的计划。
- 对于计划中的每一步:
- 调用MCP工具(例如。,
find_agent)获取最佳任务代理的代理卡。 - 通过A2A调用所选的任务代理以执行任务:
- 机票: 任务代理将使用MCP服务器中的辅助工具。该工具查询SQLLite数据库以查找航班。
- 酒店: 任务代理将使用MCP服务器中的辅助工具。 该工具查询SQLLite数据库以查找酒店。
- 租车: 任务代理将使用MCP服务器中的辅助工具。 该工具查询SQLLite数据库以查找租车。
- 将结果存储在内存中
- 调用MCP工具(例如。,
- 汇总结果并为客户进行总结。
- 如果代理发现预算不匹配或预订失败,则会启动重新规划任务。
执行示例的步骤
此示例是使用3个ADK代理执行任务和一个充当计划器的LangGraph代理构建的。 所有3个ADK代理都使用相同的python代码,但使用不同的代理卡实例化。
您可以执行以下命令在一个终端中运行所有步骤:
bash samples/python/agents/a2a_mcp/run.sh
-
启动MCP服务器:
cd samples/python/agents/a2a_mcp uv venv # (if not already done) source .venv/bin/activate # Runs on port 10100 by default, change as needed by setting the --host and --port parameters. uv run --env-file .env a2a-mcp --run mcp-server --transport sse -
启动编排器代理:
在新的终端窗口中
cd samples/python/agents/a2a_mcp uv venv # (if not already done) source .venv/bin/activate # Note: Change the host and port as needed. uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/orchestrator_agent.json --port 10101 -
启动Planner Agent:
在新的终端窗口中
cd samples/python/agents/a2a_mcp uv venv # (if not already done) source .venv/bin/activate # Note: Change the host and port as needed. uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/planner_agent.json --port 10102 -
启动航空公司票务代理:
在新的终端窗口中
cd samples/python/agents/a2a_mcp uv venv # (if not already done) source .venv/bin/activate # Note: Change the host and port as needed. uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/air_ticketing_agent.json --port 10103 -
启动酒店预订代理:
在新的终端窗口中
cd samples/python/agents/a2a_mcp uv venv # (if not already done) source .venv/bin/activate # Note: Change the host and port as needed. uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/hotel_booking_agent.json --port 10104 -
启动租车预订代理:
在新的终端窗口中
cd samples/python/agents/a2a_mcp uv venv # (if not already done) source .venv/bin/activate # Note: Change the host and port as needed. uv run --env-file .env src/a2a_mcp/agents/ --agent-card agent_cards/car_rental_agent.json --port 10105 -
启动cli:
在新的终端窗口中
cd samples/python/agents/a2a_mcp uv venv # (if not already done) source .venv/bin/activate uv run --env-file .env src/a2a_mcp/mcp/client.py --resource "resource://agent_cards/list" --find_agent "I would like to plan a trip to France."
文件/目录说明
-
agent_cards/:此目录存储每个A2A代理卡的JSON模式。这些卡定义了系统中不同代理的身份、功能和端点。MCP服务器为这些卡提供服务。*_agent.json:每个JSON文件表示特定代理的卡(例如。,air_ticketing_agent.json对于处理航班预订的代理)。
-
src/a2a_mcp/:此A2A和MCP示例的主要Python源代码。agents/:包含设计文档中描述的不同类型代理的Python实现。__main__.py:启动代理服务的主脚本。adk_travel_agent.py:这是使用ADK构建的核心旅行代理,使用不同的代理卡来实例化代理。langgraph_planner_agent.py:使用LangGraph实现“Planner Agent”,负责将用户请求分解为结构化计划。orchestrator_agent.py:实现“编排器代理”,从计划器中获取计划,通过MCP发现适当的任务代理,并使用A2A调用它们。
common/:保存多个代理或系统部分使用的共享代码。agent_executor.py:一个A2A模块,用于管理编排流中任务的状态、依赖关系和执行。agent_runner.py:用于运行ADK代理实例、管理其生命周期和公开其服务的实用程序或框架组件。base_agent.py:一个抽象基类或接口,定义此项目中所有代理的通用方法和属性。prompts.py:包含用于与代理内的大型语言模型(LLM)交互的预定义提示模板(例如,用于计划或总结)。types.py:定义项目中使用的自定义Python数据类型、Pydantic模型或枚举(例如,用于表示任务、代理卡结构或API请求/响应)。utils.py:通用实用函数的集合。workflow.py:管理流程的工作流。
mcp/:包含与模型上下文协议相关的实现。client.py:一个辅助MCP客户端库,用于向MCP服务器查询代理卡或工具。这是一个测试工具,代理不使用。server.py:MCP服务器本身的实现。此服务器将代理卡作为资源托管。
-
travel_agency.db:承载演示数据的轻量级SQLLite数据库。
免责声明
重要提示:提供的示例代码仅用于演示,说明了代理到代理(A2A)协议的机制。在构建生产应用程序时,将任何在您直接控制之外运行的代理视为潜在的不受信任的实体至关重要。
从外部代理接收到的所有数据,包括但不限于其AgentCard、消息、工件和任务状态,都应作为不受信任的输入进行处理。例如,恶意代理可以提供一个AgentCard,其字段中包含精心编制的数据(例如描述、名称、技能描述)。如果未经净化就使用此数据来构建大型语言模型(LLM)的提示,则可能会使您的应用程序暴露于提示注入攻击。在使用前未能正确验证和清理这些数据可能会给您的应用程序带来安全漏洞。
开发人员负责实施适当的安全措施,如输入验证和安全处理凭据,以保护他们的系统和用户。