Agents SDK+MCP智能体开发

2025年3月27号,Agents SDK正式官宣支持MCP使用,这也使得Agents SDK的实际应用场景得到拓展。

现在,我们仅需在创建Agent的时候,将MCP服务器视作为一项工具,即可顺利调用MCP服务器进行Agent开发。换而言之,就是如果使用Agents SDK作为Agent开发框架,则可以零门槛快速接入MCP海量服务器生态。

一、Agents SDK + MCP基础调用流程(单个MCP服务 + stdio模式)

我们接下来使用高德天气查询API开发一个MCP服务,并将其作为工具在Agents中调用。

环境准备

需先安装如下依赖

  • pip install openai-agents
  • pip install mcp
  • pip install httpx
  • pip install python-dotenv

开发高德天气查询MCP server端

新建weather_server.py文件代码如下,

python 复制代码
#weather_server.py
import json
import httpx
from typing import Any
from mcp.server.fastmcp import FastMCP
from dotenv import load_dotenv
import os

# 从 .env 文件加载环境变量
load_dotenv()

# 初始化 MCP 服务器
mcp = FastMCP("WeatherServer")

async def fetch_weather(city: str) -> dict[str, Any] | None:
    """
    从 高德天气查询API 获取天气信息。
    :param city: 城市编码(城市adcode,如 110101)
    :return: 天气数据字典;若出错返回包含 error 信息的字典
    """

    #高德天气查询 API 配置
    BASE_URL = "https://restapi.amap.com/v3/weather/weatherInfo"
    API_KEY = os.getenv('AMAP_API_KEY')  # 获取环境变量中的高德API Key,也可直接替换成自己的高德API Key
    
    params = {
        "city": city,
        "key": API_KEY,
        "extensions": "base", # base:返回实况天气; all:返回预报天气
        "output": "JSON"
    }

    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(BASE_URL, params=params, timeout=30.0)
            response.raise_for_status()
            return response.json()  # 返回字典类型
        except httpx.HTTPStatusError as e:
            return {"error": f"HTTP 错误: {e.response.status_code}"}
        except Exception as e:
            return {"error": f"请求失败: {str(e)}"}

def format_weather(data: dict[str, Any] | str) -> str:
    """
    将天气数据格式化为易读文本。
    :param data: 天气数据(可以是字典或 JSON 字符串)
    :return: 格式化后的天气信息字符串
    """
    # 如果传入的是字符串,则先转换为字典
    if isinstance(data, str):
        try:
            data = json.loads(data)
        except Exception as e:
            return f"无法解析天气数据: {e}"

    # 如果数据中包含错误信息,直接返回错误提示
    if "error" in data:
        return f"⚠️ {data['error']}"

    # 列表可能为空,因此用 [0] 前先提供默认字典
    lives_list = data.get("lives", [{}])
    live_data = lives_list[0]
    
    # 提取数据时做容错处理
    province = live_data.get("province", "未知")
    city = live_data.get("city", "未知")
    weather = live_data.get("weather", "未知")
    temperature = live_data.get("temperature", "N/A")
    humidity = live_data.get("humidity", "N/A")
    winddirection = live_data.get("winddirection", "未知")
    windpower = live_data.get("windpower", "N/A")

    return (
        f"🌍 {province}, {city}\n"
        f"🌤 天气: {weather}\n"
        f"🌡 温度: {temperature}°C\n"
        f"💧 湿度: {humidity}%\n"
        f"🌬 风速: {winddirection}风, {windpower}级\n"
    )

@mcp.tool()
async def query_weather(city: str) -> str:
    """
    输入指定城市的城市编码(城市adcode,如 110101),返回今日天气查询结果。
    :param city: 城市编码(城市adcode,如 110101)
    :return: 格式化后的天气信息
    """
    data = await fetch_weather(city)
    return format_weather(data)

if __name__ == "__main__":
    # 以标准 I/O 方式运行 MCP 服务器
    mcp.run(transport='stdio')

使用Agents SDK创建Agents并与MCP服务通信。

在新版的Agents SDK中,Agents SDK可以将某个对应的Agent封装为client,并外部定义好的server进行通信。

新建run_agent_weather.py文件,代码如下:

python 复制代码
# ------------------------------
#     查询天气单MCP工具Agent
# ------------------------------
from openai import AsyncOpenAI
from agents import OpenAIChatCompletionsModel, Agent, Runner, set_default_openai_client
from agents.mcp import MCPServerStdio, MCPServerStdioParams
import asyncio
import os
import logging
# pip install python-dotenv
from dotenv import load_dotenv
import os

# 从 .env 文件加载环境变量
load_dotenv()

# 完全禁用所有日志
logging.getLogger().setLevel(logging.CRITICAL)

# 自定义模型对象
external_client = AsyncOpenAI(
    base_url="https://api.deepseek.com",
    api_key=os.getenv('DEEPSEEK_API_KEY'), 
)
# 设置默认模型
set_default_openai_client(external_client)

