讓AI再次偉大-MCP-Client開發指南

  • 👏作者簡介:大家好,我是愛吃芝士的土豆倪,24屆校招生Java選手,很高興認識大家
  • 📕系列專欄:Spring原理、JUC原理、Kafka原理、分布式技術原理、數據庫技術、JVM原理、AI應用
  • 🔥如果感覺博主的文章還不錯的話,請👍三連支持👍一下博主哦
  • 🍂博主正在努力完成2025計劃中:逆水行舟,不進則退
  • 📝聯系方式:nhs19990716,加我進群,大家一起學習,一起進步,一起對抗互聯網寒冬👀

文章目錄

  • 簡述
  • 環境準備
  • 創建client客戶端
    • 初始化
    • 封裝連接mcp-server函數
    • 處理用戶查詢的核心函數
      • 調用deepseek返回可用工具
      • 檢查模型響應中是否包含工具調用請求
      • 處理prompt模板
    • 啟動client客戶端

簡述

今天簡單聊聊mcp-client客戶端,并接入deepseek 模型,調用我們自己的mcp server,本篇是基于之前開發好的mcp-server進行的。并且使用python去實現mcp client的客戶端。

什么是mcp的客戶端呢?mcp的客戶端通俗易懂的來講,就像是一個翻譯官,它具備對英語或者漢語或其他語種的翻譯語種,語種可以理解為一個具體的ai模型,它可以幫助我們和mcp服務進行通信,就比如我們有一個專門用于天氣查詢的mcp服務,但是這個服務只會根據它熟悉的格式或者語言去查詢天氣,那么mcp客戶端就是把我們的自然語言,也就是普通的描述,比如你幫我查詢天氣,然后mcp客戶端會把這個普通語言翻譯成天氣查詢mcp服務理解的格式或者語言,最終將天氣查詢mcp服務返回的數據再翻譯成普通語言告訴我們,那么這個過程其實就是mcp客戶端 加 模型一起完成的,可以把mcp客戶端想象成翻譯官,那么它所掌握的某個語言,比如說漢語,英語其實就是模型。

環境準備

curl -LsSf https://astral.sh/uv/install.sh | sh
# 創建目錄
uv init mcp-clientcd mcp-client# 創建虛擬環境
uv env# 激活虛擬環境
source .venv/bin/activate# 安裝相關的依賴
uv add mcp anthropic python-dotenv# 創建一個程序入口文件
touch client.py
# 創建環境變量文件,用于存儲模型的api key
touch .envAPI_KEY = 去deepseek官網申請即可
BASE_URL = 去官網查即可
MODEL_NAME = 去官網搜模型名稱 使用的是deepseek v3,因為官網的文檔里明確說了r1不支持function call

創建client客戶端

初始化

# 用于導入異步IO庫,用于支持異步編程
import asyncio 
# 用于導入JSON庫,用于處理JSON數據
import json
# 用于處理命令行參數
import sys 
# 用于類型提示功能
from typing import Optional 
# 異步資源管理器,用于管理多個異步資源
from contextlib import AsyncExitStack # MCP 客戶端相關導入
# 導入 MCP 客戶端會話和標準輸入輸出服務器參數
from mcp import ClientSession, StdioServerParameters 
# 導入標準輸入輸出客戶端通信模塊
from mcp.client.stdio import stdio_client 
# Openai SDK
from openai import OpenAI # 環境變量加載相關
# 導入環境變量加載工具
from dotenv import load_dotenv 
# 用于獲取環境變量值
import os # 加載 .env 文件中的環境變量
load_dotenv()  # 定義 MCP 客戶端類
class DeepSeekMCPClient:"""使用 DeepSeek V3 API 的 MCP 客戶端類處理 MCP 服務器連接和 DeepSeek V3 API 的交互這個類就像是一個翻譯官,一方面與MCP服務器進行通信,另一方面與DeepSeek API進行通信,幫助用戶通過自然語言來使用各種強大的工具"""def __init__(self):""" 初始化MCP客戶端的各項屬性主要設置了三個重要組件:- session: 用于與MCP服務器通信的會話- exit_stack: 用于管理異步資源的上下文管理器,確保資源正確釋放,那么在與 MCP 服務通信時,它會負責接收和發送通信數據- llm_client: DeepSeek API 的客戶端,使用 OpenAI 的 SDK"""# MCP 客戶端會話,初始值為 Noneself.session: Optional[ClientSession] = None# 創建異步資源管理器,用于管理多個異步資源self.exit_stack = AsyncExitStack()# 初始化 DeepSeek API 客戶端self.llm_client = OpenAI(api_key=os.getenv("API_KEY"), # 從環境變量中獲取 API 密鑰base_url=os.getenv("BASE_URL") # 從環境變量中獲取 API 基礎 URL)# 從環境變量獲取模型名稱self.model = os.getenv("MODEL")

