Model Context Protocol (MCP)

什么是MCP

MCP 起源于 2024 年 11 月 25 日 Anthropic 發(fā)布的文章:Introducing the Model Context Protocol。

MCP 是一個開放協(xié)議,它為應用程序向 LLM 提供上下文的方式進行了標準化。你可以將 MCP 想象成 AI 應用程序的 USB-C 接口。就像 USB-C 為設備連接各種外設和配件提供了標準化的方式一樣,MCP 為 AI 模型連接各種數(shù)據(jù)源和工具提供了標準化的接口。

如下圖


image.png

可以看出,MCP 就是以更標準的方式讓 LLM Chat 使用不同工具,更簡單的可視化如下圖所示,這樣你應該更容易理解“中間協(xié)議層”的概念了。Anthropic 旨在實現(xiàn) LLM Tool Call 的標準。

image.png

MCP架構(gòu)

20250418141925.jpg

MCP 由三個核心組件構(gòu)成:Host、Client 和 Server。

這里主要涉及到三個角色:主機、服務器客戶端。

Host是發(fā)起連接的 LLM 應用程序(如 Claude Desktop 或 IDE)
Client在主機應用程序內(nèi)部與服務器保持 1:1 連接
Server向客戶端提供上下文、工具和提示

Why MCP

LLM的一些缺點:

1.會產(chǎn)生幻覺。

2.結(jié)果并不總是真實的。

  1. 對時事的了解有限或一無所知。

4.很難應對復雜的計算。

為了解決這個問題出現(xiàn)了一系列的技術(shù)或者手段

image.png

簡介

Function Calling 的核心思想:大語言模型的語言理解能力與外部工具的功能結(jié)合起來,讓大語言模型能夠理解用戶的意圖,并調(diào)用合適的工具來完成任務。例如,通過 Function Calling,大語言模型可以:

調(diào)用天氣 API獲取實時天氣信息: 不再局限于提供過時的天氣預報,而是可以告訴你此時此刻的天氣狀況,就像你打開手機上的天氣應用一樣。

調(diào)用訂票網(wǎng)站 API 預訂機票: 不再只是告訴你如何訂票,而是可以直接幫你完成訂票操作,就像一個專業(yè)的旅行代理一樣。
調(diào)用代碼執(zhí)行程序: 可以執(zhí)行代碼來完成各種任務,例如數(shù)據(jù)分析、圖像處理等,就像一個經(jīng)驗豐富的程序員一樣。

多模態(tài)感知和工具利用等策略來擴展其感知和行動空間

function call 實現(xiàn)偽代碼

# 定義可調(diào)用的函數(shù)列表 (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\. 判斷是否需要調(diào)用函數(shù)
    if intent == "weather_inquiry":
        # 3\. 提取函數(shù)調(diào)用參數(shù)
        params = extract_parameters(
            input_text,
            function_schema=functions["get_weather"]["parameters"]
        )

        # 4\. 生成函數(shù)調(diào)用指令
        function_call = {
            "name": "get_weather",
            "arguments": params
        }

        # 5\. 執(zhí)行函數(shù)調(diào)用(可能對接外部API)
        if validate_parameters(function_call):
            weather_data = external_api_call(
                function_call["name"], 
                function_call["arguments"]
            )

            # 6\. 將結(jié)構(gòu)化數(shù)據(jù)轉(zhuǎn)換為自然語言響應
            response = generate_response(weather_data)
            return response

    # 其他意圖處理...
    else:
        return generate_general_response(input_text)

# 執(zhí)行處理流程
final_response = process_request(user_input)
print(final_response)

從上面?zhèn)未a可以看到 function call 主要干了兩件事。

1.判斷是否要調(diào)用某個預定義的函數(shù)。

2.如果要調(diào)用,從用戶輸入的文本里提取出函數(shù)所需要的函數(shù)值。

將這個過程標準化,變?yōu)橐粋€協(xié)議,所有的LLM都可以調(diào)用 這個就是MCP

MCP 協(xié)議都包括什么
https://www.claudemcp.com/zh/specification

如何使用 MCP?

https://zhuanlan.zhihu.com/p/30102885373 mcp服務和資源網(wǎng)站

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

以cursor為例演示

MCP 原理

在學習的過程中,我一直好奇一個問題:Claude(模型)是在什么時候確定使用哪些工具的呢?
解釋

當用戶提出一個問題時:

graph LR
A[用戶輸入自然語言] --> B[LLM 解析意圖]
B --> C[生成 MCP 工具調(diào)用指令]
C --> D[MCP Client 發(fā)送請求]
D --> E[MCP Server 調(diào)用工具]
E --> F[工具執(zhí)行并返回結(jié)果]
F --> G[LLM 整合結(jié)果生成回答]
G --> H[用戶獲得最終響應]

// 偽代碼:LLM 服務端處理
import OpenAI from 'openai';

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

async function callLLM(userQuery: string): Promise<string> {
  const prompt = `
    請將用戶問題轉(zhuǎn)換為 MCP 工具調(diào)用指令(JSON格式):
    問題:${userQuery}

    可用工具清單:
    - 代碼分析工具: analyze_code,參數(shù) { file_path: string, check_type: 'memory_leak' | 'performance' }
    - 數(shù)據(jù)查詢工具: query_database,參數(shù) { 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 執(zhí)行所選的工具。

3.工具的執(zhí)行結(jié)果被送回給 Cursor。

4.Cursor 結(jié)合執(zhí)行結(jié)果構(gòu)造最終的 prompt 并生成自然語言的回應。

5.回應最終展示給用戶!

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

7.執(zhí)行對應的 MCP Server 并對執(zhí)行結(jié)果進行重新處理

代碼解析
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... 假設這里已經(jīng)處理了用戶消息輸入.
         messages.append({"role": "user", "content": user_input})
 
         # 將 system_message 和用戶消息輸入一起發(fā)送給 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)和工具所需要的參數(shù)(args_desc)轉(zhuǎn)化為文本
     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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容