# 创建模型对象
deepseek_model = OpenAIChatCompletionsModel(
    openai_client=external_client,
    model="deepseek-chat"
)

# 定义mcp连接和agent调用函数
async def run_with_mcp_detailed():
    """详细调试 MCP 连接过程"""
    try:
        print("步骤1: 创建 MCP Server的连接参数...")
        stdio_params = MCPServerStdioParams(
            command="python",
            #mcp server对应的文件路径
            args=["weather_server.py"]
        )
        print("✓ 参数创建成功")
        
        print("步骤2: 创建 MCP Server 实例对象...")
        mcp_server = MCPServerStdio(
            #mcp server的自定义名称(叫啥都行)
            name="Weather Server",
            params=stdio_params,
            cache_tools_list=True
        )
        print("✓ MCPServerStdio 实例创建成功")
        
        print("步骤3: 连接mcp server...")
        async with mcp_server as server:
            print("✓ MCP 服务器连接成功")
            
            print("步骤4: 创建 Agent...")
            agent = Agent(
                name="Assistant",
                instructions="你是一名助人为乐的助手,可以使用天气查询工具帮助用户查询天气。请使用get_weather工具来查询天气信息。请根据用户想要查询的地区选择最合适的城市编码,无需要用户二次确认",
                mcp_servers=[server], #指定给当前agent绑定的mcp server(外部工具)
                model=deepseek_model
            )
            print("✓ Agent 创建成功")

            print("步骤5: 运行agent...")
            message = "请帮我查询上海今天天气如何?"
            print(f"用户提问: {message}")
            result = await Runner.run(starting_agent=agent, input=message)
            print(f"助手回复: {result.final_output}")
            
    except Exception as e:
        print(f"❌ 错误发生在: {e}")
        import traceback
        traceback.print_exc()

# 运行
if __name__ == "__main__":
    # 运行主程序
    asyncio.run(run_with_mcp_detailed())

执行天气查询 Agent

在cmd中执行命令python run_agent_weather.py,效果如下:

二、Agents SDK 接入多个MCP服务器

理论上,一个MCP服务器能同时运行多个外部函数,而一个MCP Client则可以连接多个MCP服务器。

如何将Agents SDK同时接入多个MCP服务器?

这里我们写一个同时可"查询天气"并把"内容写入本地"的多MCP服务的Agents。 "天气查询"MCP服务还使用上面的代码,这里新写一个"内容写入本地"的伪代码示例MCP服务。

新建write_server.py文件,代码如下:

python 复制代码
import json
import httpx
from typing import Any
from mcp.server.fastmcp import FastMCP

# 初始化 MCP 服务器
mcp = FastMCP("WriteServer")
USER_AGENT = "write-app/1.0"

@mcp.tool()
async def write_file(content: str) -> str:
    """
    将指定内容写入本地文件。
    :param content: 必要参数,字符串类型,用于表示需要写入文档的具体内容。
    :return:是否成功写入
    """
    # 实现一个伪写文件方法
    return "已成功写入本地文件。"

if __name__ == "__main__":
    # 以标准 I/O 方式运行 MCP 服务器
    mcp.run(transport='stdio')

使用Agents SDK创建Agents并连接多个MCP服务。

新建run_agent_multiTool.py文件,代码如下:

python 复制代码
# --------------------------------
#  查询天气并写入信息多MCP工具Agent
# --------------------------------
from openai import AsyncOpenAI
from agents import OpenAIChatCompletionsModel, Agent, Runner, set_default_openai_client
from agents.mcp import MCPServerStdio, MCPServerStdioParams
import asyncio
import os
import logging
# pip install python-dotenv
from dotenv import load_dotenv
import os

# 从 .env 文件加载环境变量
load_dotenv()

# 完全禁用所有日志
logging.getLogger().setLevel(logging.CRITICAL)

# 自定义模型对象
external_client = AsyncOpenAI(
    base_url="https://api.deepseek.com",
    api_key=os.getenv('DEEPSEEK_API_KEY'), 
)

# 设置默认模型
set_default_openai_client(external_client)

# 创建模型对象
deepseek_model = OpenAIChatCompletionsModel(
    openai_client=external_client,
    model="deepseek-chat"
)