封裝連接mcp-server函數

async def connect_to_server(self, server_script_path: str):"""連接到MCP服務這個函數就像是撥通電話,建立與 MCP 服務器的連接,它會根據服務腳本的類型(Python 或 JavaScript)選擇正確的命令啟動服務器,然后與之建立通信。參數:server_script_path: MCP 服務腳本路徑,支持 Python(.py) 或 Node.js(.js) 文件異常:ValueError: 如果服務器腳本不是.py或.js文件"""# 檢查腳本類型is_python = server_script_path.endswith('.py') # 判斷是否是 Python 腳本is_js = server_script_path.endswith('.js') # 判斷是否是 JavaScript 腳本if not (is_python or is_js): # 如果腳本類型不是 Python 或 JavaScript,則拋出異常raise ValueError("服務器腳本必須是 .py 或 .js 文件")# 根據腳本類型選擇正確的運行命令command = "python" if is_python else "node" # Python 使用 python 運行,JavaScript 使用 node 運行# 設置服務器啟動參數,那么 server_params 最終會生成類似于 Python xxx.py 這種運行命令server_params = StdioServerParameters(command=command, # 要執行的命令(python 或 node)args=[server_script_path], # 要執行的命令的參數(腳本路徑)env=None # 環境變量, 使用 None 表示繼承當前環境變量)# 創建標準輸入輸出通信信道stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))# 解構對象中的讀寫通信,分別用于向MCP服務接收和發送數據self.stdio, self.write = stdio_transport# 創建MCP客戶端會話self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))# 初始化MCP客戶端會話await self.session.initialize() # 初始化會話,準備好與MCP服務進行通信# 列出可用的工具# 獲取 MCP 服務提供的工具列表response = await self.session.list_tools()# 獲取工具列表tools = response.tools# 打印工具列表print("\n已連接到MCP服務,可用的工具列表:", [tool.name for tool in tools])

這個函數的作用就是通過命令運行一個mcp-server,然后使用mcp-client客戶端連接這個mcp-server,要保持一個會話狀態,然后我們就可以通過這個session去請求到這個mcp-server了,然后去獲取到這個mcp-server所提供的工具tools了

處理用戶查詢的核心函數

async def process_query(self, query: str) -> str:"""處理用戶查詢,根據查詢參數使用DeepSeek V3和MCP工具這個函數就是整個系統的核心,他就像一個指揮官,它接收用戶的問題,然后再把問題交給AI模型然后模型決定使用哪些工具,然后告訴 MCP Client 去調用這些工具。然后獲取到工具結果再返回給模型,模型根據工具結果生成最終的回答。整個過程就像是:用戶提問->模型判斷->MCP Client 使用工具->返回工具結果->模型根據工具結果生成回答參數:query: 用戶的問題返回:str: 處理后的最終響應的文本"""# 創建消息列表,用于存儲用戶的問題和模型的回答messages = [{# 系統角色,用于設定AI的行為準則"role": "system", "content": "你是一個專業的助手,可以通過調用合適的工具來幫助用戶解決問題,請根據用戶的需求選擇最合適的工具。"},{# 用戶角色,表示這是用戶發送的消息"role": "user", "content": query}]# 請求 MCP 服務獲取服務提供的工具列表response = await self.session.list_tools()# 獲取工具列表tools = response.tools# 構建工具信息數組,我們需要把工具信息轉換成 DeepSeek API 需要的格式available_tools = [{"type": "function", # 工具類型,表示這是一個函數工具"function": { # 工具的詳細定義"name": tool.name, # 工具名稱"description": tool.description, # 工具描述"parameters": tool.inputSchema # 工具參數}} for tool in tools]# 打印可用工具信息,便于調試print(f"當前 MCP 服務所有工具列表: {available_tools}\n--------------------------------\n")

調用deepseek返回可用工具

