Model Context Protocol (MCP)

什么是MCP

MCP 起源于 2024 年 11 月 25 日 Anthropic 发布的文章:Introducing the Model Context Protocol

MCP 是一个开放协议,它为应用程序向 LLM 提供上下文的方式进行了标准化。你可以将 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 为设备连接各种外设和配件提供了标准化的方式一样,MCP 为 AI 模型连接各种数据源和工具提供了标准化的接口。

如下图


image.png

可以看出,MCP 就是以更标准的方式让 LLM Chat 使用不同工具,更简单的可视化如下图所示,这样你应该更容易理解“中间协议层”的概念了。Anthropic 旨在实现 LLM Tool Call 的标准。

image.png

MCP架构

20250418141925.jpg

MCP 由三个核心组件构成:Host、Client 和 Server。

这里主要涉及到三个角色:主机服务器客户端

Host是发起连接的 LLM 应用程序(如 Claude Desktop 或 IDE)
Client在主机应用程序内部与服务器保持 1:1 连接
Server向客户端提供上下文、工具和提示

Why MCP

LLM的一些缺点:

1.会产生幻觉。

2.结果并不总是真实的。

  1. 对时事的了解有限或一无所知。

4.很难应对复杂的计算。

为了解决这个问题出现了一系列的技术或者手段

image.png

简介

Function Calling 的核心思想:大语言模型的语言理解能力与外部工具的功能结合起来,让大语言模型能够理解用户的意图,并调用合适的工具来完成任务。例如,通过 Function Calling,大语言模型可以:

调用天气 API获取实时天气信息: 不再局限于提供过时的天气预报,而是可以告诉你此时此刻的天气状况,就像你打开手机上的天气应用一样。

调用订票网站 API 预订机票: 不再只是告诉你如何订票,而是可以直接帮你完成订票操作,就像一个专业的旅行代理一样。
调用代码执行程序: 可以执行代码来完成各种任务,例如数据分析、图像处理等,就像一个经验丰富的程序员一样。

多模态感知和工具利用等策略来扩展其感知和行动空间

function call 实现伪代码

# 定义可调用的函数列表 (AI 可使用的工具)
functions = [
    {
        "name": "get_weather",
        "description": "获取指定城市的天气信息",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {"type": "string", "description": "城市名称"},
                "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
            },
            "required": ["location"]
        }
    },
    {
        "name": "track",
        "description": "追踪指定股票的实时价格",
        "parameters": {
            "type": "object",
            "properties": {
                "symbol": {
                    "description": "需要追踪的股票代码"
                }
            },
            "required": ['symbol']
        }
    }
    ...
]

# 用户输入处理
user_input = "北京今天气温多少度?"

# AI 模型处理流程
def process_request(input_text):
    # 1\. 语义理解
    intent = understand_intent(input_text)  # 识别用户意图

    # 2\. 判断是否需要调用函数
    if intent == "weather_inquiry":
        # 3\. 提取函数调用参数
        params = extract_parameters(
            input_text,
            function_schema=functions["get_weather"]["parameters"]
        )

        # 4\. 生成函数调用指令
        function_call = {
            "name": "get_weather",
            "arguments": params
        }

        # 5\. 执行函数调用(可能对接外部API)
        if validate_parameters(function_call):
            weather_data = external_api_call(
                function_call["name"], 
                function_call["arguments"]
            )

            # 6\. 将结构化数据转换为自然语言响应
            response = generate_response(weather_data)
            return response

    # 其他意图处理...
    else:
        return generate_general_response(input_text)

# 执行处理流程
final_response = process_request(user_input)
print(final_response)

从上面伪代码可以看到 function call 主要干了两件事。

1.判断是否要调用某个预定义的函数。

2.如果要调用,从用户输入的文本里提取出函数所需要的函数值。

将这个过程标准化,变为一个协议,所有的LLM都可以调用 这个就是MCP

MCP 协议都包括什么
https://www.claudemcp.com/zh/specification

如何使用 MCP?

https://zhuanlan.zhihu.com/p/30102885373 mcp服务和资源网站

https://www.claudemcp.com/zh/servers

以cursor为例演示

MCP 原理

在学习的过程中,我一直好奇一个问题:Claude(模型)是在什么时候确定使用哪些工具的呢
解释

当用户提出一个问题时:

graph LR
A[用户输入自然语言] --> B[LLM 解析意图]
B --> C[生成 MCP 工具调用指令]
C --> D[MCP Client 发送请求]
D --> E[MCP Server 调用工具]
E --> F[工具执行并返回结果]
F --> G[LLM 整合结果生成回答]
G --> H[用户获得最终响应]

// 伪代码:LLM 服务端处理
import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: 'YOUR_KEY' });