# 定义mcp连接和agent调用函数
async def run_with_mcp_detailed():
    """详细调试 MCP 连接过程"""
    try:
        print("步骤1: 创建 MCP服务器参数...")
         # 创建天气服务器参数
        weather_params = MCPServerStdioParams(
            command="python",
            args=["weather_server_amap.py"]
        )
        # 创建写作服务器参数
        write_params = MCPServerStdioParams(
            command="python", 
            args=["write_server.py"]
        )
        print("✓ 参数创建成功")
        
        print("步骤2: 创建 MCP服务器实例...")
        weather_server = MCPServerStdio(
            params=weather_params,
            name="Weather Server",
            cache_tools_list=True
        )
        write_server = MCPServerStdio(
            params=write_params,
            name="Write Server", 
            cache_tools_list=True
        )
        print("✓ MCPServerStdio 实例创建成功")
        
        print("步骤3: 同时连接两个 MCP 服务器...")
        async with weather_server as ws, write_server as wrs:
            print("✓ 两个 MCP 服务器连接成功")
            
            print("步骤4: 创建 Agent(集成两个服务器的工具)...")
            agent = Agent(
                name="MultiTool Assistant",
                instructions="""你是一个多功能助手,可以同时使用天气查询和本地文档写入的能力。
你可以使用的工具包括:
1. 天气查询工具 - 查询全球城市的天气信息
2. 本地文档写入 - 帮助用户将相关数据写入本地文档进行保存
请根据用户的需求智能选择合适的工具:
- 当用户询问天气时,使用天气查询工具
- 当用户需要写入数据保存时,使用本地文档写入工具
- 如果用户的需求涉及多个方面,可以组合使用多个工具
- 如果不知道使用哪个工具,可以询问用户澄清""",
                mcp_servers=[ws, wrs],  # 传入两个服务器
                model=deepseek_model
            )
            print("✓ Agent 创建成功")

            print("步骤5: 运行查询...")
            message = "请帮我查询上海天气,并写入本地文档。"
            print(f"用户提问: {message}")
            result = await Runner.run(starting_agent=agent, input=message)
            print(f"助手回复: {result.final_output}")
            
    except Exception as e:
        print(f"❌ 错误发生在: {e}")
        import traceback
        traceback.print_exc()

# 运行
if __name__ == "__main__":
    # 运行主程序
    asyncio.run(run_with_mcp_detailed())

执行多MCP Agents

在cmd中执行命令python run_agent_multiTool.py,效果如下:

三、Agents SDK + MCP基础调用流程(单个MCP服务 + SSE模式)

以12306的MCP 服务器应用为例:新建文件run_agent_sse_12306.py,代码如下:

python 复制代码
from openai import AsyncOpenAI
from agents import OpenAIChatCompletionsModel, Agent, Runner, set_default_openai_client
import asyncio
import os
import logging
from agents.mcp import MCPServerSse
# pip install python-dotenv
from dotenv import load_dotenv
import os

# 从 .env 文件加载环境变量
load_dotenv()

# 完全禁用所有日志
logging.getLogger().setLevel(logging.CRITICAL)

# 自定义模型对象
external_client = AsyncOpenAI(
    base_url="https://api.deepseek.com",
    api_key=os.getenv('DEEPSEEK_API_KEY'), 
)
# 设置默认模型
set_default_openai_client(external_client)

# 创建模型对象
deepseek_model = OpenAIChatCompletionsModel(
    model="deepseek-chat",
    openai_client=external_client
)

# 定义mcp连接和agent调用函数
async def run_with_sse():
    """使用 SSE 传输方式"""
    try:#创建sse模式下的mcp server对象
        async with MCPServerSse(
            name="Train Server",
            params={
                #url就是mcp server配置信息中的链接地址。可从魔塔社区获取。
                "url": "https://mcp.api-inference.modelscope.net/ad61d61d2e7847/sse"
            }
        ) as server:
            
            agent = Agent(
                name="Assistant",
                instructions="你是一名车票查询的助手",
                mcp_servers=[server],
                model=deepseek_model
            )

            message = "帮我查询今天下午北京到上海的高铁余票信息"
            print(f"用户提问: {message}")
            result = await Runner.run(starting_agent=agent, input=message)
            print(f"助手回复: {result.final_output}")
            
    except Exception as e:
        print(f"SSE 错误: {e}")

# 运行
if __name__ == "__main__":
    # 运行主程序
    asyncio.run(run_with_sse())

在cmd中执行命令python run_agent_sse_12306.py,效果如下:

相关推荐
图图大恼4 小时前
在iOS上体验Open-AutoGLM:从安装到流畅操作的完整指南
人工智能·ios·agent
被制作时长两年半的个人练习生4 小时前
agent和知识库技术发展的一个可能性
大模型·agent·知识库
前端阿森纳5 小时前
破除大模型神话:4个关键问题揭示AI的真实边界
aigc·agent·ai编程
qq_386218996 小时前
Agent
人工智能·agent
KAI智习15 小时前
一张图看懂AI Agent的6种模式—MAS
人工智能·agent·多智能体·mas
李姆斯15 小时前
Agent时代下,ToB前端的UI和交互会往哪走?
前端·agent·交互设计
AI Echoes16 小时前
构建一个LangChain RAG应用
数据库·python·langchain·prompt·agent
DevYK18 小时前
Coze Studio 二次开发(二)支持 MCP Server 动态配置
后端·agent·coze
KotlinKUG贵州20 小时前
Kotlin/Ktor 实践:利用 MCP 从零打造 AI Agent 服务端指南
kotlin·agent·mcp