好的,這是一篇針對台灣讀者的部落格文章,介紹 FastMCP v2。
🚀 讓你的 LLM 更聰明:用 FastMCP 打造強大的工具與資料庫!
嘿,各位熱愛 AI 的朋友們!你是否也覺得大型語言模型(LLM)很棒,但有時候就是少了點什麼?像是無法存取特定資料、不能執行特定動作,或是總覺得回答不夠精準?
今天就來介紹一個超棒的工具 FastMCP v2,它能讓你輕鬆打造 LLM 的專屬外掛,讓你的 LLM 瞬間升級,變得更加強大!
網址: 根據參考資料,FastMCP 的官方文件網址是 gofastmcp.com。 專案原始碼放在 Github 上:https://github.com/jlowin/fastmcp
什麼是 MCP?跟 FastMCP 有什麼關係?
首先,我們要先了解 MCP(Model Context Protocol,模型上下文協定) 是什麼。簡單來說,MCP 就像是一個讓 LLM 可以安全、標準化地存取外部資料和功能的橋樑。你可以想像成 LLM 專用的 API,讓它可以:
- 讀取資料(Resources): 就像 GET 請求,把資料餵給 LLM,讓它了解更多資訊。
- 執行動作(Tools): 就像 POST/PUT 請求,讓 LLM 可以呼叫外部功能,例如計算、查詢資料庫等等。
- 定義互動模式(Prompts): 就像範本,引導 LLM 如何更有效地使用這些功能。
而 FastMCP 就是一個讓你用 Python 快速、簡單地建立和使用 MCP 伺服器的工具。它幫你處理了複雜的協定細節,讓你專注在打造實用的功能上。
為什麼要用 FastMCP?
你可能會想,自己寫 API 不就好了嗎?為什麼要用 MCP 和 FastMCP 呢?原因很簡單:
- 標準化: MCP 是一個公開的協定,讓不同的 LLM 和應用程式可以互相溝通。
- 安全性: MCP 提供了一種安全的方式,讓 LLM 存取外部資源,避免潛在的風險。
- 方便性: FastMCP 讓你用 Python 就能快速建立 MCP 伺服器,省去大量的程式碼。
更棒的是,FastMCP 2.0 還加入了更多進階功能,像是可以代理和組合 MCP 伺服器,甚至可以從現有的 OpenAPI 或 FastAPI 應用程式自動產生 MCP 伺服器!
FastMCP 的核心概念:打造 LLM 的超能力
FastMCP 的核心概念其實很簡單,就是透過一些 Python 的裝飾器(Decorator),讓你輕鬆地定義 LLM 可以使用的功能。
1. FastMCP
伺服器:你的 LLM 中樞
FastMCP
伺服器是整個應用程式的核心,它負責處理連線、協定細節和路由。你可以這樣建立一個 FastMCP
伺服器:
from fastmcp import FastMCP
# 建立一個名為 "我的應用程式" 的伺服器
mcp = FastMCP("我的應用程式")
# 或是指定需要的依賴套件,方便部署
mcp = FastMCP("我的應用程式", dependencies=["pandas", "numpy"])
2. 工具(Tools):讓 LLM 動起來
工具讓 LLM 可以執行特定的動作,例如計算、查詢資料庫、發送通知等等。你可以用 @mcp.tool()
裝飾器來定義工具:
import httpx
from pydantic import BaseModel
class 使用者資訊(BaseModel):
使用者ID: int
通知: bool = False
@mcp.tool()
async def 發送通知(使用者: 使用者資訊, 訊息: str) -> dict:
"""如果使用者要求,發送通知給使用者。"""
if 使用者.通知:
# 模擬發送通知
print(f"正在通知使用者 {使用者.使用者ID}: {訊息}")
return {"狀態": "已發送", "使用者ID": 使用者.使用者ID}
return {"狀態": "已跳過", "使用者ID": 使用者.使用者ID}
@mcp.tool()
def 取得股票價格(股票代碼: str) -> float:
"""取得指定股票代碼的目前價格。"""
# 替換成實際的 API 呼叫
價格 = {"AAPL": 180.50, "GOOG": 140.20}
return 價格.get(股票代碼.upper(), 0.0)
在這個例子中,我們定義了兩個工具:
發送通知
:可以根據使用者資訊發送通知。取得股票價格
:可以取得指定股票的價格。
FastMCP 會自動根據型別提示(Type Hints)和文件字串(Docstrings)產生必要的 MCP schema。你甚至可以使用 Pydantic 模型來定義複雜的輸入。
3. 資源(Resources):讓 LLM 讀取資料
資源讓 LLM 可以讀取特定的資料,例如設定檔、使用者資料、產品資訊等等。你可以用 @mcp.resource("你的://URI")
裝飾器來定義資源:
# 靜態資源,回傳簡單的文字
@mcp.resource("config://應用程式版本")
def 取得應用程式版本() -> str:
"""回傳應用程式的版本。"""
return "v2.1.0"
# 動態資源範本,從 URI 取得 '使用者ID'
@mcp.resource("db://使用者/{使用者ID}/email")
async def 取得使用者Email(使用者ID: str) -> str:
"""取得指定使用者 ID 的 email 地址。"""
# 替換成實際的資料庫查詢
emails = {"123": "alice@example.com", "456": "bob@example.com"}
return emails.get(使用者ID, "找不到@example.com")
# 資源,回傳 JSON 資料
@mcp.resource("data://產品類別")
def 取得產品類別() -> list[str]:
"""回傳可用的產品類別列表。"""
return ["電子產品", "書籍", "家居用品"]
在這個例子中,我們定義了三個資源:
取得應用程式版本
:回傳應用程式的版本。取得使用者Email
:根據使用者 ID 回傳 email 地址。取得產品類別
:回傳可用的產品類別列表。
你可以在 URI 中使用大括號 {}
來定義動態資源,讓 URI 的一部分變成函式的參數。
4. 提示(Prompts):引導 LLM 的互動
提示定義了可重複使用的範本或互動模式,引導 LLM 如何更有效地使用你的伺服器。你可以用 @mcp.prompt()
裝飾器來定義提示:
from fastmcp.prompts.base import UserMessage, AssistantMessage
@mcp.prompt()
def 請求程式碼審查(程式碼片段: str) -> str:
"""產生一個標準的程式碼審查請求。"""
return f"請審查以下程式碼片段,找出潛在的錯誤和風格問題:\n```python\n{程式碼片段}\n```"
@mcp.prompt()
def 開始除錯會話(錯誤訊息: str) -> list[Message]:
"""啟動一個除錯協助會話。"""
return [
UserMessage(f"我遇到一個錯誤:\n{錯誤訊息}"),
AssistantMessage("好的,我可以幫忙。請提供完整的追蹤訊息,並告訴我你想要做什麼?")
]
在這個例子中,我們定義了兩個提示:
請求程式碼審查
:產生一個程式碼審查請求。開始除錯會話
:啟動一個除錯協助會話。
5. 上下文(Context):在工具和資源中存取 MCP 功能
透過將 fastmcp.Context
型別提示加到參數中,你可以在工具或資源函式 內部 存取 MCP 伺服器功能。
from fastmcp import Context, FastMCP
mcp = FastMCP("Context 範例")
@mcp.resource("system://狀態")
async def 取得系統狀態(ctx: Context) -> dict:
"""檢查系統狀態並記錄資訊。"""
await ctx.info("正在檢查系統狀態...")
# 執行檢查
await ctx.report_progress(1, 1) # 回報完成
return {"狀態": "OK", "負載": 0.5, "client": ctx.client_id}
@mcp.tool()
async def 處理大型檔案(檔案URI: str, ctx: Context) -> str:
"""處理大型檔案,回報進度並讀取資源。"""
await ctx.info(f"開始處理 {檔案URI}")
# 使用上下文讀取資源
檔案內容資源 = await ctx.read_resource(檔案URI)
檔案內容 = 檔案內容資源[0].content # 假設是單一文字內容
lines = 檔案內容.splitlines()
總行數 = len(lines)
for i, line in enumerate(lines):
# 處理行...
if (i + 1) % 100 == 0: # 每 100 行回報進度
await ctx.report_progress(i + 1, 總行數)
await ctx.info(f"完成處理 {檔案URI}")
return f"已處理 {總行數} 行。"
Context
物件提供:
- 記錄:
ctx.debug()
、ctx.info()
、ctx.warning()
、ctx.error()
- 進度報告:
ctx.report_progress(current, total)
- 資源存取:
await ctx.read_resource(uri)
- 請求資訊:
ctx.request_id
、ctx.client_id
- 取樣(進階):
await ctx.sample(...)
向連線的 LLM 客戶端請求完成。
6. 圖像
使用 fastmcp.Image
輔助類別輕鬆處理影像輸入和輸出。
from fastmcp import FastMCP, Image
from PIL import Image as PILImage
import io
mcp = FastMCP("圖片範例")
@mcp.tool()
def 建立縮圖(圖片資料: Image) -> Image:
"""從提供的圖片建立一個 100x100 的縮圖。"""
img = PILImage.open(io.BytesIO(圖片資料.data)) # 假設圖片資料是帶有位元組的 Image 接收
img.thumbnail((100, 100))
buffer = io.BytesIO()
img.save(buffer, format="PNG")
# 回傳一個新的帶有縮圖資料的 Image 物件
return Image(data=buffer.getvalue(), format="png")
@mcp.tool()
def 從磁碟載入圖片(路徑: str) -> Image:
"""從指定的路徑載入圖片。"""
# 處理讀取檔案並根據副檔名偵測格式
return Image(path=path)
FastMCP 會處理轉換為 MCP 協定所需的 base64 編碼格式。
實際操作:快速開始
現在,讓我們來看看如何實際建立一個簡單的 MCP 伺服器:
- 安裝 FastMCP:
pip install fastmcp
- 建立一個
server.py
檔案,並加入以下程式碼:# server.py from fastmcp import FastMCP # 建立一個 MCP 伺服器 mcp = FastMCP("Demo") # 加入一個加法工具 @mcp.tool() def 加法(a: int, b: int) -> int: """加兩個數字""" return a + b # 加入一個動態問候語資源 @mcp.resource("greeting://{name}") def 取得問候語(name: str) -> str: """取得個人化的問候語""" return f"哈囉,{name}!" if __name__ == "__main__": mcp.run()
- 執行伺服器:
python server.py
或者,使用 FastMCP CLI 工具:
fastmcp run server.py
- (推薦)使用 Claude Desktop 測試:
如果你有安裝 Claude Desktop,可以直接用以下指令安裝這個伺服器:
fastmcp install server.py
然後就可以在 Claude Desktop 中使用你建立的工具和資源了!
進階功能:打造更複雜的應用程式
FastMCP 2.0 還提供了一些進階功能,讓你打造更複雜的應用程式:
- 代理伺服器: 建立一個 FastMCP 伺服器,作為另一個 MCP 端點的中介,代理請求。
- 組合 MCP 伺服器: 將多個 FastMCP 伺服器組合在一起,建立模組化的應用程式。
- 從 OpenAPI 和 FastAPI 產生: 從現有的 OpenAPI 或 FastAPI 應用程式自動產生 FastMCP 伺服器。
結論:讓你的 LLM 飛起來!
FastMCP 是一個非常強大的工具,它可以讓你輕鬆打造 LLM 的專屬外掛,讓你的 LLM 變得更加聰明、更加實用。如果你想要讓你的 LLM 飛起來,那就趕快開始使用 FastMCP 吧!
希望這篇文章對你有幫助!如果你有任何問題,歡迎在留言區提出。也歡迎分享你用 FastMCP 打造的有趣應用!
參考閱讀
https://github.com/jlowin/fastmcp