async function callLLM(userQuery: string): Promise<string> {
  const prompt = `
    请将用户问题转换为 MCP 工具调用指令(JSON格式):
    问题:${userQuery}

    可用工具清单:
    - 代码分析工具: analyze_code,参数 { file_path: string, check_type: 'memory_leak' | 'performance' }
    - 数据查询工具: query_database,参数 { sql: string }

    输出示例:
    { "tool_name": "analyze_code", "parameters": { "file_path": "src/App.cpp", "check_type": "memory_leak" } }
  `;

  const completion = await openai.chat.completions.create({
    messages: [{ role: 'user', content: prompt }],
    model: 'gpt-4',
  });

  return completion.choices[0].message.content;
}
  1. Cursor 分析可用的工具,并决定使用哪一个(或多个)。

2.客户端通过 MCP Server 执行所选的工具。

3.工具的执行结果被送回给 Cursor。

4.Cursor 结合执行结果构造最终的 prompt 并生成自然语言的回应。

5.回应最终展示给用户!

6.由 LLM(Cursor)确定使用哪些 MCP Server。

7.执行对应的 MCP Server 并对执行结果进行重新处理

代码解析
https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/clients/simple-chatbot/mcp_simple_chatbot/main.py#L341

... # 省略了无关的代码
 async def start(self):
     # 初始化所有的 mcp server
     for server in self.servers:
         await server.initialize()
 
     # 获取所有的 tools 命名为 all_tools
     all_tools = []
     for server in self.servers:
         tools = await server.list_tools()
         all_tools.extend(tools)
 
     # 将所有的 tools 的功能描述格式化成字符串供 LLM 使用
     # tool.format_for_llm() 我放到了这段代码最后,方便阅读。
     tools_description = "\n".join(
         [tool.format_for_llm() for tool in all_tools]
     )
 
     # 这里就不简化了,以供参考,实际上就是基于 prompt 和当前所有工具的信息
     # 询问 LLM(Claude) 应该使用哪些工具。
     system_message = (
         "You are a helpful assistant with access to these tools:\n\n"
         f"{tools_description}\n"
         "Choose the appropriate tool based on the user's question. "
         "If no tool is needed, reply directly.\n\n"
         "IMPORTANT: When you need to use a tool, you must ONLY respond with "
         "the exact JSON object format below, nothing else:\n"
         "{\n"
         '    "tool": "tool-name",\n'
         '    "arguments": {\n'
         '        "argument-name": "value"\n'
         "    }\n"
         "}\n\n"
         "After receiving a tool's response:\n"
         "1\. Transform the raw data into a natural, conversational response\n"
         "2\. Keep responses concise but informative\n"
         "3\. Focus on the most relevant information\n"
         "4\. Use appropriate context from the user's question\n"
         "5\. Avoid simply repeating the raw data\n\n"
         "Please use only the tools that are explicitly defined above."
     )
     messages = [{"role": "system", "content": system_message}]
 
     while True:
         # Final... 假设这里已经处理了用户消息输入.
         messages.append({"role": "user", "content": user_input})
 
         # 将 system_message 和用户消息输入一起发送给 LLM
         llm_response = self.llm_client.get_response(messages)
 
     ... # 后面和确定使用哪些工具无关

 
 class Tool:
     """Represents a tool with its properties and formatting."""
 
     def __init__(
         self, name: str, description: str, input_schema: dict[str, Any]
     ) -> None:
         self.name: str = name
         self.description: str = description
         self.input_schema: dict[str, Any] = input_schema
 
     # 把工具的名字 / 工具的用途(description)和工具所需要的参数(args_desc)转化为文本
     def format_for_llm(self) -> str:
         """Format tool information for LLM.
 
         Returns:
             A formatted string describing the tool.
         """
         args_desc = []
         if "properties" in self.input_schema:
             for param_name, param_info in self.input_schema["properties"].items():
                 arg_desc = (
                     f"- {param_name}: {param_info.get('description', 'No description')}"
                 )
                 if param_name in self.input_schema.get("required", []):
                     arg_desc += " (required)"
                 args_desc.append(arg_desc)
 
         return f"""
 Tool: {self.name}
 Description: {self.description}
 Arguments:
 {chr(10).join(args_desc)}
 """

其他MCP

vite-plugin-vue-mcp

参考

https://www.claudemcp.com/zh/docs/introduction

https://zhuanlan.zhihu.com/p/663770472

https://zhuanlan.zhihu.com/p/1892612293252065003

https://zhuanlan.zhihu.com/p/29001189476

https://zhuanlan.zhihu.com/p/678893732

https://juejin.cn/post/7488188832921649215

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容