乐于分享
好东西不私藏

为什么 AI 的工具不能像 USB 一样即插即用?

为什么 AI 的工具不能像 USB 一样即插即用?

一句话:MCP 可以理解成 Agent 世界的"Type-C 接口"——它不保证完全零适配,但能显著减少工具跨平台集成成本。

划重点

  • Function Calling 的痛点:每换一个模型/平台,工具就得重新适配一遍
  • MCP(Model Context Protocol):Anthropic 提出的开放协议,让工具和模型之间有统一接口
  • 类比:Function Calling 是"专用充电线",MCP 是"Type-C 接口"
  • MCP 三个核心角色:Host(宿主)、Client(客户端)、Server(工具服务)
  • 实战:用 Python 写一个最小 MCP Server,接入 Claude Desktop

一个真实的痛点

假设你写了一个"查天气"工具。

用 OpenAI 的 Function Calling,你需要按 OpenAI 的格式定义 JSON Schema,注册到 tools 列表里。

现在老板说:换成 Claude。

你发现 Claude 的工具格式……跟 OpenAI 不一样。重写。

再换 DeepSeek?又不一样。再重写。

如果你有 10 个工具、3 个模型平台,你就需要维护 30 份适配代码。

公平地说,2025-2026 年各平台的 API 已经在趋同(很多都兼容 OpenAI SDK),没有早期那么碎片化了。但工具定义格式、消息结构、流式协议仍有差异——换平台不至于"完全重写",但总要改一轮适配代码。

MCP 的目标是把"跨模型工具适配"从大量重复工程,收敛为统一协议层的问题。 不能保证完全"零适配",但能显著减少重复工具集成成本。


MCP 是什么?

MCP(Model Context Protocol)是 Anthropic 在 2024 年底提出的开放协议。核心思想很简单:

在模型和工具之间加一层标准协议,让两边互不感知对方的实现细节。

类比:

没有 MCP
有 MCP
每个手机一根专用充电线
所有设备都用 Type-C
换模型就要改工具代码
工具写一次,兼容 MCP 的平台都能接入
10 工具 × 3 平台 = 30 份适配
10 工具 × 1 标准 = 10 份实现

更精确地说,MCP 更像 AI 世界的 LSP(Language Server Protocol)——统一能力声明和调用协议,让工具、模型、IDE 各自独立演进。USB 类比帮助理解,但 MCP 不涉及硬件级热插拔。


MCP 的架构:三个角色

┌──────────────────────────────────────────────┐│                   Host(宿主)                 ││    Claude Desktop / VS Code / 你的 App        ││                                              ││  ┌────────────┐    ┌────────────┐            ││  │  MCP Client │    │  MCP Client │  ...      ││  └─────┬──────┘    └─────┬──────┘            ││        │                  │                   │└────────┼──────────────────┼───────────────────┘         │                  │    ┌────▼─────┐      ┌────▼─────┐    │MCP Server│      │MCP Server│    │ (天气)    │      │ (数据库)  │    └──────────┘      └──────────┘

三个角色:

1. Host(宿主)

用户直接交互的应用——Claude Desktop、VS Code Copilot、你自己的 Agent 应用。Host 负责管理所有 MCP Client 的生命周期。

2. Client(客户端)

Host 内部的协议适配层。每个 Client 跟一个 Server 建立 1:1 连接。Client 负责把模型的工具调用请求翻译成 MCP 协议格式。

3. Server(工具服务)

暴露具体能力的服务。一个 Server 可以提供:

  • Tools(工具):模型可以调用的函数,比如查天气、发邮件
  • Resources(资源):模型可以读取的数据,比如文件内容、数据库记录
  • Prompts(提示模板):预定义的交互模板

MCP vs Function Calling:到底区别在哪?

维度
Function Calling
MCP
定义位置
工具定义与模型 SDK 强绑定
独立 Server 进程
复用性
换模型/平台要重写
写一次到处用
发现机制
手动注册 tools 列表
Server 自动声明能力
运行方式
工具定义与模型调用逻辑耦合
独立进程,通过 stdio/HTTP 通信
适合场景
单模型、少量工具
多模型、多工具、需要复用

关键区别在"谁拥有工具定义":

  • Function Calling:工具定义写在"调用模型的那段代码里",跟模型绑定
  • MCP:工具定义写在独立的 Server 里,任何兼容 MCP 的 Client 都能连上来发现和调用

这就像:

  • Function Calling = 你把打印机驱动写死在一个应用里,换电脑就不能用
  • MCP = 打印机自带驱动,任何电脑插上就能识别

实战:写一个最小 MCP Server

下面用 Python 写一个最简单的 MCP Server——提供一个"查天气"工具。

