在AI快速发展的时代,越来越多的开发者希望将智能对话功能集成到自己的应用中。本文将详细介绍如何使用C#和Microsoft Semantic Kernel框架连接DeepSeek AI服务,构建一个功能完善的聊天应用。文章包含完整代码示例和详细注释,适合有基础C#知识的开发者学习。这个库NB的就是支持所有大模型,不过有些地方要调整一下。
我们将构建一个控制台应用程序,支持以下功能:
使用的核心技术和库:
首先,创建一个新的控制台应用程序,并安装必要的NuGet包:
Bashdotnet add package Microsoft.SemanticKernel dotnet add package Microsoft.SemanticKernel.Connectors.OpenAI dotnet add package Microsoft.Extensions.Hosting
需要获取DeepSeek API的访问密钥,可以通过DeepSeek官方网站注册获取。
下面是一个完整的聊天应用实现,包含详细注释:
C#using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel;
using System.Net.Http;
using OpenAI;
using System.ClientModel;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using OpenAI.Chat;
using System.Collections.Generic;
using System.Text;
namespace AppMultimodal
{
internal class Program
{
// 最大保存的对话轮数,防止历史记录过长
private const int MaxConversationTurns = 10;
static async Task Main(string[] args)
{
try
{
// 使用Host Builder模式配置应用
var builder = Host.CreateApplicationBuilder(args);
// 从配置文件或环境变量加载API密钥
// 实际使用时请替换为自己的API密钥或通过环境变量配置
builder.Configuration.AddEnvironmentVariables();
var apiKey = builder.Configuration["OpenAI:ApiKey"] ?? "sk-替换为你的API密钥";
// 配置OpenAI客户端凭证
var openAIClientCredential = new ApiKeyCredential(apiKey);
var openAIClientOption = new OpenAIClientOptions
{
// 这里使用DeepSeek的API端点
Endpoint = new Uri("https://api.deepseek.com/v1")
};
// 创建OpenAI客户端
var openaiClient = new OpenAIClient(openAIClientCredential, openAIClientOption);
// 注册服务,指定模型名称
builder.Services.AddOpenAIChatCompletion("deepseek-chat", openaiClient);
var host = builder.Build();
// 启动聊天循环
await RunChatLoopAsync(openaiClient);
}
catch (Exception ex)
{
// 全局异常处理
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"发生错误: {ex.Message}");
Console.ResetColor();
}
}
/// <summary>
/// 运行聊天主循环,处理用户输入并获取AI响应
/// </summary>
static async Task RunChatLoopAsync(OpenAIClient openaiClient)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("DeepSeek: 你好,有什么是我能帮你的吗?");
// 初始化聊天历史
List<ChatMessage> chatHistory = new List<ChatMessage>();
var systemContent = ChatMessage.CreateSystemMessage("你是我的助手");
chatHistory.Add(systemContent);
// 设置聊天参数
var settingOptions = new ChatCompletionOptions
{
MaxOutputTokenCount = 2048, // 限制输出长度
Temperature = 0.7f, // 控制回答的创造性,值越高创造性越强
};
// 获取聊天客户端
var client = openaiClient.GetChatClient("deepseek-chat");
// 聊天循环
while (true)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("你: ");
var userInput = Console.ReadLine();
// 空输入退出
if (string.IsNullOrEmpty(userInput))
break;
// 处理用户消息
await ProcessUserMessageAsync(userInput, chatHistory, client, settingOptions);
}
}
/// <summary>
/// 处理用户输入消息,发送到AI并获取响应
/// </summary>
static async Task ProcessUserMessageAsync(string userInput, List<ChatMessage> chatHistory,
OpenAI.Chat.ChatClient client, ChatCompletionOptions options)
{
try
{
// 添加用户消息到历史
var inputMsg = ChatMessage.CreateUserMessage(userInput);
chatHistory.Add(inputMsg);
// 管理对话历史长度,防止内存溢出
ManageChatHistorySize(chatHistory);
Console.ForegroundColor = ConsoleColor.White;
Console.Write("DeepSeek: ");
// 流式接收并显示回复
var response = StreamAndDisplayResponse(client, chatHistory, options);
// 添加助手回复到历史
var assistantMsg = ChatMessage.CreateAssistantMessage(response);
chatHistory.Add(assistantMsg);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"处理消息时出错: {ex.Message}");
Console.ResetColor();
}
}
/// <summary>
/// 流式获取并显示AI响应,实现打字机效果
/// </summary>
static string StreamAndDisplayResponse(OpenAI.Chat.ChatClient client,
List<ChatMessage> chatHistory, ChatCompletionOptions options)
{
// 使用流式API获取响应
var clientResult = client.CompleteChatStreaming(chatHistory, options);
StringBuilder sb = new StringBuilder();
try
{
// 遍历流式响应的每个部分
foreach (var item in clientResult)
{
var text = item.ContentUpdate.FirstOrDefault()?.Text ?? string.Empty;
sb.Append(text);
Console.Write(text); // 实时显示,创造打字机效果
}
Console.WriteLine();
return sb.ToString();
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"\n获取回复时出错: {ex.Message}");
Console.ResetColor();
return $"抱歉,获取回复时发生错误。";
}
}
/// <summary>
/// 管理聊天历史大小,防止过长导致token超限或内存问题
/// </summary>
static void ManageChatHistorySize(List<ChatMessage> chatHistory)
{
// 保留系统消息和最近的对话
if (chatHistory.Count > MaxConversationTurns * 2 + 1) // +1 是为系统消息
{
// 保留系统消息
var systemMsg = chatHistory[0];
// 移除最早的用户-助手对话对
chatHistory.RemoveRange(1, 2);
// 确保系统消息仍在第一位
if (chatHistory[0] != systemMsg)
{
chatHistory.Insert(0, systemMsg);
}
}
}
}
}

