百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

C#调用大模型DeepSeek API 完整实例,结果逐字动态输出在界面上

zhezhongyun 2025-04-30 21:17 46 浏览

前言

如何运用开发语言 C#对 DeepSeek API 进行调用,使其能够如同 DeepSeek 官方网站那样涵盖分析、推理等流程,最终以类似于动态打字的效果将答案输出至界面。本文章包含了全部需要的运行代码,代码下载后,只需要修改deepseek API key就可以完美运行,效果呈现如下:

deepseek API key

需要前往 DeepSeek 官方网站去申请 API Key,具体操作方式如下所示,该API Key是后续调用 DeepSeek API 进行开发和应用的重要凭证,务必妥善保管和使用。

Windows 窗体设计

首先,创建一个 C# 的 Windows 窗体应用程序。在这个过程中,采用 panel 控件来进行布局,以实现更加合理和美观的界面设计。在界面中,答案部分设置为一个 RichTextBox 控件,用于展示详细和丰富的答案内容。而在其下方的问题部分,同样也设置一个 RichTextBox 控件,方便用户输入和编辑相关的问题。此外,还需创建一个 Button 控件,并且对其 Text 属性进行修改,将其设定为“DeepSeek”。 设计界面如下:



API类函数

对 API 函数予以封装,并将其存于一个类文件之内,同时,APIKey 置于类的 app.config 文件之中,完整代码如下:

using System;
using System.Text;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
using System.Configuration;
using System.Runtime.InteropServices;


namespace DeepSeekService
{
   