# 調用 DeepSeek API,發送用戶查詢和可用工具信息,
# 告訴 DeepSeek API 根據用戶提問你可以使用哪些工具,最終返回可調用的工具
response = self.llm_client.chat.completions.create(# 指定的模型名稱model=self.model, # 消息歷史(系統提示和用戶問題)messages=messages, # 可用的工具列表tools=available_tools if available_tools else None, # 溫度參數,控制響應的隨機性(0.5是中等隨機性)temperature=0.5, # 最大生成令牌數,限制響應長度max_tokens=4096 
)
# 打印模型響應,便于調試
print(f"DeepSeek API 響應: {response}\n--------------------------------\n")# 獲取模型的回復,包含 role(消息發送者) 和 
# content(消息內容) 以及 tool_calls(工具調用請求)
reply = response.choices[0].message # 獲取模型的回答# 打印模型的回答
print(f"DeepSekk 初始回復: {reply}\n--------------------------------\n")# 初始化最終文本結果列表
final_text = []# 將模型回復添加到歷史消息中,用于維護完整的對話歷史
# 這一步非常重要,確保模型 記得 自己之前決定使用什么工具,
# 即使模型沒有請求調用工具,也要保持對話連貫性。
messages.append(reply)

檢查模型響應中是否包含工具調用請求

# 檢查模型響應中是否包含工具調用請求,如果用戶的問題涉及到使用工具,
# 那就會包含 tool_calls 字段,否則就沒有
if hasattr(reply, "tool_calls") and reply.tool_calls:# 遍歷所有工具調用請求for tool_call in reply.tool_calls:# 獲取工具名稱tool_name = tool_call.function.name# 獲取工具參數try:# 嘗試將工具的參數從 JSON 字符串解析為 Python 字典tool_args = json.loads(tool_call.function.arguments)except json.JSONDecodeError:tool_args = {}# 打印工具調用信息,便于調試print(f"準備調用工具: {tool_name} 參數: {tool_args}\n--------------------------------\n")# 異步調用 MCP 服務上的工具,傳入工具名稱和函數參數,返回工具函數執行結果result = await self.session.call_tool(tool_name, tool_args)# 打印工具執行結果,便于調試print(f"工具 {tool_name} 執行結果: {result}\n--------------------------------\n")# 將工具調用信息添加到最終輸出文本中,便于用戶了解執行過程final_text.append(f"調用工具: {tool_name}, 參數: {tool_args}\n")# 確保工具結果是字符串格式tool_result_content = result.contentif isinstance(tool_result_content, list):# 如果工具結果是列表,則將列表中的每個元素轉換為字符串并添加到最終文本中text_content = ""for item in tool_result_content:if hasattr(item, 'text'):text_content += item.texttool_result_content = text_contentelif not isinstance(tool_result_content, str):# 如果不是字符串,則轉換為字符串tool_result_content = str(tool_result_content)# 打印工具返回結果print(f"工具返回結果(格式化后): {tool_result_content}\n--------------------------------\n")# 將工具調用結果添加到歷史消息中,保證與模型會話的連貫性tool_message = {# 工具角色,表示這是工具返回的結果"role": "tool", # 工具調用ID"tool_call_id": tool_call.id,# 工具返回的結果"content": tool_result_content, }# 打印消息內容print(f"添加到歷史消息中的工具消息: {tool_message}\n--------------------------------\n")# 添加到歷史消息中messages.append(tool_message)# 再次調用 DeepSeek API,讓模型根據工具結果生成最終的回答try:print("正在請求 DeepSeek API 生成最終回答...")# 發送包含工具調用和結果的完整消息歷史final_response = self.llm_client.chat.completions.create(model=self.model, # 指定的模型名稱messages=messages, # 消息歷史(系統提示和用戶問題)temperature=0.5, # 溫度參數,控制響應的隨機性(0.5是中等隨機性)max_tokens=4096 # 最大生成令牌數,限制響應長度)# 添加 DeepSeek 對工具結果的解釋然后到最終輸出final_content = "DeepSeek回答:" + final_response.choices[0].message.contentif final_content:# 如果模型生成了對工具結果的解釋,就將其添加到最終輸出數組中final_text.append(final_content)else:print("警告:DeepSeek API 沒有生成任何內容。")# 如果沒用內容,直接顯示工具結果final_text.append(f"工具調用結果:\n{tool_result_content}")except Exception as e:print(f"生成最終回復時出錯: {e}")final_text.append(f"工具返回結果:\n{tool_result_content}")
else:# 如果模型沒有請求調用工具,那么就直接返回模型的內容if reply.content:# 將模型的直接回復添加到最終輸出數組final_text.append(f"{reply.content}")else:# 如果模型沒有生成內容,則添加提示信息final_text.append("模型沒有生成有效回復。")# 我們把用戶的問題和MCP服務可用工具全部給到 DeepSeek,# DeepSeek 判斷出具體需要調用哪個工具,然后讓 MCP Client 去調用這個工具,# 然后我們再把工具函數返回的結果給到 DeepSeek,# 讓 DeepSeek 根據工具結果生成最終的回答# 返回最終的回答return '\n'.join(final_text)

