該專欄優先在飛書發布,歡迎收藏關注!
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