【deepseek实战】绿色好用,不断网

前言

        最佳deepseek火热网络,我也开发一款windows的电脑端,接入了deepseek,基本是复刻了网页端,还加入一些特色功能。

        助力国内AI,发出自己的热量

        说一下开发过程和内容的使用吧。


目录

一、介绍

二、具体工作

        1.1、引用

        1.2、主界面

        1.3、主界面布局

        1.4 、消息类

        1.5 、设置

三、运行图示 

四、总结

五、下载


一、介绍

  •    目标:个人桌面AI助手,避免与专属API冲突,因为官网一些原因断网,自己接入API,确保能上deepseek。
    先上图,确定是否需要使用:
  • 软件是免费的,自己用自己的key或者别人的key,没有key可以联系我

二、具体工作

        1.1、引用

        dotnet8.0

  <TargetFramework>net8.0-windows</TargetFramework>

        PackageReference 

    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
    <PackageReference Include="System.Drawing.Common" Version="8.0.0" />
    <PackageReference Include="System.Speech" Version="8.0.0" />
    <PackageReference Include="Spire.Doc" Version="12.8.0" />

            Newtonsoft.Json 编译和反编译API信息
            System.Drawing 绘制库,画界面主要
            System.Speech 语音接入
            Spire.Doc 文档使用

        这几个引用根据自己需要添加

        1.2、主界面

        信息处理,分为及时信息和二次信息处理,这样能对文本信息进行个人需要处理

private async Task<ChatMessage> StreamResponseAsync(string apiKey, List<ChatMessage> chatHistory, string language, CancellationToken cancellationToken)
{
    var deepseekService = new DeepseekService(currentUser, _printService);
    var messages = chatHistory.Select(m => new ChatMessage
    {
        Role = m.Role,
        MessageType = m.MessageType,
        Content = m.Content
    }).ToList();
    try
    {
        var typingDelay = TimeSpan.FromMilliseconds(50);
        var buffer = new StringBuilder();
        
        var responseMessage = new ChatMessage
        {
            Role = "assistant",
            MessageType = MessageType.Answer,
            Content = string.Empty,
            WrappedContent = string.Empty
        };
        // 创建响应消息但不立即添加到历史记录
        var responseIndex = _displayHistory .Count;

        // 实时处理流式响应 - deepseek输出开始
        var charCount = 0;
        var tempBuffer = new StringBuilder();
      
        await foreach (var chunk in deepseekService.StreamChatResponseAsync(apiKey, messages, language).WithCancellation(cancellationToken))
        {
            if (string.IsNullOrEmpty(chunk) || _isStopping || cancellationToken.IsCancellationRequested) 
            {
                // Immediately return if stopping
                return new ChatMessage
                {
                    Role = "assistant",
                    MessageType = MessageType.Answer,
                    Content = "对话已终止",
                    WrappedContent = "对话已终止"
                };
            }
            
            tempBuffer.Append(chunk);
            charCount += chunk.Length;
            // 每20个字符更新一次显示
            if (charCount >= 20)
            {
                buffer.Append(tempBuffer.ToString());
                tempBuffer.Clear();
                charCount = 0;
                await Dispatcher.InvokeAsync(() => {
                    responseMessage.Content = buffer.ToString();
                    responseMessage.WrappedContent = WrapText(responseMessage.Content+"\n回答完成1",
                        ChatHistoryRichTextBox?.ActualWidth - 20 ?? ChatMessage.DefaultBorderWidth);
                    
                    // 更新_curchat
                    _curchatMesg = responseMessage;
                    
                    // 只在第一次更新时添加消息
                    if (_displayHistory .Count == responseIndex) {
                        _displayHistory .Add(responseMessage);
                    } else {
                        _displayHistory [responseIndex] = responseMessage;
                    }
                    
                    UpdateChatHistoryDisplayList(_displayHistory);
                });          
                await Task.Delay(typingDelay);
            }
        }
        
        // 处理剩余不足20字符的内容
        if (tempBuffer.Length > 0)
        {
            buffer.Append(tempBuffer.ToString());
            await Dispatcher.InvokeAsync(() => {
                responseMessage.Content = buffer.ToString() ;
                responseMessage.WrappedContent = WrapText(responseMessage.Content+"\n回答完成2",
                    ChatHistoryRichTextBox?.ActualWidth - 20 ?? ChatMessage.DefaultBorderWidth);          
                // 更新_curchat
                _curchatMesg = responseMessage;
                _displayHistory [responseIndex] = responseMessage;
                UpdateChatHistoryDisplayList(_displayHistory);
            });
        }
        

        // deepseek输出完成 - 流式响应结束
        // 进行最后的换行检查
        await Dispatcher.InvokeAsync(() => {
            responseMessage.WrappedContent = WrapText(responseMessage.Content+"\n回答完成3", 
                ChatHistoryRichTextBox?.ActualWidth - 20 ?? ChatMessage.DefaultBorderWidth);
            // 更新_curchat
            _curchatMesg = responseMessage;
            _displayHistory [responseIndex] = responseMessage;
            UpdateChatHistoryDisplayList(_displayHistory);
        });
        
        return responseMessage;
    }
    catch (Exception ex)
    {
        return new ChatMessage
        {
            Role = "assistant",
            MessageType = MessageType.Answer,
            Content = $"Error: {ex.Message}",
            WrappedContent = $"Error: {ex.Message}"
        };
    }
    finally
    {
        // 清空输入框
        InputTextBox.Text = string.Empty;
    }
}

        1.3、主界面布局