        public class DeepSeepClient
        {
        public static string ApiKey { get { return ConfigurationManager.AppSettings["DeepseekAPI_KEY"].ToString(); } }
        private readonly HttpClient client;
        private const string ApiUrl = "https://api.deepseek.com/v1/chat/completions";
        private const string ModelName = "deepseek-chat";
        public DeepSeepClient() {

            client = new HttpClient();
            client.DefaultRequestHeaders.Add("Authorization", #34;Bearer {ApiKey}");
            client.DefaultRequestHeaders.Add("Accept", "text/event-stream");
        }
      
        enum ProcessingPhase
        {
            Analyzing,
            Researching,
            Reasoning,
            Finalizing
        }

        public  async Task RunDeepSeek(RichTextBox rt, string prompt)
        {           


            var requestData = new
            {
                model = ModelName,
                messages = new[]
                {
                    new { role = "system", content = "请按以下步骤回答:1.分析问题 2.联网资料 3.推理 4.答案. 提供的参考知识库:\n\\n经典作品常常与我们自己的生活息息相关。在《经典常谈》中,作者通过对比古今文化,指出许多经典所讨论的主题,例如爱情、死亡、自由与责任,依然是人类永恒的心结。这些主题在不同的历史阶段被赋予了全新的意义,使我们在面对生活中的困惑与挑战时,能够从中寻找到启发与指引。阅读经典,让我意识到自己的生活困扰其实早已被前人探讨过,不同的是我们面对这些问题的态度与答案。我们在阅读经典的同时,也在审视自己的价值观和人生观。我开始意识到,经典作品所引发的思考往往比作品本身更为重要。与其一味追求书中所传达的思想,不如在阅读中找到与自己内心的对话,发掘出属于自己的理解与感悟。\\n\\n最后,经典的吸引力在于它们的共鸣。正是这些作品,让我们在个体经验与历史智慧之间架起了一座桥梁。在这个信息碎片化的时代,经典作品无疑为我们的精神世界提供了一种持久的滋养。它们教会我们如何在复杂的社会中保持清醒,自省以及不断追求更高的理想。\\n\\n《经典常谈》带给我的新认识是,经典不仅是文化的承载体,更是人类思考与自我发现的工具。在未来的日子里,我将继续怀揣这份对经典的敬畏与热爱,让其在我的人生旅途中指引前行的方向。\";" },

                    new { role = "user", content = prompt }
                },
                stream = true
            };

            try
            {
                using (var request = new HttpRequestMessage(HttpMethod.Post, ApiUrl))
                {
                    request.Content = new StringContent(
                        JsonSerializer.Serialize(requestData),
                        Encoding.UTF8,
                        "application/json");

                    using (var response = await client.SendAsync(
                        request,
                        HttpCompletionOption.ResponseHeadersRead))
                    {
                        response.EnsureSuccessStatusCode();

                        var currentPhase = ProcessingPhase.Analyzing;
                        var phaseBuffer = new StringBuilder();
                        var fullAnswer = new StringBuilder();
                        rt.AppendText(" Thinking...");
                        rt.AppendText(Environment.NewLine);
                        rt.Refresh();
                        using (var stream = await response.Content.ReadAsStreamAsync())
                        using (var reader = new System.IO.StreamReader(stream))
                        {
                            while (!reader.EndOfStream)
                            {
                                var line = await reader.ReadLineAsync();
                                if (string.IsNullOrWhiteSpace(line)) continue;

                                if (line.StartsWith("data: "))
                                {
                                    var jsonData = line.Substring(6).Trim();
                                    if (jsonData == "[DONE]") break;

                                    using (var jsonDoc = JsonDocument.Parse(jsonData))
                                    {
                                        var choices = jsonDoc.RootElement
                                            .GetProperty("choices");

                                        foreach (var choice in choices.EnumerateArray())
                                        {
                                            var delta = choice.GetProperty("delta");
                                            if (delta.TryGetProperty("content", out var content))
                                            {
                                                var text = content.GetString();
                                                phaseBuffer.Append(text);
                                                fullAnswer.Append(text);

                                                #region "enabled if required"                                               // 检测阶段标记
                                                //var bufferStr = phaseBuffer.ToString();
                                                //if (bufferStr.Contains("【分析】"))
                                                //{
                                                //    UpdatePhase(ref currentPhase, ProcessingPhase.Analyzing, "问题分析",rt);
                                                //    phaseBuffer.Clear();
                                                //}
                                                //else if (bufferStr.Contains("【资料】"))
                                                //{
                                                //    UpdatePhase(ref currentPhase, ProcessingPhase.Researching, "信息检索",rt);
                                                //    phaseBuffer.Clear();
                                                //}
                                                //else if (bufferStr.Contains("【推理】"))
                                                //{
                                                //    UpdatePhase(ref currentPhase, ProcessingPhase.Reasoning, "逻辑推理",rt);
                                                //    phaseBuffer.Clear();
                                                //}
                                                #endregion

                                                // output 
                                                  AddTextToRichTextBox(rt, text);
                                              
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        Console.ForegroundColor = ConsoleColor.Green;
                      
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(#34;\n exception handling: {e.Message}");
            }
        }
        private static void AddTextToRichTextBox(RichTextBox rt, string text)
        {


            rt.SuspendLayout();
            rt.AppendText(text);
            rt.SelectionStart = rt.TextLength;
            rt.ScrollToCaret();
            rt.ResumeLayout();

        }
        static void UpdatePhase(ref ProcessingPhase currentPhase, ProcessingPhase newPhase, string phaseName,RichTextBox rt)
        {
            if (currentPhase == newPhase) return;

            currentPhase = newPhase;
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine(#34;\n\n Current Phase:{phaseName}");

            rt.AppendText("Current Phase:{phaseName}");
            rt.ScrollToCaret();
            Console.ResetColor();
        }
    }
}

app.config配置

于 app.config 配置文件当中,对 API key 的配置情况如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
	<appSettings>
		<add key="DeepseekAPI_KEY" value=你的deepseek API Key />
	</appSettings>
</configuration>

Windows 窗体代码

创建一个 Windows 窗体,借助 Panel 来实施布局,而后创建两个 RichTextBox ,分别用以呈现输入的内容以及答案。创建一个button,命名为btDeepseek

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DeepSeekService;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.WindowState = FormWindowState.Maximized;
        }
         private async void btDeepseek_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(rtbAnswer.Text.Trim()))
            {
                rtbAnswer.AppendText(Environment.NewLine);
                rtbAnswer.AppendText(Environment.NewLine);

            }
            DeepSeepClient dsClient = new DeepSeepClient();

            await dsClient.RunDeepSeek(rtbAnswer, rtbQuestion.Text);

        }

       
    }
}

总结

当运行以上代码之后,便成功地实现了对 deepseek api 的调用。在此过程中,能够根据具体的输入,动态地输出相应的结果内容,欢迎大家提出问题。

相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...