大模型應用開發新范式:深入解讀MCP協議設計思想 原創
MCP能解決什么問題
我們之前開發LLM應用的時候,這個應用不僅基于已有的知識庫對話,還和外部連接訪問數據和使用工具:
- 訪問 google 進行內容檢索
- 訪問 youtube 進行視頻檢索
- 調用公司內部的CRM接口
我們在LLM應用內部做了很多的粘合工作,在之后如果我們要新開一個LLM應用,如果還需要使用這些工具怎么辦呢?我們可以引入一個中間層,把這些能力放在中間層中,LLM 應用只負責和中間層打交道。這其實就是MCP做的事,MCP可以用來簡化LLM應用和這些外部資源工具的集成。
MCP 有哪些優勢
MCP的核心就是標準化和統一操作,其實這也是軟件開發中一種常見的范式,比如有些廠商提供了統一的API網關,可以訪問不同大模型廠家的模型。MCP的出現隔離了開發者的關注點,LLM應用專注于應用開發,MCP Server 關注于工具能力的開發,如果某個外部資源的接口發生變化,那么也只需要修改對應的MCP Server, 作為使用方的其他LLM應用是不需要修改的。具體意義體現在以下幾個方面:
- 簡化了LLM應用的開發,LLM 應用只需要選擇對應的MCP Server即可
- AI能力共享:MCP Server的出現,使得新的LLM應用可以快速獲得很多能力,形成了一種全新的合作體系
基于MCP的架構
MCP Server
MCP Server 并非是傳統意義上的那種server,其實叫組件更合適。它可以和LLM應用部署在同一個服務器上,也可以遠程部署。
怎么獲取MCP Server
- 下載別人寫好的MCP Server, 這種在github上一搜一大堆,比如下面這個地址https://github.com/punkpeye/awesome-mcp-servers
- 自己使用MCP 的包自己開發,后面我們自己開發一個
MCP Server 需要提供什么
- Tools: 這個MCP Server 有哪些工具,MCP Client 獲取Server對應的Tools 之后才知道用戶的什么請求可以使用什么Tool
- Resources: 提供結構化數據(如知識庫、產品目錄、術語表),補充LLM的靜態知識或實時數據
- prompts: 提供給LLM應用的一些Prompt模板。比如你的應用是一個Chatbot,可以從MCP Server中取出這些模板,讓使用者選擇使用
MCP Server如何啟動
- 不同的 MCP Server 有不同的啟動命令,參考對應的說明即可,可能有的還需要安裝Server啟動所需要的依賴
- 一般MCP Server 啟動之后就是本地的一個獨立的進程了
MCP Client
MCP Client 是LLM 應用使用MCP的包創建的一個session會話,可以類比成數據庫的一個connection連接。通過這個會話,可以調用MCP Server,比如查詢Server支持哪些tools之類的。
Client & Server怎么通信
- 如果 Server 部署在遠端,那么通過網絡協議進行通信
- 如果 Server 部署在本地,那就是一個獨立的進程,linux 進程間的通信可以通過管道,client 和 server的通信就是通過stdio交互數據。例如一個進程可以把另一個進程的?
?stdout?
? 讀入作為它的??stdin?
?,這樣就能獲取到第二個進程的輸出數據
實操演示
先來個簡單的demo:
from mcp.server import FastMCP
# 初始化 MCP 服務器,名稱用于客戶端識別
mcp = FastMCP("my-server")
# 注冊工具:同步函數示例(加法器)
@mcp.tool()
def add(a: int, b: int) -> int:
"""計算兩個數的和"""
return a + b
# 注冊工具:異步函數示例(模擬API請求)
@mcp.tool()
asyncdef fetch_data(url: str) -> str:
"""從URL獲取數據"""
import httpx
asyncwith httpx.AsyncClient() as client:
response = await client.get(url)
return response.text
if __name__ == "__main__":
mcp.run(transport="stdio") # 使用標準輸入輸出通信
- ?
?@mcp.tool()?
? 裝飾器暴露函數為 MCP 工具。 - 支持同步和異步函數(如?
?async/await?
?)。 - 函數注釋(?
?"""..."""?
?)會被 AI 客戶端解析,幫助模型理解工具用途
我們也可以把這個server當做遠程部署來啟動:
mcp run server.py --transport=sse
接下來我們創建一個MCP Client:
from mcp.client.stdio import stdio_client
from mcp import ClientSession, StdioServerParameters, types
import asyncio
# Client會使用這里的配置來啟動本地MCP Server
server_params = StdioServerParameters(
command="python3",
args=["./mcp_server.py"],
env=None
)
asyncdef main():
asyncwith stdio_client(server_params) as (read, write):
asyncwith ClientSession(
read, write, sampling_callback=None
) as session:
await session.initialize()
print(await session.list_tools())
print('\n正在調用工具...')
result = await session.call_tool("add", {"a": 1, "b": 2})
print(result.content)
time.sleep(60)
asyncio.run(main())
最終返回的結果如下:
我們會發現mcp_server 作為mcp_client的一個子進程在運行
高級用法
??resources?
?? 和 ??prompt?
? 是兩類強大的擴展功能,分別用于動態數據共享和引導AI模型行為
Resources
Resources 允許在工具之間共享狀態或數據(如數據庫連接、API密鑰),無需全局變量。特點:
- 生命周期由 MCP 管理(如懶加載、自動清理)
- 支持依賴注入(工具可聲明需要某資源)
import sqlite3
from contextlib import contextmanager
@mcp.resource()
@contextmanager
def db_connection():
"""數據庫連接資源(自動關閉)"""
conn = sqlite3.connect("data.db")
try:
yield conn
finally:
conn.close()
@mcp.tool()
def query_users(query: str, conn: sqlite3.Connection = mcp.depends(db_connection)) -> list:
"""執行SQL查詢"""
return conn.execute(query).fetchall()
Prompt
??Prompt?
? 功能用于 動態控制 AI 模型的行為,通過修改模型的上下文提示詞(System Prompt)或提供示例(Few-shot Examples),可以顯著改變模型的輸出風格和邏輯。
from fastmcp import FastMCP
import openai # 官方OpenAI庫
mcp = FastMCP("openai-integration")
# 配置OpenAI API密鑰(實際應從環境變量讀取)
openai.api_key = "sk-your-api-key"
@mcp.prompt()
def role_based_prompt(role: str):
"""動態Prompt:根據角色設定AI行為"""
role_profiles = {
"teacher": "你是一個嚴謹的數學老師,必須逐步解釋推導過程",
"joker": "用幽默的段子和網絡流行語回答問題",
"coder": "僅返回代碼,不要任何解釋"
}
return {"system": role_profiles.get(role, "默認助手模式")}
# 給工具綁定prompt
@mcp.tool(prompt=role_based_prompt)
def ask_question(question: str, role: str = "teacher") -> str:
"""實際調用OpenAI生成回答(非模擬)"""
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": role_based_prompt(role)["system"]},
{"role": "user", "content": question}
],
temperature=0.7if role == "joker"else0.3# 幽默模式需要更高隨機性
)
return response.choices[0].message["content"] # 返回AI生成的文本
if __name__ == "__main__":
mcp.run(transport="http", port=8000) # 啟動HTTP服務
總結
本文闡述的MCP框架知識體系為后續開發復雜智能Agent奠定了理論基礎。在實際應用開發環節,我們將基于MCP架構設計并實現功能強大的LLM應用解決方案。
參考資料:
- ??https://modelcontextprotocol.io/introduction??
- ??https://github.com/punkpeye/awesome-mcp-servers??
- ??https://glama.ai/mcp/servers??
- ??https://github.com/supercorp-ai/supergateway??
- ??https://github.com/langchain-ai/langchain-mcp-adapters??
本文轉載自公眾號AI 博物院 作者:longyunfeigu
原文鏈接:??https://mp.weixin.qq.com/s/rvZ7uDojJDxX6x3ZmQivLQ??
