支持私有云部署
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


给你的 AI Agent 装个“万能插座”?聊聊 OpenAI Agents SDK 里的 MCP

发布日期:2025-03-27 16:49:43 浏览次数: 1626 来源:老码小张
推荐语

探索AI Agent的全新互动方式,OpenAI Agents SDK中的MCP如何成为AI应用的“USB-C”接口。

核心内容:
1. AI Agent与现实世界互动的挑战
2. MCP作为AI模型的标准化连接协议
3. MCP如何简化工具服务开发与AI应用集成

杨芳贤
53A创始人/腾讯云(TVP)最具价值专家

 

嘿,大家好,我是老码小张。

混迹技术圈有些年头了,相比追逐各种花里胡哨的新名词,我可能更喜欢钻研技术背后的那点儿门道,琢磨怎么用这些技术实实在在地解决点问题。最近 AI Agent 这阵风刮得挺猛,OpenAI 也推出了自家的 Agents SDK,我自然也去扒拉了一下,发现里面有个叫 MCP 的东西,挺有意思,今天就想跟大家唠唠这个。

你想啊,咱们现在用的大语言模型(LLM),像 GPT-4 这些,脑子确实聪明,能聊天能写文能写代码。但它们本质上还是被关在一个“数字黑箱”里,跟咱们现实世界或者具体的软件系统是隔离开的。你想让它帮你查查今天本地天气怎么样?或者去你的项目管理软件里更新个任务状态?直接跟它说,它大概率只能摊摊手,表示“臣妾做不到啊”。

为啥?因为它没有“手”和“脚”啊!它需要一些工具(Tools)或者说能力,才能跟外部世界互动。

过去我们怎么做呢?通常是在应用代码里写一堆特定的函数,然后通过各种提示工程(Prompt Engineering)或者特定的 API 调用方式,告诉 LLM:“嘿,当你需要查天气时,就调用这个 get_weather(city) 函数;当你需要读文件时,就用这个 read_file(path) 函数。”

这种方法不是不行,但有几个问题:

  1. 1. 定制化太强:每个应用都得自己写一套工具对接逻辑,有点像给每个电器都配一个专用插头,换个地方可能就用不了了。
  2. 2. 不够灵活:如果别人已经做了一个很牛的查数据库工具,你想用,可能还得自己重新封装一遍,适配你的 Agent 框架。
  3. 3. 标准缺失:各家搞各家的,没个统一的“说法”,交流和复用都挺麻烦。

这时候,MCP 就登场了。

MCP:AI 应用的“USB-C 接口”

MCP 全称是 Model Context Protocol,模型上下文协议。官方文档打了个很形象的比方:MCP 就像是 AI 应用的 USB-C 接口

想想 USB-C:一个标准接口,能充电、能传数据、能接显示器、能连各种外设。不管你是苹果、安卓还是 Windows 电脑,只要支持 USB-C,很多配件都能通用。

MCP 想做的,就是为 AI 模型(特别是 LLM)提供一个标准化的方式来连接不同的数据源和工具

有了这个标准协议,理论上:

  • • 工具开发者可以开发符合 MCP 规范的工具服务(比如一个专门操作 Notion 的服务,或者一个控制智能家居的服务),而不用太关心这个服务最终会被哪个具体的 AI 应用或 Agent 框架使用。
  • • AI 应用开发者(比如咱们用 OpenAI Agents SDK 的人)可以方便地接入各种现成的 MCP 工具服务,给自己的 Agent “插上”各种能力,而不需要为每种工具都写一堆定制的对接代码。

听起来是不是有点小激动?这就像给你的 AI Agent 配上了一个万能插座,以后想加什么新功能,只要找到支持 MCP 的“电器”(工具服务),插上就行了。

OpenAI Agents SDK 怎么玩转 MCP?

好消息是,OpenAI 的 Agents SDK 已经内置了对 MCP 的支持。这意味着咱们可以直接在创建 Agent 的时候,把 MCP 服务给“挂载”上去。

那么,MCP 服务具体长啥样呢?目前 MCP 规范定义了两种类型的服务,主要是通信方式不同:

  1. 1. stdio 服务器 (stdio servers):这种服务通常是作为一个子进程在你的应用程序内部运行的,可以理解为“本地运行”。通信方式是通过标准输入/输出(stdin/stdout)。
  2. 2. HTTP over SSE 服务器 (HTTP over SSE servers):这种服务是远程运行的,你需要通过一个 URL 去连接它。通信方式是基于 HTTP 和 Server-Sent Events (SSE)。

OpenAI Agents SDK 提供了两个对应的类来连接这两种服务器:MCPServerStdio 和 MCPServerSse

