MCP入門實戰(Python版)

MCP介紹

MCP入門介紹

MCP 簡介 - MCP 中文文檔

MCP,全稱是Model Context Protocol,模型上下文協議,由Claude母公司Anthropic于2024年11月正式提出。

從本質上來說,MCP是一種技術協議,一種智能體Agent開發過程中共同約定的一種規范。這就好比秦始皇的“書同文、車同軌”,在統一的規范下,大家的協作效率就能大幅提高,最終提升智能體Agent的開發效率。截止目前,已上千種MCP工具誕生,在強悍的MCP生態加持下, 人人手搓Manus的時代即將到來。

總的來說,MCP解決的最大痛點,就是Agent開發中調用外部工具的技術門檻過高的問題

我們都知道,能調用外部工具,是大模型進化為智能體Agent的關鍵,如果不能使用外部工具,大模型就 只能是個簡單的聊天機器人,甚至連查詢天氣都做不到。由于底層技術限制,大模型本身是無法和外部工具直接通信的,因此Function calling的思路,就是創建一個外部函數(function)作為中介,一邊 傳遞大模型的請求,另一邊調用外部工具,最終讓大模型能夠間接的調用外部工具。

例如,當我們要查詢當前天氣時,讓大模型調用外部工具的function calling的過程就如圖所示:

Function calling是個非常不錯的技術設計,自誕生以來,一直被業內奉為圭臬。但唯一的問題就是,編寫這個外部函數的工作量太大了,一個簡單的外部函數往往就得上百行代碼,而且,為了讓大模型“認識” 這些外部函數,我們還要額外為每個外部函數編寫一個JSON Schema格式的功能說明,此外,我們還需要精心設計一個提示詞模版,才能提高Function calling響應的準確率

MCP的目標,就是能在Agent開發過程中,讓大模型更加便捷的調用外部工具。為此,MCP提出了兩個方案

  • 其一,“車同軌、書同文”,統一Function calling的運行規范。 首先是先統一名稱,MCP把大模型運行環境稱作 MCP Client,也就是MCP客戶端,同時,把外部函數運行環境稱作MCP Server,也就是MCP服務器
  • 然后,統一MCP客戶端和服務器的運行規范,并且要求MCP客戶端和服務器之間,也統一按照某個既定的提示詞模板進行通信

“車同軌、書同文”最大的好處就在于,可以避免MCP服務器的重復開發,也就是避免外部函數重復編寫。 例如,像查詢天氣、網頁爬取、查詢本地MySQL數據庫這種通用的需求,大家有一個人開發了一個服務器就好,開發完大家都能復制到自己的項目里來使用,不用每個人每次都單獨寫一套。現在,只要你本地運行的大模型支持MCP協議,也就是只要安裝了相關的庫,僅需幾行代碼即可接入這 些海量的外部工具。

這種“車同軌、書同文”的規范,在技術領域就被稱作協議,例如http就是網絡信息交換的技術協議。各類技術協議的目標,都是希望通過提高協作效率來提升開發效率,而MCP,Model Context Protocol,就是一種旨在提高大模型Agent開發效率的技術協議

那既然是協議,必然是使用的人越多才越有用。因此,為了進一普及MCP協議,Anthropic還提供了一整 套MCP客戶端、服務器開發的SDK,也就是開發工具,并且支持Python、TS和Java等多種語言,借助 SDK,僅需幾行代碼,就可以快速開發一個MCP服務器。

# server.py
from mcp.server.fastmcp import FastMCP# Create an MCP server
mcp = FastMCP("Demo")# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:"""Add two numbers"""return a + b# Add a dynamic greeting resource
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:"""Get a personalized greeting"""return f"Hello, {name}!"

然后,你就可以把它接入任意一個MCP客戶端來構建智能體,如果愿意,還可以把MCP服務器分享到社區,給有需求的開發者使用,甚至你還可以把你的MCP服務器放到線上運行,讓用戶付費使用。

而MCP的客戶端,不僅支持Claude模型,也支持任意本地模型或者在線大模型,或者是一些IDE。例 如,現在Cursor正式接入MCP,代表著Cursor正式成為MCP客戶端,在Cursor中,我們不僅能快速編寫 MCP服務器(外部函數),更能借助Cursor一鍵連接上成百上千的開源MCP服務器,讓大模型快速接入 海量工具,從而大幅加快Agent開發進度。

Function calling技術簡介

MCP客戶端開發

UV工具入門使用指南

UV介紹

MCP開發要求借助uv進行虛擬環境創建和依賴管理。

uv 是一個Python 依賴管理工具,類似于 pip 和 conda ,但它更快、更高效,并且可以更好地管理 Python 虛擬環境和依賴項。它的核心目標是 替代 pip 、venv 和 pip-tools ,提供更好的性能和更低的管理開銷。

uv 的特點:

  • 1. 速度更快:相比 pip ,uv 采用 Rust 編寫,性能更優。
  • 2. 支持 PEP 582:無需 virtualenv ,可以直接使用
  • 3. 兼容 pip :支持 __pypackages__ 進行管理。 requirements.txt 和 pyproject.toml 依賴管理。
  • 4. 替代 venv :提供 uv venv 進行虛擬環境管理,比venv 更輕量。
  • 5. 跨平臺:支持 Windows、macOS 和 Linux。

?uv安裝流程

方法 1:使用 pip 安裝(適用于已安裝 pip install uv venv 更輕量。 pip 的系統)

pip install uv

方法 2:使用 curl 直接安裝 如果你的系統沒有 pip ,可以直接運行:

curl -LsSf https://astral.sh/uv/install.sh | sh

這會自動下載 uv 并安裝到 /usr/local/bin 。

uv的基本用法介紹

安裝 uv 后,你可以像 pip 一樣使用它,但它的語法更簡潔,速度也更快。注意,以下為使用語法 示例,不用實際運行。

  • 安裝 Python 依賴
uv pip install requests

與 pip install requests 類似,但更快?

  • 創建虛擬環境
uv venv myenv

等效于 python -m venv myenv,但更高效。?

  • 激活虛擬環境
source myenv/bin/activate  # Linux/macOS
myenv\Scripts\activate     # Windows
  • 安裝 requirements.txt
 uv pip install -r requirements.txt
  • 直接運行 Python 項目

如果項目中包含 pyproject.toml ,你可以直接運行:

uv run python script.py

這等效于:

