什么是 MCP?
官网:https://modelcontextprotocol.io/introduction
2025 年,Anthropic 提出了 MCP(Model Context Protocol)协议。简单来说,这是为大模型和外部工具之间的交互提供的一套统一标准。就像 USB-C 接口统一了各种设备的连接方式一样,MCP 让 AI 大模型调用查询信息、操作本地文件等外部工具变得更加规范。
MCP 采用 C/S 架构(客户端/服务端),既支持在客户端设备上调用远程 Server 提供的服务,也支持 stdio 流式传输模式,也就是可以在客户端本地启动 MCP 服务端。只需要在配置文件中新增 MCP 服务端,就能直接用上该服务器提供的各种工具,大大提升了大模型集成外部能力的便捷性。

作为开源协议,MCP 旨在让所有 AI 厂商和工具都能将其集成到客户端中。生态越丰富,协议的发展就越快,最终惠及整个开发者社区。
了解 Function Call
在 MCP 普及之前,如果我们想开发能调用外部工具的 AI Agent,通常得针对不同的模型 SDK 编写适配代码。最经典的方案莫过于 OpenAI 的 Function Calling 机制。
Function Call 实战演示
1. 配置工具,让 AI 生成参数
调用 Chat Completions 接口时,通过 tools 参数传入外部工具的定义。这包括了工具的描述、所需参数及其类型说明。其中 tool_choice 设为 auto 表示让模型自动决定是否调用工具,设为 none 则禁止调用。
{
"tool_choice": "auto",
"messages": [
{ "role": "system", "content": "你是一个天气查询助手" },
{ "role": "user", "content": "帮我查询上海的天气" }
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "城市名" }
},
"required": ["city"]
}
}
}
]
}
对应的 Python SDK 代码如下。我们将工具定义放入字典列表,作为 create 函数的 tools 参数。这里以 Qwen2.5 模型为例,实际运行时请替换为有效的 API Key。
import openai
import json
def main():
client = openai.OpenAI(
api_key="your_api_key_here",
base_url="https://api.siliconflow.cn/v1"
)
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "城市名" }
},
"required": ["city"]
}
}
}]
res = client.chat.completions.create(
model="Qwen/Qwen2.5-32B-Instruct",
messages=[
{ "role": "system", "content": "你是一个天气查询助手" },
{ "role": "user", "content": "帮我查询上海的天气" }
],
tools=tools,
tool_choice="auto"
)
print("content:", res.choices[0].message.content)
print("tools:", res.choices[0].message.tool_calls)
print("message:", res.choices[0].message.to_dict())
if __name__ == "__main__":
main()
运行后,大模型会根据用户请求和提供的工具定义,自动生成参数。此时 content 字段通常为空,关键信息在 tool_calls 中。
❯ uv run main.py
content:
tools: [ChatCompletionMessageToolCall(id='...', function=Function(arguments='{"city": "上海"}', name='get_weather'), type='function')]
响应 JSON 会包含具体的参数结构:
{
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "...",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\n \"city\": \"上海\"\n}"
}
}
]
}
2. 调用工具并让 AI 二次处理
拿到模型返回的参数后,我们需要执行实际的函数调用,并将结果反馈给模型进行后续处理。这一步的关键在于维护对话上下文。
首先,将第一次请求中模型返回的结果(即 role: assistant 的消息)保留在上下文中。接着,插入一条新的消息,角色标记为 tool,内容包含工具调用的 ID 和返回结果。格式大致如下:
{
"role": "tool",
"tool_call_id": "...",
"content": "{"weather": "sunny", "temp": 25}"
}
这样,模型就能结合之前的意图和最新的工具返回数据,生成最终的回复。这种流程虽然有效,但每次对接新模型或新工具时,往往需要重新适配参数结构和调用逻辑,这也是 MCP 协议试图解决的核心痛点之一。


