C#實現MCP Client 與 LLM 連接,抓取網頁內容功能!

該專欄優先在飛書發布,歡迎收藏關注!

https://www.feishu.cn/community/article?id=7507084665509904403

前面的課程,我們已經用C#實現了,自己的MCP Client。

下面我們一起來實現,MCP Client與LLM 對接。

一、添加依賴庫

目前來說,絕大部分的大模型的API,都是遵循OpenAI的接口規范。

Microsoft.Extensions.AI 是微軟官方提供的一套 統一的 AI 抽象層 ,大大簡化 AI 模型在 .NET 應用中的集成。

添加依賴庫:Microsoft.Extensions.AI.OpenAI,版本為:最新預發行版 9.4.4-preview.1.25259.16**,添加的時候記得勾選:包括預發行版。**

圖片

添加依賴庫:Microsoft.Extensions.AI,版本為:9.4.4-preview.1.25259.16。

圖片

二、OpenAI 客戶端實現

新增文件:ChatAIClient

圖片

2.1 初始化OpenAI客戶端


初始化OpenAI客戶端,并使用UseFunctionInvocation 來增強客戶端, 這里啟用函數調用。

備注:以下代碼涉及的秘鑰,記得替換為自己的。

using?Microsoft.Extensions.AI;
using?OpenAI;
using?System.ClientModel;
namespace?MCPClient
{///?<summary>///?表示一個用于與 AI 聊天模型交互的客戶端封裝類。///?負責初始化聊天客戶端并維護對話上下文。///?</summary>public?class?ChatAIClient{///?<summary>///?封裝后的 AI 聊天客戶端接口,支持函數調用等功能。///?</summary>private?IChatClient ChatClient;///?<summary>///?存儲當前會話中的所有聊天消息記錄。///?</summary>private?IList<ChatMessage> Messages;///?<summary>///?API 訪問密鑰,用于身份認證。【記得替換為自己的】///?</summary>private?const?string?_apiKey =?"6092598c-ce00-48fd-a5be-0d758088c888";///?<summary>///?AI 服務的基礎請求地址。【記得替換為自己的】///?</summary>private?const?string?_baseURL =?"https://api-inference.modelscope.cn/v1/";///?<summary>///?使用的 AI 模型標識符。【記得替換為自己的】///?</summary>private?const?string?_modelID =?"Qwen/Qwen2.5-72B-Instruct";///?<summary>///?初始化一個新的?<see cref="ChatAIClient"/>?實例。///?構造函數中自動完成聊天客戶端的初始化配置。///?</summary>public?ChatAIClient(){InitIChatClient();}///?<summary>///?初始化內部使用的 AI 聊天客戶端實例。///?配置 API 憑證、服務端點,并構建具備函數調用能力的客戶端。///?同時初始化系統消息作為對話起點。///?</summary>private?void?InitIChatClient(){// 創建 API 密鑰憑證ApiKeyCredential apiKeyCredential =?new?ApiKeyCredential(_apiKey);// 設置 OpenAI 客戶端選項,如自定義服務端點OpenAIClientOptions openAIClientOptions =?new?OpenAIClientOptions();openAIClientOptions.Endpoint =?new?Uri(_baseURL);// 創建 OpenAI 客戶端并獲取指定模型的聊天接口var?openaiClient =?new?OpenAIClient(apiKeyCredential, openAIClientOptions).GetChatClient(_modelID).AsIChatClient();// 構建增強功能的聊天客戶端(例如啟用函數調用)ChatClient =?new?ChatClientBuilder(openaiClient).UseFunctionInvocation().Build();// 初始化對話歷史,包含一條系統提示信息Messages =[// 添加系統角色消息new(ChatRole.System,?"您是一位樂于助人的助手,幫助我們測試MCP服務器功能,優先使用中文回答!"),];}}
}

2.2 處理用戶的自然語言查詢


ChatAIClient文件,添加如下代碼,實現與 AI 模型交互,并傳入 MCP 工具。

