04:具有多个MCP服务器的代理 目标:学习如何配置单个OpenAI代理,以同时连接到多个MCP服务器并使用其中的工具。
🧪 本模块实际涵盖的内容 该子模块提供:
用于多MCP集成的Python脚本 模拟或模拟MCP服务器配置 与跨这些服务器托管的工具进行交互的代理 深入了解错误处理、服务器隔离和可扩展性 示例跟踪:这两个工具都位于由使用OpenAI代理SDK创建的代理调用的单独服务器上。
🧠 用例和优势 🔌 分布式工具集:访问跨不同MCP服务器托管的工具,例如一个用于天气,一个用于财务。 🧱 模块化架构:单个团队可以独立托管他们的工具,同时公开标准MCP接口。 📈 可扩展性和弹性:负载可以在MCP之间分布;一台服务器停机不一定会阻止代理功能。 🌐 第三方集成:任何公开MCP兼容端点的外部服务都可以无缝添加。 ⚙️ 配置和要求 代理的mcp_servers参数接受活动mcp客户端实例的列表。 每个客户端都应该通过MCPServerStreamableHttpParams进行配置,并在AsyncExitStack内进行管理。 ✅ 推荐异步模式 导入异步 从contextlib导入AsyncExitStack 从agents.mcp导入MCPServerStreamableHttp、MCPServerStreamtableHttp参数 从代理导入代理、AsyncOpenAI、OpenAIChatCompletionsModel、Runner
定义所有MCP服务器URL
MCP_SERVER_URLS=\[ "http://localhost:8001/mcp", "http://localhost:8002/mcp", \]
设置客户端(例如,兼容OpenAI/Gemini)
客户端=异步OpenAI( api_key=“你的api密钥”, base_url=“https://your-base-url", )
异步定义main(): mcpservers=\[\]
async with AsyncExitStack() as stack:
for url in MCP_SERVER_URLS:
mcp_params = MCPServerStreamableHttpParams(url=url)
mcp_server_client = await stack.enter_async_context(
MCPServerStreamableHttp(params=mcp_params, name=f"MCPClient_{url}")
)
mcp_servers.append(mcp_server_client)
assistant = Agent(
name="MultiMCPAgent",
instructions="You are a multi-server agent.",
mcp_servers=mcp_servers,
model=OpenAIChatCompletionsModel(model="gemini-2.0-flash", openai_client=client),
)
result = await Runner.run(assistant, "Get today's weather and Tesla stock price.")
print(f"[AGENT RESPONSE]: {result.final_output}")asyncio.run(main()) 🚀 逐步运行示例 要运行示例并查看代理连接到多个MCP服务器:
启动MCP服务器:您需要运行两个MCP服务器:一个用于情绪,一个用于天气。这些服务器位于此示例模块(04_agent_with_multiple_mcp_servers)中的mcp_servers子目录中。打开两个单独的端子。
Mood Server(在端口8001上运行):在您的第一个终端中,导航到mcp_servers目录: cd mcp服务器 uv运行python moodserver.py 此服务器提供mood_from_shared_server工具。 天气服务器(在端口8002上运行):在您的第二个终端中,也导航到mcp_servers目录: cd mcp服务器 uv运行python weather_server.py 此服务器提供了一个get_forecast工具。 确保两台服务器都成功启动。他们将把信息记录到各自的终端上(例如,“信息:Uvicorn正在运行http://0.0.0.0:8001(按CTRL+C退出)“)。您可以让这些终端保持运行。
配置环境变量:位于agent_connect/main.py中的代理代码(在此示例模块中)通过AsyncOpenAI为Gemini模型使用API键。
导航到agent_connect子目录。 如果.env文件不存在,请创建一个.env文件(例如agent_connect/.env)。 将您的GEMINI_API_KEY添加到此文件: GEMINI_API_KEY=“您的_实际\_ API_KEY_here” main.py脚本也配置用于LangSmith跟踪。如果要使用LangSmith,请确保已设置了LANGCHAIN_API_KEY、LANGCHAIN_TRACING_V2=“true”和LANGCHAIN_PROJECT=“your-PROJECT-name”环境变量(例如,在同一.env文件或shell环境中)。 运行代理:如果您还没有,请从该示例模块的根目录(04_Agent_with_multiple_mcp_servers)导航到Agent_connect子目录:
cd代理连接 然后,运行主代理脚本:
uv运行python main.py 代理将尝试连接到两个MCP服务器,聚合它们的工具(mood_from_shared_server和get_forecast),然后处理类似“Junaid的心情怎么样,伦敦的天气怎么样?”这样的查询。您应该在终端中看到输出,指示代理的交互(包括由MCP服务器客户端名称标识的工具调用)及其最终响应。
观察跟踪(可选但推荐):由于agent_connect/main.py配置了OpenAIAgentsTracingProcessor(使用typing.cast进行linter兼容性),如果您的LangSmith环境变量设置正确:
您可以在LangSmith中导航到您的项目,以查看代理执行的详细跟踪。 此跟踪将清楚地显示代理的决策过程、调用了哪些工具、哪个MCP服务器处理了每个调用(可通过客户端名称识别,如MCPServerClient_http://localhost:8001/mcp),以及流经系统的数据。这对于调试、理解多MCP交互以及验证来自不同服务器的工具是否被正确使用来说是非常宝贵的。 🧰 聚合工具管理 当代理连接到多个MCP服务器时,它会将工具集聚合到一个逻辑注册表中。 LLM对agent.tools的调用或决策会自动考虑来自所有MCP来源的所有工具。 🚨 工具名称唯一性和冲突处理 重要提示:工具名称在所有连接的MCP中必须是唯一的。
冲突(例如,两个get_weather工具)可能会导致不可预测的行为,具体取决于内部解决顺序。
最佳实践:使用命名空间或前缀约定,如:
财务_股票_价格 天气预报 SDK目前不会自动解决这些冲突,这是开发人员的责任。