# weather_server.pyfrom mcp.server.fastmcp import FastMCPmcp = FastMCP("weather-server")@mcp.tool()defget_weather(city: str) -> str:"""查询指定城市的当前天气"""# 这里替换成真实 API 调用returnf"{city}:晴,28°C,湿度 45%"if __name__ == "__main__":    mcp.run()

这就是一个完整的 MCP Server。 大约 10 行代码。

FastMCP 是 MCP Python SDK 提供的高层封装,类似 FastAPI 对 WSGI 的抽象——你只需要用 @mcp.tool() 装饰器声明工具函数,SDK 自动处理能力声明、参数校验和通信协议。底层仍然是标准 MCP protocol。

它做了两件事:

  1. 声明工具:函数名就是工具名,docstring 就是描述,类型标注就是参数 schema
  2. 启动服务:mcp.run() 默认通过 stdio 通信

接入 Claude Desktop

把上面的 Server 接入 Claude Desktop 只需要一步:编辑配置文件。

// claude_desktop_config.json{"mcpServers": {"weather": {"type""stdio","command""python","args": ["weather_server.py"],"cwd""/path/to/your/project"    }  }}

重启 Claude Desktop 后,它会自动:

  1. 启动你的 weather_server.py 进程
  2. 通过 MCP 协议发现 get_weather 工具
  3. 当用户问天气相关问题时,Claude 会自动发现并请求调用这个工具(实际调用时 Host 可能要求用户确认权限)

你不需要写任何 Function Calling 的 JSON Schema,不需要手动注册 tools——Server 自己声明了能力,Client 自动发现。


MCP 的通信方式

MCP 当前主流支持两种传输方式:

1. stdio(标准输入输出)

Client 启动 Server 进程,通过 stdin/stdout 通信。适合本地工具。

Client ──stdin──> ServerClient <─stdout── Server

2. Streamable HTTP(远程服务通信)

Server 作为独立 HTTP 服务运行,Client 通过网络连接。适合远程工具/团队共享。早期版本使用 HTTP + SSE(Server-Sent Events),新版协议已转向 Streamable HTTP。

Client ──HTTP──> Server(发送请求)Client <─HTTP── Server(流式返回结果)

选哪种?

  • 本地开发/个人使用 → stdio(简单,零配置)
  • 团队共享/生产部署 → Streamable HTTP(可远程访问)

MCP 生态现状

截至目前,MCP 生态已经相当丰富:

支持 MCP 的 Host:

  • Claude Desktop(原生支持)
  • VS Code / GitHub Copilot(已支持或正在适配 MCP)
  • Cursor(已集成 MCP 支持)
  • 部分开源 Agent 框架(LangChain、CrewAI 等有不同程度的适配)

常见 MCP Server:

  • 文件系统操作(读写文件、目录遍历)
  • 数据库查询(PostgreSQL、SQLite)
  • Web 搜索(Brave Search、Google)
  • GitHub(PR、Issue、代码搜索)
  • 第三方 API(Slack、Notion、飞书)

社区已经有数百个现成 Server,大多数开箱即用。


什么时候该用 MCP,什么时候用 Function Calling?

场景
推荐
快速原型,单模型,2-3 个工具
Function Calling(更简单)
工具要在多个平台复用
MCP
团队协作,工具需要独立维护
MCP
工具逻辑复杂,需要独立进程
MCP
想接入 Claude Desktop / VS Code
MCP(原生支持)

不是非此即彼。 很多生产系统是混合使用的——简单工具用 Function Calling 快速搞定,复杂/需要复用的工具用 MCP 独立部署。


总结

概念
一句话理解
MCP 本质
Agent 工具的"USB 接口标准"
为什么需要
Function Calling 换模型就要重写,MCP 写一次到处用
三个角色
Host(应用)→ Client(适配层)→ Server(工具)
Server 核心
用 @mcp.tool() 声明工具函数,SDK 自动处理其余一切
通信方式
stdio(本地)或 Streamable HTTP(远程)

核心思想:工具和模型之间不应该紧耦合。MCP 在中间加了一层协议,让两边可以独立演进。

需要注意的是:MCP 解决了工具声明和调用层面的标准化,但模型能否正确理解和选择工具、权限管理、多步工作流编排等问题,仍需要 Agent Runtime 自己处理——这些正是前几篇讲的 Runtime 设计要解决的事。

换句话说:MCP 解决的是"工具怎么接",而不是"Agent 怎么思考"。 从软件工程视角看,MCP 更像"设备驱动接口标准",而 Agent Runtime 更像"操作系统"——MCP 是基础设施的一部分,但不是全部。

这跟前面讲的 Runtime 思路一脉相承——Agent 的架构越来越像传统软件工程:分层、解耦、标准化。

下期预告:Multi-Agent——一个 Agent 不够用怎么办?多个 Agent 怎么协作?主从模式、专家组模式,以及 A2A 协议。