上面的代碼中其實針對于沒有使用mcp-server的 prompt功能的tool已經可以了,但是我們在開發 mcp-server demo的時候其實是知道可以配置prompt的,但是實際上我們并沒有根據tool調用的返回去處理 prompt模板。

處理prompt模板

# 嘗試解析工具返回的JSON結果,檢查是否包含MCP模板結構
try:# 將工具返回結果 JSON格式 轉換為 Python 字典tool_result_json = json.loads(tool_result_content)# 檢查是否包含 MCP 模板結構(具有 prompt_template 和 template_args 字段)if(isinstance(tool_result_json, dict) and "prompt_template" in tool_result_json and "template_args" in tool_result_json):raw_data = tool_result_json["raw_data"] # 原始數據prompt_template = tool_result_json["prompt_template"] # 模板函數名稱template_args = tool_result_json["template_args"] # 模板參數# 將模板參數轉換為字符串類型(MCP規范要求)string_args = {k:str(v) for k,v in template_args.items()}# 打印模板參數print(f"模板名稱: {prompt_template}, 模板參數: {string_args}\n--------------------------------\n")# 調用 MCP 服務上的工具,傳入工具名稱和函數參數,返回工具函數執行結果template_response = await self.session.get_prompt(prompt_template, string_args)# 打印工具執行結果,便于調試print(f"模板響應: {template_response}\n--------------------------------\n")if hasattr(template_response, "messages") and template_response.messages:# 打印模板響應print(f"模板具體的信息: {template_response.messages}\n--------------------------------\n")for msg in template_response.messages:# 提取消息內容content = msg.content.text if hasattr(msg.content, "text") else msg.content# 構建歷史信息template_message = {"role": msg.role, # 保持原始角色"content": content # 消息內容}print(f"模板消息歷史: {template_message}\n--------------------------------\n")# 添加到歷史消息中messages.append(template_message)else:print("警告:模板響應中沒有包含消息內容。")
except json.JSONDecodeError:pass# 再次調用 DeepSeek API,讓模型根據工具結果生成最終的回答try:print("正在請求 DeepSeek API 生成最終回答...")# 發送包含工具調用和結果的完整消息歷史final_response = self.llm_client.chat.completions.create(model=self.model, # 指定的模型名稱messages=messages, # 消息歷史(系統提示和用戶問題)temperature=0.5, # 溫度參數,控制響應的隨機性(0.5是中等隨機性)max_tokens=4096 # 最大生成令牌數,限制響應長度)# 添加 DeepSeek 對工具結果的解釋然后到最終輸出final_content = "DeepSeek回答:" + final_response.choices[0].message.contentif final_content:# 如果模型生成了對工具結果的解釋,就將其添加到最終輸出數組中final_text.append(final_content)else:print("警告:DeepSeek API 沒有生成任何內容。")# 如果沒用內容,直接顯示工具結果final_text.append(f"工具調用結果:\n{tool_result_content}")except Exception as e:print(f"生成最終回復時出錯: {e}")final_text.append(f"工具返回結果:\n{tool_result_content}")

啟動client客戶端

async def chat_loop(self):"""運行交互式聊天循環,處理用戶輸入并顯示回復這個函數就是一個簡單的聊天界面,不斷接收用戶輸入,處理問題,并顯示回答,直到用戶輸入'quit'退出。"""print("\nDeepSeek MCP 客戶端已經啟動!")print("請輸入你的問題,輸入'quit'退出。")# 循環處理用戶輸入while True:try:# 獲取用戶輸入query = input("\n問題: ").strip()# 檢查是否要退出if query.lower() == 'quit':break# 處理用戶輸入,傳入到查詢函數中response = await self.process_query(query)print("\n" + 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("用法: python client.py <服務器腳本路徑>")sys.exit(1) # 如果參數不足,顯示使用說明并退出# 創建客戶端實例client = DeepSeekMCPClient()try:# 連接到MCP服務器await client.connect_to_server(sys.argv[1])# 啟動聊天循環await client.chat_loop()finally:# 清理資源,確保在任何情況下都清理資源await client.cleanup()# 程序入口點
if __name__ == "__main__":# 運行主函數asyncio.run(main())# 使用說明
# 激活虛擬環境(如果尚未激活)
# source .venv/Scripts/activate# 運行 MCP 客戶端,連接到天氣查詢 MCP 服務器(示例)
# uv run client.py D:\\開源MCP項目\\weather\\weather.py

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

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