<Window x:Class="AIzhushou.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:AIzhushou.Converters"
        Title="智能聊天助手" Height="820" Width="420" MinHeight="800" MinWidth="400"
        WindowStartupLocation="Manual"
        Background="#333333" ResizeMode="CanResizeWithGrip">

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Styles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <local:EndMarkVisibilityConverter x:Key="EndMarkVisibilityConverter"/>
            <local:MathConverter x:Key="MathConverter"/>
        </ResourceDictionary>
    </Window.Resources>

    <Viewbox Stretch="Uniform">
        <Grid Width="420" Height="760" Background="#333333">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="63*"/>
                <ColumnDefinition Width="337*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <!-- Top Buttons -->
            <DockPanel Grid.Row="0" Grid.Column="1" Margin="265,0,20,5" Width="88">
                <Button  x:Name="setting" Style="{StaticResource MainButtonStyle}"
                    Click="setting_Click" Height="40" Width="40" RenderTransformOrigin="0.5,0.5"
                    DockPanel.Dock="Right">
                    <Image Source="pack://application:,,,/AIzhushou;component/Img/icons8-home-page-50.png" Width="30" Height="30"/>
                </Button>
            </DockPanel>

            <!-- Chat History Label -->
            <Label Style="{StaticResource SectionLabelStyle}" 
                   Content="聊天记录" Margin="22,0,0,0" Grid.ColumnSpan="2" VerticalAlignment="Center"/>

            <!-- Chat History RichTextBox -->
            <Border Grid.Row="1" Style="{StaticResource ChatBorderStyle}" HorizontalAlignment="Left"
                    Grid.ColumnSpan="2" Margin="15,0,0,10">
                <Border.Resources>
                    <Style TargetType="ScrollViewer" BasedOn="{StaticResource CustomScrollViewerStyle}" />
                </Border.Resources>

                <RichTextBox x:Name="ChatHistoryRichTextBox" Style="{StaticResource ChatHistoryRichTextBoxStyle}"
                Loaded="ChatHistoryRichTextBox_Loaded" Width="380" Margin="-10,0,0,0">
                    <RichTextBox.Resources>
                        <!-- 设置 Paragraph 的 Margin -->
                        <Style TargetType="Paragraph">
                            <Setter Property="Margin" Value="0"/>
                        </Style>
                    </RichTextBox.Resources>
                </RichTextBox>
            </Border>

            <!-- New Conversation Button -->
            <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,10,0,10" Grid.Column="1">
                <!--<Button x:Name="FreshButton" Style="{StaticResource FreshButtonStyle}" 
                        Click="freshButton_Click" Height="36" Width="120">
                    <Button.Content>
                        <StackPanel Orientation="Horizontal">
                            <Image Source="pack://application:,,,/AIzhushou;component/Img/icons8-refresh-96.png" 
                                Width="20" Height="20" Margin="0,0,5,0"/>
                            <TextBlock Text="刷新刚才回答" VerticalAlignment="Center" Foreground="#4d6bfe"/>
                        </StackPanel>
                    </Button.Content>
                </Button>-->
                <Button x:Name="NewConversationButton" Style="{StaticResource NewConversationButtonStyle}"
                        Click="NewConversationButton_Click" Margin="90,0,5,0" Height="36" Width="120">
                    <Button.Content>
                        <StackPanel Orientation="Horizontal">
                            <Image Source="pack://application:,,,/AIzhushou;component/Img/icons8-talk-64.png" 
                                Width="20" Height="20" Margin="0,0,5,0"/>
                            <TextBlock Text="开启新对话" VerticalAlignment="Center" Foreground="#4d6bfe"/>
                        </StackPanel>
                    </Button.Content>
                </Button>
            </StackPanel>

            <!-- Input Label -->
            <Label Grid.Row="3" Style="{StaticResource SectionLabelStyle}" 
                   Content="输入消息" Margin="22,0,0,0" Grid.ColumnSpan="2" VerticalAlignment="Center"/>

            <!-- Input Section -->
            <Grid Grid.Row="4" HorizontalAlignment="Left" VerticalAlignment="Bottom"
                  Margin="22,0,0,-10" Width="378" Grid.ColumnSpan="2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>

                <!-- Input TextBox -->
                <TextBox x:Name="InputTextBox" Grid.Column="0"
                        Style="{StaticResource InputTextBoxStyle}"
                        TextWrapping="Wrap" AcceptsReturn="True"
                        KeyDown="InputTextBox_KeyDown"
                        PreviewKeyDown="InputTextBox_KeyDown"/>

                <!-- Send Button -->
                <Border Grid.Column="1" Style="{StaticResource SendButtonBorderStyle}" 
                        Margin="10,0,0,0">
                    <Button x:Name="SendButton" Style="{StaticResource SendButtonStyle}"
                           Content="发送" Click="SendButton_Click" IsEnabled="True"/>
                </Border>
            </Grid>
        </Grid>
    </Viewbox>