pip install -r requirements.txt
python script.py

    但 uv 速度更快,管理更高效。

    為什么MCP更推薦使用uv進行環境管理?

    MCP 依賴的 Python 環境可能包含多個模塊,uv 通過 pyproject.toml 提供更高效的管理方式,并且可以避免 pip 的一些依賴沖突問題。此外,uv 的包管理速度遠超 pip ,這對于 MCP 這樣頻繁管理依賴的項目來說是一個很大的優勢。

    接下來我們嘗試先構建一個 MCP 客戶端,確保基本邏輯可用,然后再逐步搭建 MCP 服務器進行聯調, 這樣可以分階段排查問題,避免一上來就涉及太多復雜性。

    MCP極簡客戶端搭建流程

    前文我們已經說過,MCP把大模型運行環境稱作 MCP Client,也就是MCP客戶端,同時,把外部函數運行環境稱作MCP Server,也就是MCP服務器

    因此創建MCP客戶端的流程其實就是創建一個調用大模型的接口?

    創建MCP 客戶端項目

    uv init mcp-client
    cd mcp-client
    

    創建MCP客戶端虛擬環境

    # 創建虛擬環境
    uv venv
    # 激活虛擬環境
    source .venv/bin/activate

    這里需要注意的是,相比pip,uv會自動識別當前項目主目錄并創建虛擬環境。

    然后即可通過add方法在虛擬環境中安裝相關的庫。

    # 安裝 MCP SDK
    uv add mcp
    

    為了支持調用OpenAI模型,以及在環境變量中讀取API-KEY等信息,需要先安裝如下依賴:

    uv add mcp openai python-dotenv

    創建.env文件

    接下來創建.env文件,并寫入OpenAI的API-Key,以及反向代理地址。借助反向代理,國內可以無 門檻直連OpenAI官方服務器,并調用官方API。

    使用線上模型
    BASE_URL="反向代理地址"
    MODEL=gpt-4o
    OPENAI_API_KEY="OpenAI-API-Key"

    ?而如果是使用DeepSeek模型,則需要在.env中寫入如下內容

    BASE_URL=https://api.deepseek.com
    MODEL=deepseek-chat      
    OPENAI_API_KEY="DeepSeek API-Key"
    
    使用本地部署模型

    如果是本地部署的模型,比如我自己使用ollama本地部署的qwen3模型,則使用以下配置:

    BASE_URL=http://localhost:11434/v1/
    MODEL=qwen3:1.7b
    OPENAI_API_KEY=ollama
    

    如果使用的是VLLM部署的模型,則使用以下配置

    BASE_URL=http://localhost:8000/v1
    MODEL=./QwQ-32B
    OPENAI_API_KEY=EMPTY

    本地部署的模型調用過程中,api_key其實并不起作用,因此隨便填寫即可

    關于如何本地部署qwen3模型,可參考

    零基礎本地部署Qwen3模型(ollama+Open-WebUI)-CSDN博客

    vLLM調度部署Qwen3-CSDN博客

    創建client.py

    import asyncio
    import os
    from openai import OpenAI
    from dotenv import load_dotenv
    from contextlib import AsyncExitStack# 加載 .env 文件,確保 API Key 受到保護
    load_dotenv()class MCPClient:def __init__(self):"""初始化 MCP 客戶端"""self.exit_stack = AsyncExitStack()self.openai_api_key = os.getenv("OPENAI_API_KEY")  # 讀取 OpenAI API Keyself.base_url = os.getenv("BASE_URL")  # 讀取 BASE URLself.model = os.getenv("MODEL")  # 讀取 modelif not self.openai_api_key:raise ValueError("? 未找到 OpenAI API Key,請在 .env 文件中設置 OPENAI_API_KEY")self.client = OpenAI(api_key=self.openai_api_key, base_url=self.base_url)async def process_query(self, query: str) -> str:"""調用 OpenAI API 處理用戶查詢"""messages = [{"role": "system", "content": "你是一個智能助手,幫助用戶回答問題。"},{"role": "user", "content": query}]try:# 調用 OpenAI APIresponse = await asyncio.get_event_loop().run_in_executor(None,lambda: self.client.chat.completions.create(model=self.model,messages=messages))return response.choices[0].message.contentexcept Exception as e:return f"? 調用 OpenAI API 時出錯: {str(e)}"async def chat_loop(self):"""運行交互式聊天循環"""print("\n🤖MCP 客戶端已啟動!輸入 'quit' 退出")while True:try:query = input("\n你: ").strip()if query.lower() == 'quit':break# 發送用戶輸入到 OpenAI APIresponse = await self.process_query(query)print(f"\n🤖 OpenAI: {response}")except Exception as e:print(f"\n? 發生錯誤: {str(e)}")async def cleanup(self):"""清理資源"""await self.exit_stack.aclose()async def main():client = MCPClient()try:await client.chat_loop()finally:await client.cleanup()if __name__ == "__main__":asyncio.run(main())    

    ?運行

    使用線上模型運行

    如果客戶端client.py使用的是線上模型,則直接運行代碼即可

    uv run client.py
    使用本地部署模型運行

    如果客戶端使用的是本地部署的模型,則需要首先開啟本地部署的模型服務,這樣client.py才能找到要調用的模型。使用本地部署模型的工具有多種,如ollama、VLLM等

    如果我們使用ollama部署的本地模型,則只需輸入以下命令即可啟動我們在本地部署的模型服務

    ollama start

    ?如果我們使用VLLM部署的本地模型,則輸入以下命令啟動部署的模型服務

     CUDA_VISIBLE_DEVICES=0,1 vllm serve ./QwQ-32B --tensor-parallel-size 2

    然后再重新運行我們的?client.py

    uv run client.py

    運行效果如下所示

    MCP服務端開發

    MCP服務器概念介紹

    根據MCP協議定義,Server可以提供三種類型的標準能力,Resources、Tools、Prompts,每個 Server可同時提供者三種類型能力或其中一種。

    • Resources:資源,類似于文件數據讀取,可以是文件資源或是API響應返回的內容。
    • Tools:工具,第三方服務、功能函數,通過此可控制LLM可調用哪些函數。
    • Prompts:提示詞,為用戶預先定義好的完成特定任務的模板。

    MCP服務器通訊機制

    Model Context Protocol(MCP)是一種由 Anthropic 開源的協議,旨在將大型語言模型直接連接 至數據源,實現無縫集成。

    根據 MCP 的規范,當前支持兩種傳輸方式:標準輸入輸出(stdio)和基于 HTTP 的服務器推送事件(SSE),分別對應著本地與遠程通訊。Client與Server間使用JSON-RPC 2.0格式進行消息傳輸。

    • 本地通訊:使用了stdio傳輸數據,具體流程Client啟動Server程序作為子進程,其消息通訊是通過 stdin/stdout進行的,消息格式為JSON-RPC 2.0。
    • 遠程通訊:Client與Server可以部署在任何地方,Client使用SSE與Server進行通訊,消息的格式為 JSON-RPC 2.0,Server定義了/see與/messages接口用于推送與接收數據。

    而近期,開發者在 MCP 的 GitHub 倉庫中提交了一項提案,建議采用 “可流式傳輸的 HTTP”來替代現有的 HTTP+SSE 方案。此舉旨在解決當前遠程 MCP 傳輸方式的關鍵限制,同時保留其優勢。 HTTP 和 SSE(服務器推送事件)在數據傳輸方式上存在明顯區別:

    • 通信方式:
      • HTTP:采用請求-響應模式,客戶端發送請求,服務器返回響應,每次請求都是獨立的。
      • SSE:允許服務器通過單個持久的 HTTP 連接,持續向客戶端推送數據,實現實時更新。
    • 連接特性:
      • HTTP:每次請求通常建立新的連接,雖然在 HTTP/1.1 中引入了持久連接,但默認情況下仍 是短連接。
      • SSE:基于長連接,客戶端與服務器之間保持持續的連接,服務器可以在任意時間推送數據。
    • 適用場景:
      • HTTP:適用于傳統的請求-響應場景,如網頁加載、表單提交等。
      • SSE:適用于需要服務器主動向客戶端推送數據的場景,如實時通知、股票行情更新等。 需要注意的是,SSE 僅支持服務器向客戶端的單向通信,而 WebSocket 則支持雙向通信。

    需要注意的是,SSE 僅支持服務器向客戶端的單向通信,而 WebSocket 則支持雙向通信。

    天氣查詢服務器Server創建

    準備工作

    為方便,我們嘗試一個入門級的示例,那就是創建一個天氣查詢的服務器。通過使用OpenWeather API,創建一個能夠實時查詢天氣的服務器(server),并使用stdio方式進行通信。

    為了使用天氣查詢API,我們首先需要去OpenWeather注冊并獲取自己的api_key

    OpenWeather官網:https://openweathermap.org/

    注冊成功之后即可獲取自己的api_key

    申請完畢后可使用以下代碼進行api測試

    curl -s "https://api.openweathermap.org/data/2.5/weather?q=Beijing&appid=${api-key}&units=metric&lang=zh_cn"

    ?準備工作做好之后,接下來我們正式進入MCP server的開發

    服務器依賴安裝

    由于我們需要使用http請求來查詢天氣,因此需要在當前虛擬環境中添加如下依賴

    uv add mcp httpx
    

    服務器代碼編寫

    接下來嘗試創建服務器代碼,此時MCP基本執行流程如下:

    對應server服務器代碼如下:

    import json
    import httpx
    from typing import Any
    from mcp.server.fastmcp import FastMCP# 初始化 MCP 服務器
    mcp = FastMCP("WeatherServer")# OpenWeather API 配置
    OPENWEATHER_API_BASE = "https://api.openweathermap.org/data/2.5/weather"
    # API_KEY = "YOUR_API_KEY"  # 請替換為你自己的 OpenWeather API Key
    API_KEY = "62f016856f6a66a0cd6ee3cda5dbc9c3"  
    USER_AGENT = "weather-app/1.0"async def fetch_weather(city: str) -> dict[str, Any] | None:"""從 OpenWeather API 獲取天氣信息。:param city: 城市名稱(需使用英文,如 Beijing):return: 天氣數據字典;若出錯返回包含 error 信息的字典"""params = {"q": city,"appid": API_KEY,"units": "metric","lang": "zh_cn"}headers = {"User-Agent": USER_AGENT}async with httpx.AsyncClient() as client:try:response = await client.get(OPENWEATHER_API_BASE, params=params, headers=headers, timeout=30.0)response.raise_for_status()return response.json()  # 返回字典類型except httpx.HTTPStatusError as e:return {"error": f"HTTP 錯誤: {e.response.status_code}"}except Exception as e:return {"error": f"請求失敗: {str(e)}"}def format_weather(data: dict[str, Any] | str) -> str:"""將天氣數據格式化為易讀文本。:param data: 天氣數據(可以是字典或 JSON 字符串):return: 格式化后的天氣信息字符串"""# 如果傳入的是字符串,則先轉換為字典if isinstance(data, str):try:data = json.loads(data)except Exception as e:return f"無法解析天氣數據: {e}"# 如果數據中包含錯誤信息,直接返回錯誤提示if "error" in data:return f"? {data['error']}"# 提取數據時做容錯處理city = data.get("name", "未知")country = data.get("sys", {}).get("country", "未知")temp = data.get("main", {}).get("temp", "N/A")humidity = data.get("main", {}).get("humidity", "N/A")wind_speed = data.get("wind", {}).get("speed", "N/A")# weather 可能為空列表,因此用 [0] 前先提供默認字典weather_list = data.get("weather", [{}])description = weather_list[0].get("description", "未知")return (f"🌍 {city}, {country}\n"f"🌡 溫度: {temp}°C\n"f"💧 濕度: {humidity}%\n"f"🌬 風速: {wind_speed} m/s\n"f"? 天氣: {description}\n")@mcp.tool()
    async def query_weather(city: str) -> str:"""輸入指定城市的英文名稱,返回今日天氣查詢結果。:param city: 城市名稱(需使用英文):return: 格式化后的天氣信息"""data = await fetch_weather(city)return format_weather(data)if __name__ == "__main__":# 以標準 I/O 方式運行 MCP 服務器mcp.run(transport='stdio')

    天氣查詢客戶端client創建

    前邊我們創建一個極簡的客戶端代碼,本質上就是創建一個調用大模型的代碼,現在我們重新修改客戶端代碼,以支持MCP協議

    import asyncio
    import os
    import json
    import sys
    from typing import Optional
    from contextlib import AsyncExitStack
    from openai import OpenAI
    from dotenv import load_dotenv
    from mcp import ClientSession, StdioServerParameters
    from mcp.client.stdio import stdio_client# 加載 .env 文件,確保 API Key 受到保護
    load_dotenv()class MCPClient:def __init__(self):"""初始化 MCP 客戶端"""self.exit_stack = AsyncExitStack()self.openai_api_key = os.getenv("OPENAI_API_KEY")  # 讀取 OpenAI API Keyself.base_url = os.getenv("BASE_URL")  # 讀取 BASE URLself.model = os.getenv("MODEL")  # 讀取 modelif not self.openai_api_key:raise ValueError("? 未找到 OpenAI API Key,請在 .env 文件中設置 OPENAI_API_KEY")self.client = OpenAI(api_key=self.openai_api_key, base_url=self.base_url)self.session: Optional[ClientSession] = Noneself.exit_stack = AsyncExitStack()async def connect_to_server(self, server_script_path: str):print(server_script_path)"""連接到 MCP 服務器并列出可用工具"""is_python = server_script_path.endswith('.py')is_js = server_script_path.endswith('.js')if not (is_python or is_js):raise ValueError("服務器腳本必須是 .py 或 .js 文件")command = "python" if is_python else "node"server_params = StdioServerParameters(command=command,args=[server_script_path],env=None)# 啟動 MCP 服務器并建立通信stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))self.stdio, self.write = stdio_transportself.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))await self.session.initialize()# 列出 MCP 服務器上的工具response = await self.session.list_tools()tools = response.toolsprint("\n已連接到服務器,支持以下工具:", [tool.name for tool in tools])async def process_query(self, query: str) -> str:"""使用大模型處理查詢并調用可用的 MCP 工具 (Function Calling)"""messages = [{"role": "user", "content": query}]response = await self.session.list_tools()available_tools = [{"type": "function","function": {"name": tool.name,"description": tool.description,"input_schema": tool.inputSchema}} for tool in response.tools]# print(available_tools)response = self.client.chat.completions.create(model=self.model,messages=messages,tools=available_tools)# 處理返回的內容content = response.choices[0]if content.finish_reason == "tool_calls":# 如果需要使用工具,就解析工具tool_call = content.message.tool_calls[0]tool_name = tool_call.function.nametool_args = json.loads(tool_call.function.arguments)# 執行工具result = await self.session.call_tool(tool_name, tool_args)print(f"\n\n[Calling tool {tool_name} with args {tool_args}]\n\n")# 將模型返回的調用哪個工具數據和工具執行完成后的數據都存入messages中messages.append(content.message.model_dump())messages.append({"role": "tool","content": result.content[0].text,"tool_call_id": tool_call.id,})# 將上面的結果再返回給大模型用于生產最終的結果response = self.client.chat.completions.create(model=self.model,messages=messages,)return response.choices[0].message.contentreturn content.message.contentasync def chat_loop(self):"""運行交互式聊天循環"""print("\n🤖 MCP 客戶端已啟動!輸入 'quit' 退出")while True:try:query = input("\n你: ").strip()if query.lower() == 'quit':breakresponse = await self.process_query(query)  # 發送用戶輸入到 OpenAI APIprint(f"\n🤖 OpenAI: {response}")except Exception as e:print(f"\n? 發生錯誤: {str(e)}")async def cleanup(self):"""清理資源"""await self.exit_stack.aclose()async def main():if len(sys.argv) < 2:print("Usage: python client.py <path_to_server_script>")sys.exit(1)client = MCPClient()try:await client.connect_to_server(sys.argv[1])await client.chat_loop()finally:await client.cleanup()if __name__ == "__main__":import sysasyncio.run(main()) 

    代碼解讀

    導入必要庫
    import asyncio
    import os
    import json
    import sys
    from typing import Optional
    from contextlib import AsyncExitStack
    from openai import OpenAI
    from dotenv import load_dotenv
    from mcp import ClientSession, StdioServerParameters
    from mcp.client.stdio import stdio_client
    • asyncio :支持異步編程
    • os / json :讀取環境變量、解析 JSON
    • typing.Optional :類型提示
    • contextlib.AsyncExitStack :用于安全管理異步資源(如 MCP 連接)
    • openai.OpenAI :你的自定義 OpenAI Client 類
    • dotenv.load_dotenv :從 .env 文件加載環境變量(如 API Key)
    • MCP 相關: mcp.ClientSession , mcp.client.stdio , load_dotenv() StdioServerParameters
    加載環境變量

    從 .env 文件中加載環境變量?

    load_dotenv()

    初始化工作
        def __init__(self):"""初始化 MCP 客戶端"""self.exit_stack = AsyncExitStack()self.openai_api_key = os.getenv("OPENAI_API_KEY")  # 讀取 OpenAI API Keyself.base_url = os.getenv("BASE_URL")  # 讀取 BASE URLself.model = os.getenv("MODEL")  # 讀取 modelif not self.openai_api_key:raise ValueError("? 未找到 OpenAI API Key,請在 .env 文件中設置 OPENAI_API_KEY")self.client = OpenAI(api_key=self.openai_api_key, base_url=self.base_url)self.session: Optional[ClientSession] = Noneself.exit_stack = AsyncExitStack()
    • 1. self.exit_stack = AsyncExitStack()
      • 用于 統一管理異步上下文(如 MCP 連接)的生命周期。
      • 可以在退出( cleanup )時自動關閉
    • 2. 讀取環境變量 openai_api_key :
      • OpenAI API Key
      • base_url :模型請求的 Base URL(如你自建的反代地址)
      • model :OpenAI 模型名稱
    • 3. 初始化 OpenAI 客戶端
      • OpenAI(api_key=self.openai_api_key, base_url=self.base_url) :你自定義的 OpenAI 客戶端,用來與 OpenAI Chat Completion API 通信。
    • 4. self.session
      • 用于保存 MCP 的客戶端會話,默認是 None ,稍后通過 connect_to_server 進行連接。
    • 5. 再次聲明 self.exit_stack = AsyncExitStack() 這里兩次賦值其實有點冗余(前面已賦值過一次)。不過并不影響功能,等同于覆蓋掉前面的 對象。可能是手誤或調試時多寫了一次
    初始化MCP服務器連接
    command = "python" if is_python else "node"server_params = StdioServerParameters(command=command,args=[server_script_path],env=None)# 啟動 MCP 服務器并建立通信stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))self.stdio, self.write = stdio_transportself.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))await self.session.initialize()# 列出 MCP 服務器上的工具response = await self.session.list_tools()tools = response.toolsprint("\n已連接到服務器,支持以下工具:", [tool.name for tool in tools])
    • StdioServerParameters :告訴 MCP 客戶端如何啟動服務器。
      • command=command :如 "python"
      • args=[server_script_path] :如 ["weather_server.py"]
    • stdio_client(server_params) :啟動服務器進程,并建立 標準 I/O 通信管道。
    • self.stdio, self.write = stdio_transport :拿到讀寫流。
    • ClientSession(...) :創建 MCP 客戶端會話,與服務器交互。
    • await self.session.initialize() :發送初始化消息給服務器,等待服務器就緒。
    • list_tools() :向 MCP 服務器請求所有已注冊的工具(用 @mcp.tool() 標記)。
    客戶端模型調用MCP服務方法
        async def process_query(self, query: str) -> str:"""使用大模型處理查詢并調用可用的 MCP 工具 (Function Calling)"""messages = [{"role": "user", "content": query}]
    • 收到用戶輸入后,先把它組裝進一個 messages 列表,目前只包含用戶信息( "content": query} )。
            response = await self.session.list_tools()available_tools = [{"type": "function","function": {"name": tool.name,"description": tool.description,"input_schema": tool.inputSchema}} for tool in response.tools]print(available_tools)
    • 獲取服務器上的工具,再轉換成 available_tools 的格式。
    • 這里自定義了一個結構:每個工具對應一個 {"type": "function", "function": {...}} 的 字典。 方便后面發給 OpenAI,告訴它:可以調用這些工具。
           response = self.client.chat.completions.create(model=self.model,messages=messages,tools=available_tools)
    

    使用 OpenAI 客戶端的法發送請求:

    • model=self.model :比如 "gpt-4o" 或"deepseek-chat"
    • messages=messages :聊天上下文 "deepseek-chat"
    • tools=available_tools :讓模型知道有哪些可調用的「函數」。這是你自定義的 “Function Calling”協議(非官方 JSON schema)。
    # 處理返回的內容content = response.choices[0]if content.finish_reason == "tool_calls":# 如果需要使用工具,就解析工具tool_call = content.message.tool_calls[0]tool_name = tool_call.function.nametool_args = json.loads(tool_call.function.arguments)# 執行工具result = await self.session.call_tool(tool_name, tool_args)print(f"\n\n[Calling tool {tool_name} with args {tool_args}]\n\n")# 將模型返回的調用哪個工具數據和工具執行完成后的數據都存入messages中messages.append(content.message.model_dump())messages.append({"role": "tool","content": result.content[0].text,"tool_call_id": tool_call.id,})# 將上面的結果再返回給大模型用于生產最終的結果response = self.client.chat.completions.create(model=self.model,messages=messages,)return response.choices[0].message.content
    

    模型調用MCP服務并執行返回相關結果

    運行

     uv run client-mcp.py server.py

    以下是相關運行效果?

    Processing request of type ListToolsRequest已連接到服務器,支持以下工具: ['query_weather']🤖 MCP 客戶端已啟動!輸入 'quit' 退出你: 介紹一下你自己
    Processing request of type ListToolsRequest
    [{'type': 'function', 'function': {'name': 'query_weather', 'description': '\n    輸入指定城市的英文名稱,返回今日天氣查詢結果。\n    :param city: 城市名稱(需使用英文)\n    :return: 格式化后的天氣信息\n    ', 'input_schema': {'properties': {'city': {'title': 'City', 'type': 'string'}}, 'required': ['city'], 'title': 'query_weatherArguments', 'type': 'object'}}}]🤖 OpenAI: <think>
    好的,用戶讓我介紹一下自己。首先,我需要確認自己是否需要調用任何工具。根據提供的工具,有一個查詢天氣的函數,但用戶的問題是關于自我介紹,不需要天氣信息。因此,我應該直接回答,而不需要使用任何工具。接下來,我需要用簡潔明了的方式說明自己的身份和能力,比如我是智能助手,能提供幫助等。確保回答友好且信息準確。
    </think>我是智能助手,可以為您提供幫助。如果您有任何問題或需要 assistance,歡迎隨時告訴我!你: 你目前有哪些功能
    Processing request of type ListToolsRequest
    [{'type': 'function', 'function': {'name': 'query_weather', 'description': '\n    輸入指定城市的英文名稱,返回今日天氣查詢結果。\n    :param city: 城市名稱(需使用英文)\n    :return: 格式化后的天氣信息\n    ', 'input_schema': {'properties': {'city': {'title': 'City', 'type': 'string'}}, 'required': ['city'], 'title': 'query_weatherArguments', 'type': 'object'}}}]🤖 OpenAI: <think>
    嗯,用戶問我現在有哪些功能。首先,我需要回顧一下提供的工具信息。用戶提供的工具里只有一個函數,叫做query_weather,功能是查詢指定城市的天氣。這個函數的參數是城市名稱,要求用英文。所以,我的功能主要是天氣查詢,只能處理城市名稱的英文輸入。接下來,用戶可能想知道我的能力范圍,或者是否能提供其他服務。但根據當前的工具,我只能處理天氣相關的問題。我需要明確告訴用戶我的功能限制,同時提到可以協助查詢天氣。可能用戶想測試我的其他功能,但目前沒有,所以應該如實說明。另外,用戶可能希望知道是否需要提供其他幫助,比如天氣預報或建議,但根據現有工具,只能處理天氣查詢。所以回答時要誠實,同時提供可能的幫助方向。比如,告訴用戶我現在能查天氣,需要輸入城市名稱的英文,然后舉例說明,比如倫敦或紐約。這樣用戶能明白操作方法。
    </think>目前我只能查詢天氣信息,功能包括:
    1. 支持查詢全球城市天氣(需輸入英文名稱)
    2. 返回格式化后的天氣信息(如溫度、濕度、風力等)
    3. 時效性:今日天氣數據請提供需要查詢的城市英文名稱,例如"London"或"New York"。你: 幫我查詢北京的天氣
    Processing request of type ListToolsRequest
    [{'type': 'function', 'function': {'name': 'query_weather', 'description': '\n    輸入指定城市的英文名稱,返回今日天氣查詢結果。\n    :param city: 城市名稱(需使用英文)\n    :return: 格式化后的天氣信息\n    ', 'input_schema': {'properties': {'city': {'title': 'City', 'type': 'string'}}, 'required': ['city'], 'title': 'query_weatherArguments', 'type': 'object'}}}]
    Processing request of type CallToolRequest
    HTTP Request: GET https://api.openweathermap.org/data/2.5/weather?q=Beijing&appid=62f016856f6a66a0cd6ee3cda5dbc9c3&units=metric&lang=zh_cn "HTTP/1.1 200 OK"[Calling tool query_weather with args {'city': 'Beijing'}]🤖 OpenAI: <think>
    好的,用戶讓我查北京的天氣,我之前已經用英文查詢了,現在需要根據返回的數據整理成自然的中文回復。首先,確認返回的數據結構,溫度是33.46°C,濕度22%,風速1.68 m/s,天氣晴。需要把這些數據用中文表達清楚,同時保持口語化,避免使用Markdown格式。用戶可能希望得到簡潔明了的天氣信息,不需要太技術性的術語,但要準確。比如“溫度: 33.46°C”可以翻譯成“溫度:33.46°C”,保持數字格式。濕度和風速也要類似處理。最后加上天氣狀況,比如“晴”,確保信息完整。另外,用戶可能沒有明確說,但可能需要提醒注意防曬或補水,但根據問題本身,可能不需要添加額外信息。保持回答簡潔,直接給出數據即可。檢查是否有遺漏的參數,比如是否有風向,但返回中沒有提到,所以不需要補充。確保單位正確,如°C、m/s等。最后用自然的中文句式連接各部分,比如“目前北京天氣晴朗,溫度為33.46°C,濕度22%,風速1.68 m/s。”這樣用戶就能清楚了解天氣情況了。
    </think>目前北京天氣晴朗,溫度為33.46°C,濕度22%,風速1.68 m/s。你:
    

    需要注意的是,當我問大模型當前它有哪些功能的時候,它回答如下所示

    這是因為,目前我們的MCP服務端只寫了一個工具,即天氣查詢,接下來,我們可以嘗試自己寫一些服務工具來測試

    自定義MCP服務工具

    修改服務端代碼

    import json
    import httpx
    from typing import Any
    from mcp.server.fastmcp import FastMCP# 初始化 MCP 服務器
    mcp = FastMCP("WeatherServer")# OpenWeather API 配置
    OPENWEATHER_API_BASE = "https://api.openweathermap.org/data/2.5/weather"
    # API_KEY = "YOUR_API_KEY"  # 請替換為你自己的 OpenWeather API Key
    API_KEY = "62f016856f6a66a0cd6ee3cda5dbc9c3"  
    USER_AGENT = "weather-app/1.0"async def fetch_weather(city: str) -> dict[str, Any] | None:"""從 OpenWeather API 獲取天氣信息。:param city: 城市名稱(需使用英文,如 Beijing):return: 天氣數據字典;若出錯返回包含 error 信息的字典"""params = {"q": city,"appid": API_KEY,"units": "metric","lang": "zh_cn"}headers = {"User-Agent": USER_AGENT}async with httpx.AsyncClient() as client:try:response = await client.get(OPENWEATHER_API_BASE, params=params, headers=headers, timeout=30.0)response.raise_for_status()return response.json()  # 返回字典類型except httpx.HTTPStatusError as e:return {"error": f"HTTP 錯誤: {e.response.status_code}"}except Exception as e:return {"error": f"請求失敗: {str(e)}"}def format_weather(data: dict[str, Any] | str) -> str:"""將天氣數據格式化為易讀文本。:param data: 天氣數據(可以是字典或 JSON 字符串):return: 格式化后的天氣信息字符串"""# 如果傳入的是字符串,則先轉換為字典if isinstance(data, str):try:data = json.loads(data)except Exception as e:return f"無法解析天氣數據: {e}"# 如果數據中包含錯誤信息,直接返回錯誤提示if "error" in data:return f"? {data['error']}"# 提取數據時做容錯處理city = data.get("name", "未知")country = data.get("sys", {}).get("country", "未知")temp = data.get("main", {}).get("temp", "N/A")humidity = data.get("main", {}).get("humidity", "N/A")wind_speed = data.get("wind", {}).get("speed", "N/A")# weather 可能為空列表,因此用 [0] 前先提供默認字典weather_list = data.get("weather", [{}])description = weather_list[0].get("description", "未知")return (f"🌍 {city}, {country}\n"f"🌡 溫度: {temp}°C\n"f"💧 濕度: {humidity}%\n"f"🌬 風速: {wind_speed} m/s\n"f"? 天氣: {description}\n")@mcp.tool()
    async def query_weather(city: str) -> str:"""輸入指定城市的英文名稱,返回今日天氣查詢結果。:param city: 城市名稱(需使用英文):return: 格式化后的天氣信息"""data = await fetch_weather(city)return format_weather(data)@mcp.tool()
    async def Add(x:int,y:int)->int:"""執行兩個整數的加法運算:param x: 第一個加數:param y: 第二個加數:return: 兩數之和"""data=x+yreturn data@mcp.tool()
    async def Mul(x:int,y:int)->int:"""執行兩個整數的乘法運算:param x: 第一個乘數:param y: 第二個乘數:return: 兩數之積"""data=x*yreturn dataif __name__ == "__main__":# 以標準 I/O 方式運行 MCP 服務器mcp.run(transport='stdio')

    這里,我們增加了兩個自定義的MCP服務工具

    
    @mcp.tool()
    async def Add(x:int,y:int)->int:"""執行兩個整數的加法運算:param x: 第一個加數:param y: 第二個加數:return: 兩數之和"""data=x+yreturn data@mcp.tool()
    async def Mul(x:int,y:int)->int:"""執行兩個整數的乘法運算:param x: 第一個乘數:param y: 第二個乘數:return: 兩數之積"""data=x*yreturn data

    然后重新啟動

    uv run client-mcp.py server.py

    以下是相關運行效果?

    server.py
    Processing request of type ListToolsRequest已連接到服務器,支持以下工具: ['query_weather', 'Add', 'Mul']🤖 MCP 客戶端已啟動!輸入 'quit' 退出你: 介紹一下你當前的功能
    Processing request of type ListToolsRequest
    [{'type': 'function', 'function': {'name': 'query_weather', 'description': '\n    輸入指定城市的英文名稱,返回今日天氣查詢結果。\n    :param city: 城市名稱(需使用英文)\n    :return: 格式化后的天氣信息\n    ', 'input_schema': {'properties': {'city': {'title': 'City', 'type': 'string'}}, 'required': ['city'], 'title': 'query_weatherArguments', 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'Add', 'description': '\n    執行兩個整數的加法運算\n    :param x: 第一個加數\n    :param y: 第二個加數\n    :return: 兩數之和\n    ', 'input_schema': {'properties': {'x': {'title': 'X', 'type': 'integer'}, 'y': {'title': 'Y', 'type': 'integer'}}, 'required': ['x', 'y'], 'title': 'AddArguments', 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'Mul', 'description': '\n    執行兩個整數的乘法運算\n    :param x: 第一個乘數\n    :param y: 第二個乘數\n    :return: 兩數之積\n    ', 'input_schema': {'properties': {'x': {'title': 'X', 'type': 'integer'}, 'y': {'title': 'Y', 'type': 'integer'}}, 'required': ['x', 'y'], 'title': 'MulArguments', 'type': 'object'}}}]🤖 OpenAI: <think>
    好的,用戶問我介紹一下當前的功能。首先,我需要回顧一下提供的工具有哪些。有三個功能:查詢天氣、加法運算和乘法運算。接下來,我要把這些功能用簡單易懂的話解釋清楚。用戶可能不太清楚每個功能的具體用途,所以得分別說明。比如,查詢天氣需要輸入城市名稱,然后返回天氣信息。加法和乘法則直接處理兩個整數的運算。要注意用詞要友好,避免技術術語,讓普通用戶也能明白。另外,用戶可能想知道是否需要特定的參數,比如天氣功能需要英文城市名,這點要提到。同時,要提醒用戶如果需要幫助,可以進一步詢問。最后,保持回答簡潔,不需要太多細節,但要覆蓋所有功能。
    </think>目前我具備以下功能:
    1. 天氣查詢:可輸入英文城市名獲取當日天氣信息
    2. 數字運算:支持整數加法(Add)和乘法(Mul)操作
    3. 基本交互:能回答簡單問題并提供幫助需要我為您執行哪個功能?例如查詢北京天氣,或進行5+3的計算。你: 計算一下2和3的和是多少
    Processing request of type ListToolsRequest
    [{'type': 'function', 'function': {'name': 'query_weather', 'description': '\n    輸入指定城市的英文名稱,返回今日天氣查詢結果。\n    :param city: 城市名稱(需使用英文)\n    :return: 格式化后的天氣信息\n    ', 'input_schema': {'properties': {'city': {'title': 'City', 'type': 'string'}}, 'required': ['city'], 'title': 'query_weatherArguments', 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'Add', 'description': '\n    執行兩個整數的加法運算\n    :param x: 第一個加數\n    :param y: 第二個加數\n    :return: 兩數之和\n    ', 'input_schema': {'properties': {'x': {'title': 'X', 'type': 'integer'}, 'y': {'title': 'Y', 'type': 'integer'}}, 'required': ['x', 'y'], 'title': 'AddArguments', 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'Mul', 'description': '\n    執行兩個整數的乘法運算\n    :param x: 第一個乘數\n    :param y: 第二個乘數\n    :return: 兩數之積\n    ', 'input_schema': {'properties': {'x': {'title': 'X', 'type': 'integer'}, 'y': {'title': 'Y', 'type': 'integer'}}, 'required': ['x', 'y'], 'title': 'MulArguments', 'type': 'object'}}}]
    Processing request of type CallToolRequest[Calling tool Add with args {'x': 2, 'y': 3}]🤖 OpenAI: <think>
    好的,用戶讓我計算2和3的和,我需要確認他們是否真的需要簡單的加法。首先,我應該檢查是否有其他可能的解釋,比如是否有隱藏的數學概念或者陷阱。不過根據常見的數學問題,2加3的和顯然是5。用戶可能只是想確認基本的加法操作,或者測試我的反應速度。也有可能他們想看看我是否能正確識別簡單的算術題。需要確保回答準確且清晰,避免任何混淆。此外,用戶可能希望得到即時的反饋,所以直接給出答案并說明過程有助于他們理解。最后,保持回答簡潔,符合用戶的需求。
    </think>2和3的和是5。

    可以看到,編寫MCP服務端代碼其實很簡單,如下所示

    @mcp.tool()
    async def Add(x:int,y:int)->int:"""執行兩個整數的加法運算:param x: 第一個加數:param y: 第二個加數:return: 兩數之和"""data=x+yreturn data
    • @mcp.tool():聲明一個裝飾器,表明Mul函數是一個工具函數。在某些框架(如 LangChain)中,此類裝飾器用于將函數注冊為可被智能代理調用的工具,使函數能在自動化流程中被動態調用。
    • 工具說明:工具的注釋說明必須要有,這是模型識別并調用工具的關鍵
      """
      執行兩個整數的乘法運算
      :param x: 第一個乘數
      :param y: 第二個乘數
      :return: 兩數之積
      """
    • 工具函數的具體實現?

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/web/84613.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/web/84613.shtml
    英文地址,請注明出處:http://en.pswp.cn/web/84613.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    1、自然語言處理任務全流程

    自然語言處理黃金九步法&#xff0c;葵花寶典&#xff0c;請珍藏心間 目錄 需求分析&#xff1a;問題定義 1.文本分類任務 2.序列標注任務 3.文本生成任務 4.文本理解任務 5.信息抽取任務 6.文本匹配任務 7.多模態任務 一、數據獲取 1、發現可用數據集 2、常用的數…

    可編程密碼學(Part 1)

    1. 引言 當前密碼學正處于一次代際轉變之中&#xff0c;從special-purpose cryptography專用密碼學過渡到programmable cryptography可編程密碼學。 1&#xff09;所謂“專用密碼學”&#xff0c;指的是那些只能執行單個操作且具有密碼學安全保證的協議。 公鑰加密和簽名方案…

    Linux運維新人自用筆記(Ubuntu磁盤命名規則、新磁盤分區、主流文件系統類型、mkfs命令格式化文件系統、臨時和永久掛載、掛載報錯、dd指令)

    內容全為個人理解和自查資料梳理&#xff0c;歡迎各位大神指點&#xff01; 每天學習較為零散。 day21 一、磁盤維護流程 新硬盤&#xff08;虛擬機可添加&#xff09; 新硬盤需要做lvm管理 數據庫遷移&#xff08;夜間網站停機維護&#xff09;&#xff1a; 停止數據庫監…

    騰訊云輕量級服務器Ubuntu系統與可視化界面

    以云服務器的方式搭建Linux workstation對比在電腦本地安裝虛擬機的優勢在于&#xff0c;不需要占用本地電腦資源空間&#xff0c;網絡環境等相對穩定&#xff0c;可以用手機等輕量移動設備連接管理等。本文主要介紹使用騰訊云服務器&#xff0c;搭建Ubuntu Linux系統以及可視化…

    如何在MacOS系統和Windows系統安裝節點小寶遠程工具

    如何在MacOS系統和Windows系統安裝節點小寶遠程工具 摘要 本文講述如何在MacOS系統和Windows系統安裝節點小寶遠程工具&#xff0c;并詳細介紹了配置和使用遠程控制的步驟。無論是在個人電腦還是手機、平板設備之間的遠程連接&#xff0c;您都可以通過本教程輕松實現。 文章…

    60天python訓練營打卡day38

    學習目標&#xff1a; 60天python訓練營打卡 學習內容&#xff1a; DAY 38 Dataset和Dataloader類 知識點回顧&#xff1a; 1.Dataset類的__getitem__和__len__方法&#xff08;本質是python的特殊方法&#xff09; 2.Dataloader類 3.minist手寫數據集的了解 作業&#xff1a…

    Python 鄰接表詳細實現指南

    鄰接表是圖數據結構的一種高效表示方法&#xff0c;特別適合表示稀疏圖。下面我將用 Python 詳細講解鄰接表的多種實現方式、操作方法和實際應用。 一、鄰接表基礎概念 鄰接表的核心思想是為圖中的每個頂點維護一個列表&#xff0c;存儲與該頂點直接相連的所有鄰接頂點。 鄰…

    Nginx反向代理解決跨域問題詳解

    Nginx反向代理解決跨域問題詳解 核心原理 Nginx反向代理解決跨域的核心思路是讓客戶端請求同域名下的接口&#xff0c;由Nginx將請求轉發到目標服務器&#xff0c;從而規避瀏覽器的同源策略限制。 客戶端&#xff08;同源&#xff1a;www.domain.com&#xff09;↓Nginx&…

    單片機測ntc熱敏電阻的幾種方法

    在單片機中測量NTC&#xff08;負溫度系數&#xff09;熱敏電阻的阻值&#xff0c;通常需要將其轉換為電壓或頻率信號&#xff0c;再通過單片機進行采集和處理。以下是幾種常見的方法及其詳細說明&#xff1a; 1. 分壓法&#xff08;最常用&#xff09;?? ??原理??&…

    一套基于粒子群優化(PSO)算法的天線波束掃描MATLAB實現方案

    以下是一套基于粒子群優化(PSO)算法的天線波束掃描MATLAB實現方案,包含完整代碼、數學原理和詳細注釋。該方案針對均勻線性陣列(ULA)的波束方向圖優化,通過調整陣元相位實現主瓣指向目標方向并抑制旁瓣。 %% 天線波束掃描的PSO算法實現 % 作者:DeepSeek % 創建日期:20…

    增量學習ASAP的源碼剖析:如何實現人形的運動追蹤和全身控制(核心涉及HumanoidVerse中的agents模塊)

    前言 過去一周&#xff0c;我司「七月在線」長沙分部的具身團隊在機械臂和人形上并行發力 關于機械臂 一方面&#xff0c;在IL和VLA的路線下&#xff0c;先后采集了抓杯子、桌面收納、插入耳機孔的數據&#xff0c;然后云端訓-本地5090推理 二方面&#xff0c;在RL的路線下&a…

    計算機網絡學習筆記:應用層概述、動態主機配置協議DHCP

    文章目錄 一、應用層概述1.1、C/S架構1.2、P2P架構 二、動態主機配置協議DHCP2.1、DHCP發現報文2.2、DHCP提供報文2.3、DHCP請求報文2.4、DHCP確認報文2.5、DHCP的續約與終止 總結 一、應用層概述 應用層位于計算機網絡結構的最上層&#xff0c;用于解決應用進程的交互以實現特…

    為服務器SSH登錄增加2FA驗證

    安裝NTP模塊并設置時區 安裝NTP模塊 一般的服務器NTP服務默認是不安裝的&#xff0c;需要安裝NTP模塊【7】并啟用。 運行以下指令檢查你的NTP模塊是否已啟用&#xff0c;已啟用則忽略安裝NTP模塊的內容 timedatectl 如果你的返回內容和以下圖片一樣&#xff0c;則表示NTP未…

    AI大模型提示詞工程研究報告:長度與效果的辯證分析

    一、核心問題&#xff1a;提示詞長度與模型性能的平衡 核心矛盾&#xff1a;提示詞長度增加 → 信息豐富度↑ & 準確性↑ ? 計算成本↑ & 響應延遲↑ 二、詳細機制分析 &#xff08;一&#xff09;長提示詞的優勢&#xff08;實證數據支持&#xff09; 案例類型短提…

    HttpServletResponse源碼解析

    Java Servlet API 中 HttpServletResponse 接口的源碼&#xff0c;這是 Java Web 開發中非常核心的一個接口&#xff0c;用于向客戶端&#xff08;通常是瀏覽器&#xff09;發送 HTTP 響應。 public interface HttpServletResponse extends ServletResponse {int SC_CONTINUE …

    AI基礎概念

    目錄 1、ASR和STT區別 2、流式輸出 定義 原理 應用場景 優點 缺點 3、Ollama 4、mindspore和deepseek r1 v3 5、DeepSeek R1/V3 用的哪個底層AI框架 6、HAI-LLM比tensorflow、pytorch還強么 1. 核心優勢對比 2. 性能表現 3. 適用場景 總結 7、openai用的什么底層…

    ubuntu20.04速騰聚創airy驅動調試

    1.下載相關資料 下載包括&#xff1a;速騰airy產品手冊.pdf、RSView&#xff08;用于顯示激光雷達數據&#xff09;、3d數模文件、 RS-LiDAR-16用戶手冊 以下鏈接進行下載 https://www.robosense.cn/resources 2.連接線路后通過Wireshark抓包后進行本地IP配置 2.1按照線路連…

    Redis的大key和熱key如何解決

    文章目錄 Redis大Key一、什么是Redis大Key二、大Key的產生原因三、大Key的影響四、大Key的解決方案1. 檢測大Key2. 解決方案(1) 數據拆分(2) 使用壓縮算法(3) 使用合適的數據結構(4) 設置合理的過期時間(5) 合理清理(6) 配置優化 五、預防措施總結 Redis熱key一、熱Key問題的本…

    恒溫晶振與溫補晶振的區別

    在電子設備領域&#xff0c;晶振如同精準的“心臟起搏器”&#xff0c;為電路提供穩定的時鐘信號。恒溫晶振&#xff08;OCXO&#xff09;和溫補晶振&#xff08;TCXO&#xff09;作為兩類重要的晶體振蕩器&#xff0c;在不同的應用場景中發揮著關鍵作用&#xff0c;它們的區別…

    基于SpringBoot的在線考試智能監控系統設計與實現

    目錄 一.&#x1f981;前言二.&#x1f981;開源代碼與組件使用情況說明三.&#x1f981;核心功能1. ?算法設計2. ?Java開發語言3. ?Vue.js框架4. ?部署項目 四.&#x1f981;演示效果1. 管理員模塊1.1 用戶管理 2. 教師模塊2.1 考試管理2.2 瀏覽試題列表2.3 添加試題2.4 成…