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