</Window>


        1.4 、消息类

        设计这个是为了对消息类对API的信息进行存入和处理

 public enum MessageType
 {
     Question,
     Answer
 }

 public class ChatMessage
 {
     public static double DefaultBorderWidth { get; set; } = 300;

     public string Role { get; set; }
     public string Content { get; set; }
     public string WrappedContent { get; set; }
     public double BorderWidth { get; set; } = DefaultBorderWidth;
     public Brush BackgroundColor { get; set; }
     public Brush TextColor { get; set; }
     public DateTime Timestamp { get; set; }    
     public MessageType MessageType { get; set; }

     public ChatMessage()
     {
         Role = string.Empty;
         Content = string.Empty;
         WrappedContent = string.Empty;
         Timestamp = DateTime.Now;
         BackgroundColor = Brushes.White;
         TextColor = Brushes.Black;
     }

     public ChatMessage(string content, string wrappedContent, double borderWidth) : this()
     {
         Content = content;
         WrappedContent = wrappedContent;
         BorderWidth = borderWidth;
     }
 }


        1.5 、设置

        API KEY这里是必须填写的,不填写是无法进行问题的回答

这里是代码

private void SaveButton_Click(object sender, RoutedEventArgs e)
{
    // 更新用户信息
    currentUser.Username = UsernameTextBox.Text;
    currentUser.Password = PasswordBox.Password;
    currentUser.AiUrl = AiUrlTextBox.Text;
    currentUser.ModelUrl = ModelUrlTextBox.Text;
    currentUser.ApiKey = ApiKeyTextBox.Text == "请输入deepseek的API keys" ? 
        string.Empty : ApiKeyTextBox.Text;

    // 保存语言设置
    var selectedLanguage = ((ComboBoxItem)LanguageComboBox.SelectedItem).Content.ToString();
    string languageCode = selectedLanguage == "中文" ? "zh-CN" : "en-US";
    AppSettings.Instance.DefaultLanguage = languageCode;
    AppSettings.Instance.SaveLanguageSettings(languageCode);

    // 保存复制选项设置
    //AppSettings.Instance.CopyCurrent = CopyCurrentRadio.IsChecked == true;
    AppSettings.Instance.Save();

    // 保存到配置文件
    string configPath = System.IO.Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
        "AIzhushou",
        "config.json");
    
    // 确保目录存在
    var directoryPath = System.IO.Path.GetDirectoryName(configPath);
    if (string.IsNullOrEmpty(directoryPath))
    {
        throw new InvalidOperationException("无法确定配置文件的目录路径");
    }
    System.IO.Directory.CreateDirectory(directoryPath);
    
    // 序列化保存
    string json = Newtonsoft.Json.JsonConvert.SerializeObject(currentUser);
    System.IO.File.WriteAllText(configPath, json);
    
    MessageBox.Show("设置保存成功", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
    this.Close();
}