相關文章

供應鏈管理:計算題 / 倒扣法

一、理解倒扣法 在供應鏈管理中&#xff0c;倒扣法是一種常用的成本計算方法&#xff0c;主要用于確定商品的成本和銷售價格&#xff0c;以確保特定的毛利率。倒扣法的基本原理是在已知售價和期望毛利率的情況下&#xff0c;逆推計算出供貨價或成本價。 二、倒扣法的計算公式…

skynet.start 的作用詳細解析

目錄 skynet.start 的作用詳細解析1. 功能概述2. 基本用法3. 關鍵作用(1) 注冊消息處理函數(2) 啟動事件循環(3) 服務生命周期管理 4. 與其他函數的協作5. 未調用 skynet.start 的后果6. 高級場景&#xff1a;何時不需要 skynet.start7. 總結 skynet.start 的作用詳細解析 在 …

基于yolo11的BGA圖像目標檢測

1.產生圖像數據的分辨率 2.產生圖像的大小 3.產生圖像是黑白或是RGB彩色 灰度圖像&#xff0c;達到識別要求&#xff0c;減少計算量 4.標注數據的精準程度 1.模型標注后&#xff0c;少量標注全部人工校驗&#xff0c;大量數據抽檢&#xff0c;部分人工檢驗 2.明確邊界框貼合…

PADS 9.5【附破解文件+安裝教程】中文激活版下載

第1步 將軟件安裝包下載到電腦本地&#xff0c;使用解壓工具進行解壓打開&#xff08;全程關閉殺毒軟件以及防火墻&#xff0c;避免破解文件被刪除&#xff09; 第2步 鼠標右鍵以管理員身份運行“PADS9.5_mib.exe” 第3步 加載片刻后&#xff0c;彈出如圖界面&#xff0c;點擊N…

電子電氣架構 --- SOC設計流程及其集成開發環境

我是穿拖鞋的漢子&#xff0c;魔都中堅持長期主義的汽車電子工程師。 老規矩&#xff0c;分享一段喜歡的文字&#xff0c;避免自己成為高知識低文化的工程師&#xff1a; 周末洗了一個澡&#xff0c;換了一身衣服&#xff0c;出了門卻不知道去哪兒&#xff0c;不知道去找誰&am…

圖撲 HT 電纜廠 3D 可視化管控系統深度解析

在當今數字化浪潮席卷制造業的大背景下&#xff0c;圖撲軟件&#xff08;Hightopo&#xff09;憑借其自主研發的強大技術&#xff0c;為電纜廠打造了一套先進的 3D 可視化管控系統。該系統基于 HT for Web 技術&#xff0c;為電纜廠的數字化轉型提供了有力支撐。 HT 技術核心架…

【數據結構】鄰接矩陣完全指南:原理、實現與稠密圖優化技巧?

鄰接矩陣 導讀一、圖的存儲結構1.1 分類 二、鄰接矩陣法2.1 鄰接矩陣2.2 鄰接矩陣存儲網 三、鄰接矩陣的存儲結構四、算法評價4.1 時間復雜度4.2 空間復雜度 五、鄰接矩陣的特點5.1 特點1解析5.2 特點2解析5.3 特點3解析5.4 特點4解析5.5 特點5解析5.6 特點6解析 結語 導讀 大…

Docker Registry 清理鏡像最佳實踐

文章目錄 registry-clean1. 簡介2. 功能3. 安裝 docker4. 配置 docker5. 配置域名解析6. 部署 registry7. Registry API 管理8. 批量清理鏡像9. 其他10. 參考registry-clean 1. 簡介 registry-clean 是一個強大而高效的解決方案,旨在簡化您的 Docker 鏡像倉庫管理。通過 reg…

UART雙向通信實現(序列機)

前言 UART&#xff08;通用異步收發傳輸器&#xff09;是一種串行通信協議&#xff0c;用于在電子設備之間進行數據傳輸。RS232是UART協議的一種常見實現標準&#xff0c;廣泛應用于計算機和外圍設備之間的通信。它定義了串行數據的傳輸格式和電氣特性&#xff0c;以確…

機器學習算法分類全景解析:從理論到工業實踐(2025新版)