举个例子,假设你想让你的 Agent 能操作本地文件系统(读文件、写文件、列目录等)。正好,MCP 官方提供了一个基于 stdio 的文件系统服务。你可以这样把它跑起来并连接到你的 Python 代码里(这里用了 npx,通常是 Node.js 环境下的工具,它会帮你下载并运行 @modelcontextprotocol/server-filesystem 这个包):

import os
from openai_agents.mcp import MCPServerStdio
# 假设你的项目里有个叫 samples_dir 的目录
samples_dir = "./my_agent_files"
# 确保这个目录存在
os.makedirs(samples_dir, exist_ok=True

asyncdefrun_mcp_example():
    # 配置并启动 MCP 文件系统服务
    # command 指定用 npx
    # args 告诉 npx 去执行 @modelcontextprotocol/server-filesystem,
    # 并且把 samples_dir 作为工作目录传给它
    # -y 参数是告诉 npx 自动确认安装
    mcp_server_filesystem = MCPServerStdio(
        params={
            "command""npx",
            "args": ["-y""@modelcontextprotocol/server-filesystem", samples_dir],
        }
    )

    # 使用 async with 确保服务在退出时能被正确关闭
    asyncwith mcp_server_filesystem as server:
        print("MCP 文件系统服务已启动...")
        
        # 我们可以尝试手动列出它提供的工具
        tools = await server.list_tools()
        print("文件系统服务提供的工具:")
        for tool in tools:
            print(f"- {tool.function.name}{tool.function.description}")
            
        # 这里只是演示如何启动和列出工具,
        # 后面会展示如何把它集成到 Agent 中

# 如果你在异步环境运行,可以直接 await run_mcp_example()
# 如果在同步环境,可以用 asyncio.run(run_mcp_example())
import asyncio
asyncio.run(run_mcp_example())

上面这段代码干了啥?

  1. 1. 引入了 MCPServerStdio
  2. 2. 定义了要跑的命令:npx -y @modelcontextprotocol/server-filesystem ./my_agent_files。这行命令会启动一个本地的 MCP 服务,专门用来操作 ./my_agent_files 这个目录下的文件。
  3. 3. 用 async with 来管理这个服务的生命周期,确保程序退出时服务也能干净地关掉。
  4. 4. 在 with 块里,我们调用了 server.list_tools(),这个方法会通过 stdio 去问那个子进程:“嘿,你能干啥呀?把你所有的工具(能力)都报上来。”
  5. 5. 然后我们把获取到的工具列表打印出来看看。

跑起来之后,你可能会看到类似这样的输出:

MCP 文件系统服务已启动...
文件系统服务提供的工具:
- filesystem.readFile: Reads the content of a file.
- filesystem.writeFile: Writes content to a file.
- filesystem.listFiles: Lists files and directories in a given path.
... (可能还有其他工具)

看,这个文件系统服务告诉我们,它能读文件 (readFile)、写文件 (writeFile)、列文件 (listFiles) 等。

把 MCP 服务“插”给 Agent

光启动服务还不够,关键是怎么让 Agent 用起来。在 OpenAI Agents SDK 里,这事儿很简单。你只需要在创建 Agent 对象的时候,把刚才创建的 mcp_server_filesystem 实例(或者其他 MCP 服务实例)放进 mcp_servers 列表里就行了:

from openai_agents.agents import Agent
# (假设 mcp_server_filesystem 已经在前面定义好了)
# 假设还有另一个 MCP 服务叫 mcp_server_other

# 创建 Agent 时,把 MCP 服务列表传进去
my_agent = Agent(
    name="文件小助手",
    instructions="请使用提供的工具来完成任务。",
    # 把所有想让这个 Agent 使用的 MCP 服务都放在这个列表里
    mcp_servers=[mcp_server_filesystem, 
                 # mcp_server_other # 如果有其他服务,也加进来
                ] 
)

# 接下来就可以运行这个 Agent 了
# result = await my_agent.run("请帮我读取 my_agent_files 目录下的 welcome.txt 文件内容。")
# print(result.get_text()) 

当 my_agent 运行时,Agents SDK 会自动干几件事:

  1. 1. 询问能力:它会去找 mcp_servers 列表里的每个服务,调用它们的 list_tools() 方法,把所有可用的工具都收集起来。
  2. 2. 告知 LLM:在构建给 LLM 的提示(Prompt)时,SDK 会把这些从 MCP 服务收集来的工具信息(名称、描述、参数等)一并告诉 LLM。
  3. 3. 执行调用:如果 LLM 在思考后决定要使用某个来自 MCP 服务的工具(比如决定调用 filesystem.readFile),Agents SDK 会捕捉到这个意图,然后调用对应 MCP 服务的 call_tool() 方法,并把 LLM 指定的参数传过去。
  4. 4. 返回结果:MCP 服务执行完工具调用后,会把结果返回给 SDK,SDK 再把这个结果喂给 LLM,让它继续下一步思考或生成最终回复。

整个过程对我们开发者来说是比较透明的,我们只需要把 MCP 服务“注册”给 Agent 就行了,底层的通信和调用细节 SDK 都帮你处理了。

这个图清晰地展示了从用户发出指令,到 SDK 如何协调 LLM 和 MCP 服务,最终完成任务的整个流程。

性能小贴士:工具列表缓存

你可能注意到了,每次运行 Agent 时,SDK 都会调用 list_tools()。如果你的 MCP 服务是个远程服务(HTTP over SSE 类型),或者 list_tools() 本身比较耗时,这可能会带来一点延迟。

如果你的 MCP 服务提供的工具列表是相对固定的(比如那个文件系统服务,它的能力基本不会变),你可以在创建 MCPServerStdio 或 MCPServerSse 对象时,加上 cache_tools_list=True 这个参数:

mcp_server_filesystem = MCPServerStdio(
    params={...},
    cache_tools_list=True # 开启工具列表缓存
)

这样设置后,SDK 只会在第一次运行时调用 list_tools(),之后就会直接使用缓存的结果,能省下不少时间。

当然,如果你知道 MCP 服务的工具列表发生了变化(比如服务更新了,增加了新工具),你需要手动让缓存失效,可以调用服务对象的 invalidate_tools_cache() 方法。

MCP vs. 直接写 Python 工具函数

你可能会问,既然 OpenAI Agents SDK 本身也支持直接定义 Python 函数作为工具,为啥还要搞个 MCP 呢?它们有啥区别?

简单做个对比:

特性
直接定义 Python 函数
使用 MCP 服务 via SDK
实现方式
在你的 Python 代码里直接写函数,并用特定方式注册给 Agent
连接到一个实现了 MCP 协议的独立服务
语言/环境
必须是 Python,且通常运行在 Agent 应用的同一进程内
服务可以用任何语言编写,可以本地运行,也可以远程部署
复用性
主要在当前应用内复用
非常高,任何支持 MCP 的应用/框架都可以接入
标准化
低,依赖于特定 Agent 框架的实现
高,遵循开放的 MCP 协议
开发/接入成本
需要自己编写工具函数的具体逻辑
如果有现成服务,接入成本低;否则需要开发 MCP 服务
解耦性
工具逻辑与 Agent 应用代码耦合较紧
工具服务与 Agent 应用解耦,可独立部署和扩展

怎么选?

  • • 如果你的工具逻辑比较简单,只在当前 Python 应用中使用,或者需要访问应用内部的状态,那么直接定义 Python 函数可能更直接方便。
  • • 如果你需要接入一个已有的、用其他语言编写的、或者需要独立部署维护的功能服务,并且希望这个服务能被多个不同的 AI 应用(可能用了不同的 Agent 框架)复用,那么 MCP 是一个非常理想的选择。
  • • 如果你想构建一个通用的工具平台,让别人能方便地接入你的能力,实现 MCP 协议是个不错的方向。

调试与追踪

当你用了 MCP 服务后,如果 Agent 运行出了问题,怎么排查呢?别担心,OpenAI Agents SDK 的追踪(Tracing)功能也考虑到了 MCP。它会自动记录跟 MCP 相关的操作,比如:

  • • 调用 list_tools() 的过程。
  • • 当 LLM 决定调用某个 MCP 工具时,相关的函数调用信息(调了哪个工具,传了什么参数,返回了什么结果)。

这些追踪信息能帮你搞清楚在 SDK、LLM 和 MCP 服务之间到底发生了什么,定位问题会方便很多。

说了这么多

好啦,关于 OpenAI Agents SDK 里的 MCP,今天就先跟大家聊这么多。

简单来说,MCP 就是想做 AI 应用连接外部工具和数据源的那个“通用标准接口”,有点像我们硬件世界的 USB-C。OpenAI Agents SDK 对 MCP 的支持,让我们可以更方便地把各种符合规范的“能力插件”(MCP 服务)集成到我们的 Agent 里,不管是本地跑的还是远程调用的。这为构建功能更强大、更灵活、也更开放的 AI Agent 打开了一扇新的大门。

当然,MCP 还是个相对较新的东西,生态也还在发展中。但我觉得这个方向是对的,未来可能会看到越来越多基于 MCP 的工具服务涌现出来。

如果你对这个感兴趣,不妨去看看 OpenAI Agents SDK 文档里关于 MCP 的更多细节,或者直接去 examples/mcp 目录下跑跑官方提供的完整示例代码。亲自上手试一试,感觉会更真切!

我是老码小张,一个喜欢扒拉技术细节的普通技术人。希望今天的分享对你有启发!下次有机会再跟大家聊聊其他有意思的技术话题。回见!


 

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询