三、运行图示 


四、总结

  •    实测了windows c#版本和python版本, c#版比python版本的性能更好,可能C#是微软亲儿子原因?
  •    一定用要异步处理,没有什么特别需要
  •    AI里面,deepseek是真的强
  •    如果需要提供协助,可以私信我

写着写着就这么多了,可能不是特别全,不介意费时就看看吧。有时间还会接着更新。


五、下载

        AI助手绿色免安装下载 支持deepseek

        AI助手项目下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/964789.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Meta Sapiens AI论文解读:人类视觉模型基石初现,AI 未来走向何方?

一、引言 在本文中&#xff0c;我们将深入探讨 Meta AI 的一项新成果&#xff0c;该成果发表于一篇题为《Sapiens&#xff1a;人类视觉模型的基础》的研究论文中。这篇论文介绍了一系列模型&#xff0c;这些模型针对四项以人类为中心的基本任务&#xff0c;正如我们在上面的演示…

多用户同时RDP登入Win10

自备以下文件&#xff1a; winsw_frpc.xml展开如下&#xff1a; <service><!-- ID of the service. It should be unique across the Windows system--><id>winsw_frp</id><!-- Display name of the service --><name>winsw_frp</na…

2025 持续防范 GitHub 投毒,通过 Sharp4SuoExplorer 分析 Visual Studio 隐藏文件

在2024年底的网络安全事件中&#xff0c;某提权工具被发现植入后门&#xff0c;攻击者利用 .suo 文件作为隐蔽的攻击方式。由于 .suo 文件是 Visual Studio 项目的隐藏配置文件&#xff0c;通常不为安全研究人员所关注&#xff0c;因此为攻击者提供了潜在的攻击渠道。 初步调查…

Unity 2D实战小游戏开发跳跳鸟 - 记录显示最高分

上一篇文章中我们实现了游戏的开始界面,在开始界面中有一个最高分数的UI,本文将接着实现记录最高分数以及在开始界面中显示最高分数的功能。 添加跳跳鸟死亡事件 要记录最高分,则需要在跳跳鸟死亡时去进行判断当前的分数是否是最高分,如果是最高分则进行记录,如果低于之前…

牛客 - 链表相加(二)

描述 假设链表中每一个节点的值都在 0 - 9 之间&#xff0c;那么链表整体就可以代表一个整数。 给定两个这种链表&#xff0c;请生成代表两个整数相加值的结果链表。 数据范围&#xff1a;0≤n,m≤1000000&#xff0c;链表任意值 0≤val≤9 要求&#xff1a;空间复杂度 O(n)&am…

Math Reference Notes: 符号函数

1. 符号函数的定义 符号函数&#xff08;Sign Function&#xff09; sgn ( x ) \text{sgn}(x) sgn(x) 是一个将实数 ( x ) 映射为其 符号值&#xff08;即正数、负数或零&#xff09;的函数。 它的定义如下&#xff1a; sgn ( x ) { 1 如果 x > 0 0 如果 x 0 − 1 如…

手写MVVM框架-构建虚拟dom树

MVVM的核心之一就是虚拟dom树&#xff0c;我们这一章节就先构建一个虚拟dom树 首先我们需要创建一个VNode的类 // 当前类的位置是src/vnode/index.js export default class VNode{constructor(tag, // 标签名称&#xff08;英文大写&#xff09;ele, // 对应真实节点children,…

STM32单片机学习记录(2.2)

一、STM32 13.1 - PWR简介 1. PWR&#xff08;Power Control&#xff09;电源控制 &#xff08;1&#xff09;PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能&#xff1b; &#xff08;2&#xff09;可编程电压监测器&#xff08;…

ASUS/华硕天选5锐龙版 FA507U 原厂Win11 22H2 专业版系统 工厂文件 带ASUS Recovery恢复

华硕工厂文件恢复系统 &#xff0c;安装结束后带隐藏分区&#xff0c;带一键恢复&#xff0c;以及机器所有的驱动和软件。 支持型号&#xff1a;FA507UU FA507UI FA507UV 系统版本&#xff1a;Windows 11 22H2 文件下载&#xff1a;asusoem.cn/920.html 文件格式&#xff…

React图标库: 使用React Icons实现定制化图标效果

