在上一篇文章 MCP簡介 中,我們對 MCP(Model Context Protocol) 有了一個概念上的認識,本文將更加深入的介紹 MCP 的架構和功能。
MCP是什麼
如果我們認為 LLM(大語言模型) 是大腦的話, MCP 提供其它的能力將給這個大腦裝上四肢和五官,使得它具備與外界環境交互的能力。
使用 MCP,Claude 或 ChatGPT 等 AI 應用程序可以連接到數據源(例如本地文件、數據庫)、工具(例如搜索引擎、計算器)和工作流(例如:複雜任務中間一個環節用到的提示詞)。
從上圖可以看出,MCP有以下重要特點:
- 雙向通信: 使用MCP連接的AI應用和各種工具的交互是 雙向的 :AI工具可以訪問工具,而後面的工具也可以主動訪問AI應用,這與常用的API的單向調用不同。
- 功能強大:它不止提供我們最容易想象的API調用能力,還可以與本地和遠程數據源協同工作,甚至將人類、智能體/agent和外部世界連接起來。
MCP架構
MCP 是CS(Client-Server)架構 。
MCP Host/主機(例如 Claude Code 或 Claude Desktop 等 AI 應用程序)會與一個或多個 MCP 服務端建立連接。MCP 主機通過為每個 MCP 服務端創建一個 MCP 客户端來實現這一點:每個 MCP 客户端都與其對應的 MCP 服務端保持一對一的專用連接。
例如:用 Visual Studio Code 充當 MCP 主機。當 Visual Studio Code 建立與 MCP 服務端(例如 Sentry MCP 服務端)的連接時,Visual Studio Code 運行時會實例化一個 MCP 客户端對象,用於維護與 Sentry MCP 服務端的連接。當 Visual Studio Code 隨後連接到另一個 MCP 服務端(例如本地文件系統服務端)時,Visual Studio Code 運行時會實例化另一個 MCP 客户端對象來維護此連接,從而保持 MCP 客户端與 MCP 服務端之間的一對一關係。
後面的文章將使用
Visual Studio Code進行上述場景的實戰演練。
服務端
MCP 服務端常見的功能包括:用於文檔訪問的文件系統服務端、用於數據查詢的數據庫服務端、用於代碼管理的 GitHub 服務端、用於團隊溝通的 Slack 服務端以及用於日程安排的日曆服務端。
| 功能 | 説明 | 例子 |
|---|---|---|
| 工具/tools | 大模型可以主動調用的函數,並根據用户請求決定何時使用它們。工具可以寫入數據庫、調用外部 API、修改文件或觸發其他邏輯 | 搜索航班、發送消息、創建日曆活動。 |
| 資源/resources | 提供對文件內容、數據庫模式或 API 文檔等數據源的只讀訪問。 | 檢索文檔、訪問知識庫、閲讀日曆 |
| 提示詞模板/prompts | 預先構建的指令模板,它告訴大模型使用特定的工具和資源。 | 計劃假期、總結我的會議、起草電子郵件 |
提示詞模板 是由用户控制而非主動觸發的:服務端預定義提示詞模板->用户輸入提示此模板需要的參數-> 服務端返回提示詞讓大模型處理。
例如:在旅行規劃場景中,服務端會提前定義好提示詞模板,其中包含參數:出發地、目的地,當用户輸入出發地、目的地後,服務端才會使用這兩個參數填充提示此模板,生成提示詞返回。
客户端
MCP客户端 由 主機/MCP Host 應用程序實例化,用於與特定的 MCP 服務器通信。主機應用程序(例如 Claude.ai 或 IDE)負責管理整體用户體驗並協調多個客户端。每個客户端處理與一台服務器的直接通信。
兩者的區別至關重要:主機是用户與之交互的應用程序,而客户端是支持服務器連接的組件。
MCP客户端除了與MCP服務端通信以外,還連接了用户/人和大語言模型/LLM;在交互過程中,除了可以限制對資源的訪問以外,可以進行人為審核和糾正。
| 功能 | 説明 | 例子 |
|---|---|---|
| 採樣/Sampling | MCP服務端通過MCP客户端請求大模型完成任務/LLM completions,從而實現智能體的工作流。這種方法使客户端能夠完全控制用户權限和安全。 | 預訂旅行的MCP服務端可能會向 大模型/LLM 發送航班列表,並請求 大模型 為用户挑選最佳航班。 |
| 根/Roots | 允許客户端指定MCP服務端可以訪問哪些文件,引導它們到相關目錄,同時保持安全邊界。 | 預訂旅行的MCP服務端可能會被授予訪問特定目錄的權限,從而可以從中讀取用户的日曆。 |
| 獲取/Elicitation | 使MCP服務端能夠在交互過程中向用户請求特定信息。 | 預訂旅行的MCP服務端可能會詢問用户對飛機座位、房間類型或聯繫電話的偏好,以完成預訂。 |
上述概念不容易理解,尤其是
Sampling和我們直觀的想象的採樣不是同樣的意思,我覺得未來有可能會改掉這些令人費解的叫法。
如果問各種AI平台:“MCP中的Sampling是什麼意思?”,通常會體驗到大模型的“幻覺”,大模型會懵掉:)
鑑於上述概念用中文理解有一定難度,下面我們再一起學習一下這些功能的含義。
採樣/Sampling
這裏的 採樣/Sampling 並不是 隨機抽取樣本 的意思,而是由 MCP服務端 主動發起的,請求大模型完成的任務的行為。MCP客户端在構造客户端時,可以訂閲MCP服務端的Sampling事件。
我們可以通過下面簡單的代碼片段進一步理解這一點:
MCP服務端:向MCP客户端發送 SamplingMessage 消息,即吟詩一首,然後得到MCP客户端返回的結果。
mcp = FastMCP(name="Sampling Example")
@mcp.tool()
async def generate_poem(topic: str, ctx: Context[ServerSession, None]) -> str:
"""Generate a poem using LLM sampling."""
prompt = f"Write a short poem about {topic}"
result = await ctx.session.create_message(
messages=[
SamplingMessage(
role="user",
content=TextContent(type="text", text=prompt),
)
],
max_tokens=100,
)
if result.content.type == "text":
return result.content.text
return str(result.content)
MCP客户端:訂閲MCP服務端的 SamplingMessage 消息,調用大模型作詩後,返回給MCP服務端。
async def handle_sampling_message(
context: RequestContext[ClientSession, None], params: types.CreateMessageRequestParams
) -> types.CreateMessageResult:
print(f"Sampling request: {params.messages}")
poem = "..." # 調用大模型作詩
return types.CreateMessageResult(
role="assistant",
content=types.TextContent(
type="text",
text=poem,
),
model="qwen3",
stopReason="endTurn",
)
async def run():
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write, sampling_callback=handle_sampling_message) as session:
# Initialize the connection
await session.initialize()
# ...
def main():
"""Entry point for the client script."""
asyncio.run(run())
if __name__ == "__main__":
main()
在更加複雜的場景中,在 採樣/Sampling 的過程中,可以由人來干預,如下圖:
上述場景描述了:在MCP服務端請求大模型之前,人可以批准是否執行,也可以修改提示詞;在大模型執行完提示詞後,人可以批准大模型執行結果是否返回給MCP服務端,也可以修改此結果後再給MCP服務端。
獲取/Elicitation
獲取/Elicitation 使MCP服務端能夠在交互過程中向用户請求特定信息,從而創建更具動態性和響應能力的工作流。在這個過程中:服務器無需預先收集所有信息,也無需在數據缺失時停止運行,而是可以暫停運行以請求用户的特定輸入。
例如:在預定機票場景中,MCP服務端可以請求用户輸入航班號、航班日期等信息,這樣確認後,再由MCP服務端訂票。
總結
通過對MCP更多瞭解,可以發現: MCP 可以把大腦(大語言模型)和各種能力(五官和四肢)粘合起來,變成一個智能體/agent。
參考:
- MCP官網
🪐祝好運🪐