C#var builder = Host.CreateApplicationBuilder(args);
// 从配置或环境变量加载API密钥
builder.Configuration.AddEnvironmentVariables();
var apiKey = builder.Configuration["OpenAI:ApiKey"] ?? "sk-替换为你的API密钥";
// 配置OpenAI客户端
var openAIClientCredential = new ApiKeyCredential(apiKey);
var openAIClientOption = new OpenAIClientOptions
{
Endpoint = new Uri("https://api.deepseek.com/v1")
};
这段代码使用Host Builder模式配置应用,从环境变量或默认值获取API密钥,并设置DeepSeek的API端点。
C#static async Task RunChatLoopAsync(OpenAIClient openaiClient)
{
// 初始化聊天历史
List<ChatMessage> chatHistory = new List<ChatMessage>();
var systemContent = ChatMessage.CreateSystemMessage("你是我的助手");
chatHistory.Add(systemContent);
// ...聊天循环代码...
}
此方法初始化聊天历史并设置系统提示,这决定了AI助手的行为和角色定位。您可以根据需要修改系统提示,例如"你是一位专业的客服代表"或"你是一位编程导师"等。
C#static string StreamAndDisplayResponse(OpenAI.Chat.ChatClient client,
List<ChatMessage> chatHistory, ChatCompletionOptions options)
{
var clientResult = client.CompleteChatStreaming(chatHistory, options);
StringBuilder sb = new StringBuilder();
foreach (var item in clientResult)
{
var text = item.ContentUpdate.FirstOrDefault()?.Text ?? string.Empty;
sb.Append(text);
Console.Write(text); // 实时显示
}
// ...其余代码...
}
这段代码实现了流式响应处理,让AI回复像人类一样逐字显示,而不是一次性返回全部内容。这种交互更自然,特别是对于长回复。
C#static void ManageChatHistorySize(List<ChatMessage> chatHistory)
{
if (chatHistory.Count > MaxConversationTurns * 2 + 1)
{
// 保留系统消息
var systemMsg = chatHistory[0];
// 移除最早的对话
chatHistory.RemoveRange(1, 2);
// ...确保系统消息位置...
}
}
这个方法确保聊天历史不会无限增长,通过限制保留的对话轮数,防止token超限和内存问题。
可以通过更改系统消息来定制AI的行为风格:
C#// 技术顾问
var systemContent = ChatMessage.CreateSystemMessage(
"你是一位资深的技术顾问,专注于C#和.NET开发。提供专业、简洁和实用的建议。");
// 创意写作助手
var systemContent = ChatMessage.CreateSystemMessage(
"你是一位创意写作助手,善于提供生动、有创意的表达和新颖的想法。");
生产环境中,应避免在代码中硬编码API密钥,建议:
如果遇到API调用失败:
对于长时间无响应的情况:
C#// 添加超时设置
var openAIClientOption = new OpenAIClientOptions
{
Endpoint = new Uri("https://api.deepseek.com/v1"),
NetworkTimeout = TimeSpan.FromSeconds(60) // 设置60秒超时
};
本文详细介绍了如何使用C#和Semantic Kernel框架构建DeepSeek AI聊天应用。从基础设置到高级功能,提供了全面的指导和代码示例。通过本教程,开发者可以快速构建自己的AI聊天应用,并根据需求进行定制和扩展。
无论是构建客服机器人、智能助手还是创意写作工具,这套框架都能提供稳固的技术基础。希望本文对您的AI开发之旅有所帮助!
如有问题或建议,欢迎在评论区留言交流!
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!