React图标库: 使用React Icons实现定制化图标效果 图标库介绍 是一个专门为React应用设计的图标库&#xff0c;它包含了丰富的图标集合&#xff0c;覆盖了常用的图标类型&#xff0c;如FontAwesome、Material Design等。React Icons可以让开发者在React应用中轻松地添加、定制各…

【C++篇】哈希表

目录 一&#xff0c;哈希概念 1.1&#xff0c;直接定址法 1.2&#xff0c;哈希冲突 1.3&#xff0c;负载因子 二&#xff0c;哈希函数 2.1&#xff0c;除法散列法 /除留余数法 2.2&#xff0c;乘法散列法 2.3&#xff0c;全域散列法 三&#xff0c;处理哈希冲突 3.1&…

e2studio开发RA2E1(9)----定时器GPT配置输入捕获

e2studio开发RA2E1.9--定时器GPT配置输入捕获 概述视频教学样品申请硬件准备参考程序源码下载选择计时器时钟源UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uart_callback ()printf输出重定向到串口定时器输入捕获配…

MacBook Pro(M1芯片)DeepSeek R1 本地大模型环境搭建

MacBook Pro&#xff08;M1芯片&#xff09;DeepSeek R1 本地大模型环境搭建 这一阵子deepseek真的是太火了&#xff0c;这不&#xff0c;R1出来后更是掀起AI的狂欢&#xff0c;作为一个AI的外行人&#xff0c;也是忍不住想要拿过来感受一番&#xff5e;&#xff5e; 主要呢&…

数据结构:队列篇

图均为手绘,代码基于vs2022实现 系列文章目录 数据结构初探: 顺序表 数据结构初探:链表之单链表篇 数据结构初探:链表之双向链表篇 链表特别篇:链表经典算法问题 数据结构:栈篇 文章目录 系列文章目录前言一.队列的概念和结构1.1概念一、动态内存管理优势二、操作效率与安全性…

Python的那些事第十二篇:从入门到“不撞南墙不回头”Python 文件操作与异常处理

Python 文件操作与异常处理&#xff1a;从入门到“不撞南墙不回头” 目录 Python 文件操作与异常处理&#xff1a;从入门到“不撞南墙不回头” 一、引言 二、Python 文件操作 三、Python 异常处理 四、综合实例&#xff1a;学生成绩管理系统 五、总结与展望 一、引言 1.…

论文解读:《基于TinyML毫米波雷达的座舱检测、定位与分类》

摘要 本文提出了一种实时的座舱检测、定位和分类解决方案&#xff0c;采用毫米波&#xff08;mmWave&#xff09;雷达系统芯片&#xff08;SoC&#xff09;&#xff0c;CapterahCAL60S344-AE&#xff0c;支持微型机器学习&#xff08;TinyML&#xff09;。提出了波束距离-多普勒…

【B站保姆级视频教程:Jetson配置YOLOv11环境(七)Ultralytics YOLOv11配置】

Jetson配置YOLOv11环境&#xff08;7&#xff09;Ultralytics YOLOv11环境配置 文章目录 1. 下载YOLOv11 github项目2. 安装ultralytics包3. 验证ultralytics安装3.1 下载yolo11n.pt权重文件3.2 推理 1. 下载YOLOv11 github项目 创建一个目录&#xff0c;用于存放YOLOv11的项目…

代码讲解系列-CV(二)——卷积神经网络

文章目录 一、系列大纲二、卷积神经网络&#xff08;图像分类为例&#xff09;2.1 pytorch简介训练框架张量自动微分动态计算图更深入学习 2.2 数据输入和增强Dataset—— torch.utils.data.DatasetDataLoader——torch.utils.data.Dataloader数据增强 2.3 CNN设计与训练nn.Mod…

YK人工智能(六)——万字长文学会基于Torch模型网络可视化

1. 可视化网络结构 随着深度神经网络做的的发展&#xff0c;网络的结构越来越复杂&#xff0c;我们也很难确定每一层的输入结构&#xff0c;输出结构以及参数等信息&#xff0c;这样导致我们很难在短时间内完成debug。因此掌握一个可以用来可视化网络结构的工具是十分有必要的…

堆的基本概念

1.1 堆的基本概念 虚拟机所在目录 E:\ctf\pwn-self 进入虚拟机的pwndocker环境 holyeyesubuntu:~$ pwd /home/holyeyes holyeyesubuntu:~$ sudo ./1run.sh IDA分析 int __fastcall main(int argc, const char **argv, const char **envp) { void *v4; // [rsp20h] [rbp-1…