将大语言模型的能力延伸到真实场景,一直是构建AI Agent所面临的核心挑战。近期,OpenAI在Agents SDK中引入了一个名为MCP的组件,值得深入探讨——它正逐步成为AI应用连接外部世界的标准化协议。

大语言模型(例如GPT-4)在文本理解与生成方面表现卓越,但本质上它们被困在数字化的信息孤岛中,无法直接与现实世界交互。如果你想通过Agent查询今日天气,或者更新项目管理系统中的任务状态,直接向它提出指令,它大概率会给出“无能为力”的回应——因为它既没有获取外部信息的“手”,也没有执行操作的“脚”。
过去要解决此问题,常见的做法是在应用代码中编写大量特定的函数,再通过提示工程或API调用的方式告知模型:当你需要查天气时,调用get_weather(city);当你需要读取文件时,调用read_file(path)。
这种硬编码的模式存在几个明显的短板:
- 紧密耦合:每个应用都需要自行编写一套工具对接逻辑,如同给每台电器配备专用插头,更换环境就可能无法使用。
- 灵活性不足:即便他人已开发出成熟的工具,想要使用仍需重新封装以适配你的Agent框架。
- 缺乏统一规范:各平台各自为政,没有公认的标准,导致工具交流与复用效率低下。
正是在这样的背景下,MCP应运而生。
MCP:AI应用的“USB-C接口”
MCP的全称为Model Context Protocol(模型上下文协议)。官方文档用一个生动的比喻诠释了它的作用:MCP就像是AI应用的USB-C接口。
回顾USB-C——一个标准接口,既能充电、传输数据,又能连接显示器及各类外设。无论苹果、安卓还是Windows设备,只要支持USB-C,众多配件就能通用。MCP的目标,正是为AI模型提供一套标准化的方式,使其能够连接各种不同的数据源与工具。
这套标准协议带来如下好处:
- 工具开发者可以开发符合MCP规范的服务(例如专门操作Notion的服务,或控制智能家居的服务),无需关心该服务最终被哪个具体的AI应用所调用。
- AI应用开发者(例如使用OpenAI Agents SDK的开发者)能够便捷地接入各类现成的MCP服务,为Agent“插上”多样化能力,无需为每个工具编写定制化的集成代码。
这相当于为你的AI Agent配备了一个“万能插座”——未来想要增加新功能,只需找到支持MCP的“电器”(工具服务),插上即可使用。
如何在OpenAI Agents SDK中运用MCP?
好消息是,OpenAI Agents SDK已经内置了对MCP的原生支持。你可以在创建Agent时,直接将MCP服务“挂载”上去。
目前,MCP规范定义了两种类型的服务,主要区别在于通信方式:
- stdio服务器:这类服务通常作为子进程在应用内部(本地)运行,通过标准输入/输出(stdin/stdout)进行通信。
- HTTP over SSE服务器:远程运行,通过URL连接,基于HTTP和Server-Sent Events进行通信。
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)
async def run_mcp_example():
# 配置并启动 MCP 文件系统服务
mcp_server_filesystem = MCPServerStdio(
params={
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", samples_dir],
}
)
# 用 async with 确保服务在退出时能被正确关闭
async with 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}")
import asyncio
asyncio.run(run_mcp_example())
这段代码的核心流程很清晰:
- 引入
MCPServerStdio。 - 定义要执行的命令:
npx -y @modelcontextprotocol/server-filesystem ./my_agent_files。 - 使用
async with管理服务生命周期,确保程序退出时服务能被干净地关闭。 - 在
with块中调用server.list_tools(),通过stdio向子进程询问:“你能做什么?把你所有的工具都列出来。” - 将获取到的工具列表打印出来,方便查看。
运行后,你会看到类似这样的输出:
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.
...
将MCP服务“连接”给Agent
仅启动服务还不够,关键在于如何让Agent使用它。在OpenAI Agents SDK中,你只需在创建Agent对象时,将之前创建的MCP服务实例放入mcp_servers列表中:
from openai_agents.agents import Agent
my_agent = Agent(
name="文件小助手",
instructions="请使用提供的工具来完成任务。",
mcp_servers=[mcp_server_filesystem],
)
当Agent运行时,SDK会自动完成以下几个步骤:
- 查询能力:它会遍历
mcp_servers列表中的每个服务,调用它们的list_tools()方法,收集所有可用的工具信息。 - 告知LLM:在构建给LLM的提示时,SDK会将从MCP服务收集到的工具信息一并告知LLM。
- 执行调用:如果LLM决定使用某个来自MCP服务的工具,SDK会捕捉到这个意图,并调用对应MCP服务的
call_tool()方法,传递LLM指定的参数。 - 返回结果:MCP服务执行完工具调用后,将结果返回给SDK,SDK再将该结果反馈给LLM,以便其继续思考或生成最终回复。
对整个开发者而言,这个过程是相对透明的——只需将MCP服务“注册”给Agent即可。

上图清晰展示了从用户发出指令,到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与直接编写Python工具函数的对比
OpenAI Agents SDK本身也支持直接定义Python函数作为工具,那么为何还要引入MCP?两者有何区别?
| 特性 | 直接定义Python函数 | 使用MCP服务 |
| 实现方式 | 在Python代码中直接编写函数,并通过特定方式注册给Agent | 连接到一个实现了MCP协议的独立服务 |
| 语言/环境 | 必须是Python,且通常运行在Agent应用的同一进程内 | 服务可用任何语言编写,可本地运行或远程部署 |
| 复用性 | 主要在当前应用内复用 | 非常高,任何支持MCP的应用或框架都可以接入 |
| 标准化 | 较低,依赖于特定Agent框架的实现 | 高,遵循开放的MCP协议 |
| 开发/接入成本 | 需要自行编写工具函数的具体逻辑 | 有现成服务时接入成本低,否则需要开发MCP服务 |
| 解耦性 | 工具逻辑与Agent应用代码耦合较紧密 | 工具服务与Agent应用解耦,可独立部署和扩展 |
如何选择?
- 如果工具逻辑较为简单、仅在当前Python应用中使用,或者需要访问应用内部状态,直接定义Python函数更加直接方便。
- 如果需要接入已有的、用其他语言编写、或需要独立部署维护的功能服务,并且希望该服务能被多个不同AI应用复用,MCP是非常理想的选择。
- 如果你想构建一个通用的工具平台,让他人能够便捷地接入你的能力,实现MCP协议是一个值得探索的方向。
调试与追踪
使用MCP服务后,如果Agent运行出现问题,该如何排查?OpenAI Agents SDK的追踪功能同样覆盖了MCP,它会自动记录与MCP相关的操作:
- 调用
list_tools()的过程。 - 当LLM决定调用某个MCP工具时,相关的函数调用信息(调用了哪个工具、传入了什么参数、返回了什么结果)。
这些追踪信息能帮助你清晰地了解SDK、LLM与MCP服务之间的交互过程,从而更便捷地定位问题。
总结
MCP的目标是成为AI应用连接外部工具和数据源的“通用标准接口”,类似于硬件世界中的USB-C。OpenAI Agents SDK对MCP的原生支持,让开发者能够更便捷地将各种符合规范的能力插件集成到Agent中,无论是本地运行还是远程调用。
MCP仍然是一个相对较新的概念,其生态系统也处于发展之中。但这一方向无疑是正确的,未来我们很可能会看到越来越多基于MCP的工具服务涌现。如果你对这个方向感兴趣,不妨查阅OpenAI Agents SDK文档中关于MCP的更多细节,或直接前往examples/mcp目录,运行官方提供的完整示例代码。亲手实践一番,感受会更直观。
