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,效果如下:

相关推荐
linqiw6 小时前
Embabel 上手:Java Agent 是怎么干活的
agent
大模型真好玩9 小时前
DeepSeek Harness 入门很简单(三)——DeepSeek Harness接入工具、MCP、Skill
人工智能·agent·deepseek
linweidong10 小时前
中科闻歌Java面试题及参考答案
java·python·大模型·提示词·ai agent·mcp·rag原理
枫彩13 小时前
A股数据源怎么选?用 Python 验收 AI 复盘的日期与明细
python·ai agent·股票数据·mcp
阿里云云原生14 小时前
Agent 观测与优化开发者摸底报告
云原生·agent
阿里云大数据AI技术14 小时前
使用 PAI,一键拉起云端 AI “投资智囊团”
人工智能·agent
四六的六14 小时前
让 AI 自己去点后台页面,它把我们的库存点没了
前端·人工智能·agent·个人开发·ai编程·ai产品·ai前端
苏灿烤鱼14 小时前
给 AI Agent 装一个「会进化的大脑」:OpenViking 深度拆解
开源·github·agent
武子康14 小时前
Agent 的工具没变,SGLang 缓存为什么没命中?
人工智能·llm·agent