一、機器學習核心定義與分類框架 1.1 機器學習核心范式 機器學習本質是通過經驗E在特定任務T上提升性能P的算法系統&#xff08;Mitchell定義&#xff09;。其核心能力體現在&#xff1a; 數據驅動決策&#xff1a;通過數據自動發現模式&#xff0c;而非顯式編程&#xff08…

perf?命令詳解

?perf 命令詳解? perf 是 Linux 系統中最強大的 ?性能分析工具?&#xff0c;基于內核的 perf_events 子系統實現&#xff0c;支持硬件性能計數器&#xff08;PMC&#xff09;、軟件事件跟蹤等功能&#xff0c;用于定位 CPU、內存、I/O 等性能瓶頸。以下是其核心用法與實戰…

【大模型基礎_毛玉仁】6.4 生成增強

目錄 6.4 生成增強6.4.1 何時增強1&#xff09;外部觀測法2&#xff09;內部觀測法 6.4.2 何處增強6.4.3 多次增強6.4.4 降本增效1&#xff09;去除冗余文本2&#xff09;復用計算結果 6.4 生成增強 檢索器得到相關信息后&#xff0c;將其傳遞給大語言模型以期增強模型的生成能…

Leetcode 合集 -- 排列問題 | 遞歸

題目1 子集2 思路 代碼 題目2 全排列2 思路 代碼 題目3 排列總和 思路 代碼 題目4 排列總和2 思路 代碼

vue-office 支持預覽多種文件(docx、excel、pdf、pptx)預覽的vue組件庫

官網地址&#xff1a;https://github.com/501351981/vue-office 支持多種文件(docx、excel、pdf、pptx)預覽的vue組件庫&#xff0c;支持vue2/3。也支持非Vue框架的預覽。 1.在線預覽word文件&#xff08;以及本地上傳預覽&#xff09; 1.1&#xff1a;下載組件庫 npm inst…

【trino】trino配置證書https tls/ssl訪問

trini版本470 一、官方文檔 doc 在Security/TLS and HTTPS、Security/PEM files和Security/JKS files下 openssl文檔 二、配置trino 2.1 創建server.cnf文件 [ req ] distinguished_name req_distinguished_name req_extensions v3_req[ req_distinguished_name ] coun…

ZCC8702,LED驅動芯片的“六邊形戰士”可替代SY8707

在LED照明的璀璨舞臺上&#xff0c;驅動芯片猶如幕后英雄&#xff0c;默默掌控著燈光的閃耀與變幻。ZCC8702作為一款集大成的LED驅動芯片&#xff0c;憑借其卓越的性能、廣泛的應用范圍和出色的穩定性&#xff0c;成為了這個領域中當之無愧的“六邊形戰士”。今天&#xff0c;就…

Vue 數據傳遞流程圖指南

今天&#xff0c;我們探討一下 Vue 中的組件傳值問題。這不僅是我們在日常開發中經常遇到的核心問題&#xff0c;也是面試過程中經常被問到的重要知識點。無論你是初學者還是有一定經驗的開發者&#xff0c;掌握這些傳值方式都將幫助你更高效地構建和維護 Vue 應用 目錄 1. 父…

Git Restore 命令詳解與實用示例

文章目錄 Git Restore 命令詳解與實用示例1. 恢復工作區文件到最后一次提交的狀態基本命令示例恢復所有更改 2. 恢復某個文件到特定提交的狀態基本命令示例 3. 恢復暫存區的文件基本命令示例恢復所有暫存的文件 git restore 的常見選項git restore 與 git checkout 比較總結 Gi…

AI 防口誤指南_LLM 輸出安全實踐

在數字化轉型的浪潮中&#xff0c;大語言模型(以下統稱LLM)已成為企業技術棧中不可或缺的智能組件&#xff0c;這種強大的AI技術同時也帶來了前所未有的安全挑戰。它輸出的內容如同雙面刃&#xff0c;一面閃耀著效率與創新的光芒&#xff0c;另一面卻隱藏著"幻覺"與不…

程序化廣告行業(55/89):DMP與DSP對接及數據統計原理剖析

程序化廣告行業&#xff08;55/89&#xff09;&#xff1a;DMP與DSP對接及數據統計原理剖析 大家好呀&#xff01;在數字化營銷的大趨勢下&#xff0c;程序化廣告已經成為眾多企業實現精準營銷的關鍵手段。上一篇博客我們一起學習了程序化廣告中的人群標簽和Look Alike原理等知…