使用C#接入DeepSeek API实现自己的AI助手

发布时间:2025-02-16

过年期间DeepSeek非常火爆,这段时间用着官方的客户端访问,总是会提示“服务器繁忙,请稍后再试。”,本文介绍怎么通过接入DeepSeek的API实现自己的客户端。

DeepSeek开放平台获取 API Key

首先我们需要登录DeepSeek的开放平台,在开放平台上进行API Key的申请。

在浏览器中访问 https://platform.deepseek.com,即可进入开放平台,首页为”用量信息“,展示我们的用量和余额,并且以图表形式展示每天的使用情况。

https://static.scung.cn/a4850502-dc2b-47bf-9706-076307e77a47.png

点击菜单项”API Keys“,可以查看我们所有创建的API Key,点击页面上的“创建 API Key”按钮,在弹出的窗口中输入一个方便记忆的名称,点击“创建”即可。

https://static.scung.cn/2a1b2ca5-7be5-4529-bb5a-5a8ba11b415c.png

需要注意的是,当我们创建好 API Key 之后,需要复制一下,之后则无法重新查看,如果忘记的话只能删除重新创建。

接入

使用任意IDE创建一个新的 .Net 项目,根据文档我们先构建几个模型类,用来存储数据

// 消息类,用来承载发送和收到消息
class Message
{
    [JsonPropertyName("role")]
    public string Role { get; set; }
    [JsonPropertyName("content")]
    public string Content { get; set; }

}

// 请求类,用来发送请求
class ChatRequest
{
    [JsonPropertyName("model")]
    public string Model { get; }
    [JsonPropertyName("messages")]
    public List<Message> Messages { get; }
    [JsonPropertyName("plugins")]
    public string[] Plugins { get; }
    [JsonPropertyName("stream")]
    public bool Stream { get; }
    [JsonPropertyName("temperature")]
    public double Temperature { get; }

    public ChatRequest(string model, List<Message> messages, string[] plugins, bool stream, double temperature)
    {
        Model = model;
        Messages = messages;
        Plugins = plugins;
        Stream = stream;
        Temperature = temperature;
    }
}

响应类型比较复杂,先不使用模型类,到时候直接通过解析 json 数据获取。

接下来开始发送请求。使用 HttpClient 来操作。DeepSeek可以启用流式输出,如果不启用流式输出,在发送请求之后,DeepSeek会把回答的所有内容都生成完毕之后才会返回,需要很长时间的等待,效果不太友好,启用流式输出之后,DeepSeek会在生成token之后立即返回,呈现的效果就是逐字回答。

下面的代码中启用了流式输出,对于流式输出,需要多加几个判断,比如在返回有效 token 时,DeepSeek会加上 data; 前缀,当生成停止时,DeepSeek会发送 [DONE],在生成卡顿时则会发送 keep-alive 来告诉客户端继续等待。

string apiKey = "sk-********************"; // 替换为你的 API 密钥
string apiUrl = "https://api.deepseek.com/v1/chat/completions";

using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");

var messages = new List<Message>() {
  new Message{ Role = "system", Content = "你是一个编程助手。" }
};

while (true)
{
    Console.ForegroundColor = ConsoleColor.Green;
    var input = Console.ReadLine();

    messages.Add(new Message { Role = "user", Content = input });
    // 构造请求体
    var requestBody = new ChatRequest("deepseek-chat", messages, ["web_search"], true, 0.7);

    // 发送请求
    var content = new StringContent(JsonSerializer.Serialize(requestBody), Encoding.UTF8, "application/json");
    var request = new HttpRequestMessage(HttpMethod.Post, apiUrl) { Content = content };
    using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

    // 确保请求成功
    response.EnsureSuccessStatusCode();

    // 读取流式响应
    using var stream = await response.Content.ReadAsStreamAsync();
    using var reader = new System.IO.StreamReader(stream);

    var msg = new Message { Role = "assistant", Content = "" };

    while (!reader.EndOfStream)
    {
        var line = await reader.ReadLineAsync();
        if (!string.IsNullOrEmpty(line))
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            if (line.Contains("DONE"))
            {
                Console.WriteLine();
                break;
            }
            if (line.StartsWith("data:"))
            {
                Console.ForegroundColor = ConsoleColor.White;
                line = line.Substring(5);

                // 解析 JSON 数据
                var jsonDocument = JsonDocument.Parse(line);
                var choices = jsonDocument.RootElement.GetProperty("choices");

                foreach (var choice in choices.EnumerateArray())
                {
                    var delta = choice.GetProperty("delta");
                    if (delta.TryGetProperty("content", out var contentElement))
                    {
                        var ac = contentElement.GetString();
                        msg.Content += ac;
                        Console.Write(ac); // 输出增量内容
                    }
                }
                continue;
            }
            Console.WriteLine(line);
        }
    }

    // 收到的消息继续添加进消息列表,实现上下文联系
    messages.Add(msg);
}

这样我们就有了一个AI助手,下面体验一下效果,👍针不戳

https://static.scung.cn/c7878759-0be1-414d-b6a3-de3cd9f0ded0.png

其他阅读

个人简介

你好,我是猪头少年,是一名定居在云南的软件工程师,主要的开发语言为 C#JavaScript,后端使用 ASP.NET Core,桌面端使用 WPFUnity ,前端使用 AngularBabylon.js。平时喜欢自驾出游。欢迎大家联系我。

查看原文

Web前端中实现自定义右键菜单

在原生的桌面应用中,右键菜单是个很常见也很常用的东西,但是在Web应用中,由于浏览器自带了右键菜单,所以我们很少见到应用有自己的右键菜单,但不常见并不代表没有,本文就会介绍一个右键菜单的实现。

查看原文

C#中new和override的区别

在C#编程语言中,new 和 override 是两个重要的关键字,它们用于控制类成员方法的行为。在面向对象编程(OOP)中,理解这两个关键字的区别和用法,对于编写清晰、可维护和高效的代码至关重要。

查看原文

Open Graph优化SEO

Open Graph(OG)协议作为社交分享优化的核心技术,不仅决定了内容在社交媒体平台的展示效果,还间接影响搜索引擎优化(SEO)的表现。本文将从作用解析、核心标签配置到动态生成策略,全面介绍 Open Graph 的应用。

查看原文

在ASP.NET Core中使用过滤器

ASP.NET Core是一个高性能的Web开发框架,过滤器(Filter)在ASP.NET Core中被用于路由方法之上,可以在路由方法执行前后完成一些额外的操作。本文将会介绍在ASP.NET Core中使用 IActionFilter 实现过滤器并读取路由方法中的参数。

查看原文