///?<summary>
///?異步處理用戶的自然語言查詢,并與 AI 模型進行交互,支持 MCP 工具調用。
///?</summary>
///?<param name="query">用戶的自然語言查詢內容</param>
///?<param name="tools">可用的 MCP 工具列表,用于擴展 AI 的外部能力</param>
///?<returns>AI 返回的最終文本響應結果</returns>
public?async?Task<string>?ProcessQueryAsync(string?query, IList<McpClientTool> tools)
{// 如果消息歷史為空,則初始化系統提示消息if?(Messages.Count ==?0){Messages =?[new(ChatRole.System,?"您是一位樂于助人的助手,幫助我們測試MCP服務器功能,優先使用中文回答!")];}// 添加用戶輸入的消息到對話歷史Messages.Add(new(ChatRole.User, query));// 設置請求選項,注入可用工具var?options =?new?ChatOptions{Tools = [.. tools]};// 調用 AI 客戶端獲取響應var?response =?await?ChatClient.GetResponseAsync(Messages, options);// 將 AI 響應加入對話歷史Messages.AddMessages(response);// 輸出調用的工具信息OutputToolUsageInfo(response);// 返回模型生成的文本響應return?response.Text;
}

2.3 MCP 工具使用情況日志


ChatAIClient文件,添加如下代碼,輸出 AI 調用MCP 工具的情況。

?///?<summary>///?輔助方法:輸出 AI 在響應中調用的工具信息到控制臺。///?</summary>///?<param name="response">來自 AI 的完整響應對象</param>private?void?OutputToolUsageInfo(ChatResponse response){// 獲取所有 Tool 角色的消息var?toolUseMessages = response.Messages.Where(m => m.Role == ChatRole.Tool).ToList();// 判斷是否調用了工具// 獲取響應中所有角色為 Tool 的消息(即 AI 調用了哪些工具)var?toolUseMessage = response.Messages.Where(m => m.Role == ChatRole.Tool);// 判斷第一條消息的內容是否多于一個(通常第一個消息是用戶問題,第二個是調用函數)if?(response.Messages[0].Contents.Count >?1){// 嘗試從第一條消息的第二個內容項提取出函數調用信息var?functionCall = (FunctionCallContent)response.Messages[0].Contents[1];// 設置控制臺輸出顏色為綠色,用于突出顯示工具調用信息Console.ForegroundColor = ConsoleColor.Green;string?arguments =?"";// 如果函數調用包含參數,則拼接參數信息if?(functionCall.Arguments !=?null){foreach?(var?arg?in?functionCall.Arguments){arguments +=?$"{arg.Key}:{arg.Value};";}// 輸出調用的方法名及參數信息Console.WriteLine($"調用方法名:{functionCall.Name};參數信息:{arguments}");// 遍歷所有 Tool 消息,輸出每個工具調用的結果foreach?(var?message?in?toolUseMessage){// 提取工具調用后的執行結果var?functionResultContent = (FunctionResultContent)message.Contents[0];Console.WriteLine($"調用工具結果:{functionResultContent.Result}");}// 恢復控制臺默認顏色(白色)Console.ForegroundColor = ConsoleColor.White;}else{// 如果沒有參數Console.WriteLine("工具參數為空");}}else{Console.ForegroundColor = ConsoleColor.Green;Console.WriteLine("本次沒有調用工具");Console.ForegroundColor = ConsoleColor.White;}}
}

三、為LLM添加工具能力

在前面課程基礎之上,在Program.cs添加代碼。

圖片

**代碼說明:**為LLM添加工具能力,并處理客戶提交的內容。

