C#实现MCP Client 与 LLM 连接,抓取网页内容功能!

B站影视 日本电影 2025-05-23 18:30 2

摘要:添加依赖库:Microsoft.Extensions.AI.OpenAI,版本为:最新预发行版 9.4.4-preview.1.25259.16,添加的时候记得勾选:包括预发行版。

前面的课程,我们已经用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。

新增文件:ChatAIClient

初始化OpenAI客户端,并使用UseFunctionInvocation 来增强客户端, 这里启用函数调用。

备注:以下代码涉及的秘钥,记得替换为自己的。

using Microsoft.Extensions.AI;using OpenAI;using System.ClientModel;namespace MCPClient{ /// /// 表示一个用于与 AI 聊天模型交互的客户端封装类。 /// 负责初始化聊天客户端并维护对话上下文。 /// public class ChatAIClient { /// /// 封装后的 AI 聊天客户端接口,支持函数调用等功能。 /// private IChatClient ChatClient; /// /// 存储当前会话中的所有聊天消息记录。 /// private IList Messages; /// /// API 访问密钥,用于身份认证。【记得替换为自己的】 /// private const string _apiKey = "6092598c-ce00-48fd-a5be-0d758088c888"; /// /// AI 服务的基础请求地址。【记得替换为自己的】 /// private const string _baseURL = "https://api-inference.modelscope.cn/v1/"; /// /// 使用的 AI 模型标识符。【记得替换为自己的】 /// private const string _modelID = "Qwen/Qwen2.5-72B-Instruct"; /// /// 初始化一个新的 实例。 /// 构造函数中自动完成聊天客户端的初始化配置。 /// public ChatAIClient { InitIChatClient; } /// /// 初始化内部使用的 AI 聊天客户端实例。 /// 配置 API 凭证、服务端点,并构建具备函数调用能力的客户端。 /// 同时初始化系统消息作为对话起点。 /// 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服务器功能,优先使用中文回答!"), ]; } }}

ChatAIClient文件,添加如下代码,实现与 AI 模型交互,并传入 MCP 工具。

/// /// 异步处理用户的自然语言查询,并与 AI 模型进行交互,支持 MCP 工具调用。/// ///

用户的自然语言查询内容

///

可用的 MCP 工具列表,用于扩展 AI 的外部能力

/// AI 返回的最终文本响应结果public async Task ProcessQueryAsync(string query, IList 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;}

ChatAIClient文件,添加如下代码,输出 AI 调用MCP 工具的情况。

/// /// 辅助方法:输出 AI 在响应中调用的工具信息到控制台。 /// ///

来自 AI 的完整响应对象

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; } }}

在前面课程基础之上,在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响应的结果:

好了,今天就分享到这边!

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

来源:编程乐趣一点号

相关推荐