// 創建聊天客戶端實例
ChatAIClient chatAIClient =?new?ChatAIClient();
// 進入主循環,持續接收用戶輸入直到輸入 "exit"
while?(true)
{try{// 設置控制臺文字顏色為黃色,提示用戶輸入問題Console.ForegroundColor = ConsoleColor.Yellow;Console.Write("\n提問: ");// 讀取用戶輸入并去除前后空格,若為空則賦默認空字符串string?query = Console.ReadLine()?.Trim() ???string.Empty;// 判斷用戶是否輸入 "exit" 以退出程序if?(query.ToLower() ==?"exit"){break;}// 調用異步方法處理用戶查詢,并傳入預定義的工具列表(listToolsResult)string?response =?await?chatAIClient.ProcessQueryAsync(query, listToolsResult);// 設置輸出顏色為黃色,顯示 AI 的響應內容Console.ForegroundColor = ConsoleColor.Yellow;Console.WriteLine($"AI:{response}");// 恢復控制臺默認顏色(白色)Console.ForegroundColor = ConsoleColor.White;}catch?(Exception ex){// 捕獲所有異常并輸出錯誤信息,防止程序崩潰Console.WriteLine($"\nError:?{ex.Message}");}
}

四、測試效果

===

啟動項目,并輸入以下內容:

抓取?https://blog.csdn.net/daremeself/article/details/147166987 的內容,并markdown格式輸出

調用MCP Server的工具的情況日志。

圖片

AI響應的結果:

圖片

好了,今天就分享到這邊!

下一個課程:實現自己的MCP Server。

**文中示例代碼:**https://pan.quark.cn/s/b5b8853200f9

- End -

推薦閱讀

VS Code + Cline + 魔搭MCP Server 實現抓取網頁內容。

C#實現自己的MCP Client

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

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

相關文章

并發編程(6)

指令重排序 指令重排序是指在程序執行過程中&#xff0c;為了提高性能&#xff0c;編譯器或處理器會對指令的執行順序進行重新排列。 指令重排序導致可見性消失 在多線程環境下&#xff0c;每個線程都有自己的工作內存&#xff0c;線程對變量的操作是在工作內存中進行的&…

鴻蒙倉頡開發語言實戰教程:頁面跳轉和傳參

前兩天分別實現了商城應用的首頁和商品詳情頁面&#xff0c;今天要分享新的內容&#xff0c;就是這兩個頁面之間的相互跳轉和傳遞參數。 首先我們需要兩個頁面。如果你的項目中還沒有第二個頁面&#xff0c;可以右鍵cangjie文件夾新建倉頡文件&#xff1a; 新建的文件里面沒什…

Java 學習筆記:注解、泛型與 IO 流

目錄 課程目標 Java 注解(Annotation) 1. 概念與作用 2. 自定義注解示例 3. JDK 內置注解 4.注釋 Java 泛型(Generics) 1. 基本語法 2. 通配符與上下限 3. 常見應用場景 Java IO 流 1. 流的分類1.File文件類 2. 字節流與字符流 3. 經典示例:文件拷貝 總結與…

git倉庫代碼操作

1、從gitee下載代碼提交到本地github倉庫&#xff0c;保留提交記錄 # 查看當前分支 git branch# 查看當前遠程倉庫 git remote -v# 確保所有更改已提交 git add . git commit -m "準備提交到GitLab"# 添加GitLab遠程倉庫 git remote add gitlab https://gitlab.com/…

Thinkphp6使用token+Validate驗證防止表單重復提交

htm頁面加 <input type"hidden" name"__token__" value"{:token()}" /> Validate 官方文檔 ThinkPHP官方手冊

Mcu_Bsdiff_Upgrade

系統架構 概述 MCU BSDiff 升級系統通過使用二進制差分技術&#xff0c;提供了一種在資源受限的微控制器上進行高效固件更新的機制。系統不傳輸和存儲完整的固件映像&#xff0c;而是只處理固件版本之間的差異&#xff0c;從而顯著縮小更新包并降低帶寬要求。 該架構遵循一個…

Spring Boot微服務架構(四):微服務的劃分原則

微服務劃分原則&#xff08;CRM系統案例說明&#xff09; 一、微服務劃分的核心原則 單一職責原則&#xff08;SRP&#xff09; 每個微服務只負責一個明確的業務功能服務邊界清晰&#xff0c;避免功能混雜便于獨立開發、測試和部署 業務領域驅動設計&#xff08;DDD&#xff0…

基于CNN卷積神經網絡的帶頻偏QPSK調制信號檢測識別算法matlab仿真

目錄 1.算法運行效果圖預覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 5.算法完整程序工程 1.算法運行效果圖預覽 (完整程序運行后無水印) 2.算法運行軟件版本 matlab2024b 3.部分核心程序 &#xff08;完整版代碼包含詳細中文注釋和操作步驟視頻&#xff09…

從機械應答到深度交互,移遠通信如何讓機器人“靈魂覺醒”?

你是否還在因機器人的“答非所問”而無奈&#xff0c;為它們的“反應慢半拍”而抓狂&#xff1f;別慌&#xff01;一場引領機器人實現“靈魂覺醒”的技術革命&#xff0c;正如同暗夜中悄然綻放的繁星&#xff0c;徹底顛覆人們對機器人的傳統認知。 5月20日&#xff0c;移遠通信…

軟件的技術架構、應用架構、業務架構、數據架構、部署架構

一、各架構定義 1. 技術架構&#xff08;Technical Architecture&#xff09; 定義&#xff1a;技術架構關注的是支撐系統運行的底層技術基礎設施和軟件平臺&#xff0c;包括硬件、操作系統、中間件、編程語言、框架、數據庫管理系統等技術組件的選擇和組合方式。它描述了系統…

HTML-前端

目錄 開始學習HTML 什么是 HTML? 剖析一個 HTML 元素 嵌套元素 塊級元素和內聯元素 空元素 屬性 為元素添加屬性 布爾屬性 省略包圍屬性值的引號 使用單引號還是雙引號&#xff1f; 剖析 HTML 文檔 HTML 中的空白 實體引用&#xff1a;在 HTML 中包含特殊字符 HT…

多態的總結

什么是多態&#xff1f; 答&#xff1a;多態是多種形態&#xff0c;是為了完成某種行為時&#xff0c;不同對象會產生不同的形態&#xff08;結合車票例子解釋&#xff09; 2. 什么是重載、重寫(覆蓋)、重定義(隱藏)&#xff1f; 答&#xff1a;重載的條件是&#xff1a;在同一…

VBA 讀取指定范圍內的單元格數據,生成csv文件

目錄 一. 需求二. 宏代碼三. 添加按鈕 一. 需求 ?有如下表格&#xff0c;現在想在Excel中添加一個按鈕 點擊按鈕之后&#xff0c;讀取該表格中的數據&#xff0c;生成csv文件將csv文件輸出到和Excel同級目錄 二. 宏代碼 Application.PathSeparator&#xff1a;路徑分隔符Cr…

【Code Agent Benchmark】論文分享No.15:TAU-Bench

論文名稱&#xff1a;τ-bench: A Benchmark for Tool-Agent-User Interaction in Real-World Domains 論文&#xff1a;https://arxiv.org/abs/2406.12045 機構&#xff1a;Sierra Github 鏈接&#xff1a;https://github.com/sierra-research/tau-bench# 簡介 相比于Swe-ben…

Linux下 使用 SSH 完成 Git 綁定 GitHub

文章目錄 1、檢查 SSH2、生成 SSH key3、添加 SSH key4、驗證綁定是否成功 1、檢查 SSH Git Bash 中輸入ssh命令&#xff0c;查看本機是否安裝 SSH&#xff1a; 2、生成 SSH key &#xff08;1&#xff09;輸入 ssh-keygen -t rsa 命令&#xff0c;表示我們指定 RSA 算法生…

Java 8 Stream 流操作全解析

文章目錄 **一、Stream 流簡介****二、Stream 流核心操作****1. 創建 Stream****2. 中間操作&#xff08;Intermediate Operations&#xff09;****filter(Predicate<T>)&#xff1a;過濾數據****1. 簡單條件過濾****2. 多條件組合****3. 過濾對象集合****4. 過濾 null 值…

Java——設計模式(Design Pattern)

設計模式&#xff08;Design Pattern&#xff09;是軟件開發中針對常見問題的經典解決方案&#xff0c;由 GoF&#xff08;Gang of Four&#xff09;在《設計模式&#xff1a;可復用面向對象軟件的基礎》一書中歸納為23 種模式&#xff0c;分為三大類&#xff1a;創建型模式、結…

python語法學習

1.python的類的定義 class Memory_Manager: 2.__init__ 方法 __init__ 是類的構造方法&#xff0c;用于初始化類的實例。 self 是類實例的引用&#xff0c;用于訪問類的屬性和方法。 3.方法定義 類中的方法是類的功能實現&#xff0c;通過 def 定義。 4.if __name__ __ma…

如何屏蔽mac電腦更新提醒,禁止系統更新(最新有效方法)

每次打開Mac電腦時&#xff0c;頻繁的系統更新提醒可能會對我們的工作和使用體驗造成干擾。為了屏蔽這些更新提醒并禁止系統自動更新&#xff0c;我們可以通過修改Hosts文件來實現。以下是詳細步驟和方法&#xff0c;幫助你徹底屏蔽macOS的更新提醒。 系統關閉了自動更新也是…

windows10重裝ssh無法下載

問題 windows10重裝之后&#xff0c;ssh每次都是由于連接的是流量計數的網絡無法下載。 解決方法 https://www.cnblogs.com/zhg1016/p/17353348.html