当前位置: 首页 > news >正文

WPF快速创建DeepSeek本地自己的客户端-基础思路版本

开发工具:VS 2015
开发环境:.Net 4.0
使用技术:WPF

本篇文章内容:
本地部署DeepSeek以后一般使用网页工具(如Chatbox)或者DOS窗口与其对话。本篇文章使用WPF创建一个基础版的对话工具。

一、搭建本地DeepSeek环境

我参考的是一下几个教程:
1、DeepSeek本地搭建部署+搭建知识库+智能体详细图文教程
2、【问题记录】DeepSeek本地部署遇到问题
3、公司数据不泄露,DeepSeek R1本地化部署+web端访问+个人知识库搭建与使用,喂饭级实操教程,老旧笔记本竟跑出企业级AI
4、【大语言模型】本地快速部署Ollama运行大语言模型详细流程

二、vs2015 创建WPF项目

三、相关代码如下

Windows窗口界面

<Window x:Class="DeepSeekAI2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DeepSeekAI2"
        mc:Ignorable="d"
        Title="MainWindow" Height="680" Width="800">
    <Grid Margin="10,0,15,5">
        <Grid.RowDefinitions>
            <RowDefinition Height="8.5*"/>
            <RowDefinition Height="1.5*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="750"/>
        </Grid.ColumnDefinitions>

        <!--第一个格子,AI对话格子-->
        <Grid Grid.Row="0" Grid.Column="0">
            <ListBox Name="ChatListBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" TextWrapping="Wrap" MaxWidth="730"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
        <!--第二个格子,用户输入框-->
        <Grid Grid.Row="1" Grid.Column="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="8*" />
                <ColumnDefinition Width="2*"/>
            </Grid.ColumnDefinitions>
            <!--输入信息框-->
            <Grid Grid.Column="0">
                <TextBox Name="InputTextBox" HorizontalAlignment="Left" VerticalAlignment="Bottom" KeyDown="InputTextBox_KeyDown"
            Height="62" Width="522" Margin="61,0,0,14" />
            </Grid>
            <!--发送信息按钮框-->
            <Grid Grid.Column="1">
                <Button Name="SendButton" 
                    Content="Send" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Bottom" 
                    Margin="0,0,58,20" 
                    Width="90" 
                    Height="50" 
                    Click="SendButton_Click" FontFamily="Arial Black" FontSize="13" Foreground="#FF424234"/>
            </Grid>
            <Grid Grid.Column="1">
                <Button Name="SendButton1" 
                    Content="new" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Bottom" 
                    Margin="0,0,2,60" 
                    Width="30" 
                    Height="30" 
                    Click="SendButton_Click1" FontFamily="Cambria" Foreground="#FF424234" Background="#FFB6F5C2"/>
            </Grid>
        </Grid>
    </Grid>
</Window>

后端代码

using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Input;
using System.Net;

namespace DeepSeekAI2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 输入按钮框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void InputTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                RunAI();
                //InputTextBox.Text = "";
            }
        }

        /// <summary>
        /// 确认发送按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SendButton_Click(object sender, RoutedEventArgs e)
        {
            // 异步方法需在同步上下文中调用(需手动处理)
            RunAI();
            //InputTextBox.Text = "";
        }
        // 用于存储对话的历史记录
        static StringBuilder conversationHistory = new StringBuilder();
        static string apiUrl = "http://localhost:11434/api/generate";
            
        public void RunAI()
        {
            // 用户输入
            string userInput = InputTextBox.Text;
            // 如果输入不正确,不输出
            if (userInput.ToLower() == "" || userInput.ToLower() == "\n")
            {
                return;
            }
            // 用户输入添加到历史对话记录
            conversationHistory.AppendLine($"用户: {userInput}");
            ChatListBox.Items.Add("-----------用户:-----------");
            ChatListBox.Items.Add(userInput);
            var requestData = new
            {
                model = "deepseek-r1:1.5b",
                prompt = conversationHistory.ToString(),
                stream = true
            };

            string jsonContent = Newtonsoft.Json.JsonConvert.SerializeObject(requestData);
            byte[] byteArray = Encoding.UTF8.GetBytes(jsonContent);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(apiUrl);
            request.Method = "POST";
            request.ContentType = "application/json";
            request.ContentLength = byteArray.Length;

            using (Stream dataStream = request.GetRequestStream())
            {
                dataStream.Write(byteArray, 0, byteArray.Length);
            }

            try
            {
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                using (Stream responseStream = response.GetResponseStream())
                using (StreamReader reader = new StreamReader(responseStream))
                {
                    string line;

                    string line2 = "";
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (!string.IsNullOrEmpty(line))
                        {
                            dynamic result = Newtonsoft.Json.JsonConvert.DeserializeObject(line);
                            if (result != null && result.response != null)
                            {
                                //Console.Write(result.response);
                                //Console.Out.Flush(); // 强制刷新控制台输出
                                //ChatListBox.Items.Add(result.response);
                                line2 += result.response;
                            }
                        }
                    }

                    // 处理AI回话
                    // 去掉所有的换行符
                    line2 = line2.Replace("\n\n", "");
                    // 使用正则表达式去掉 <think> 和 </think> 标签
                    line2 = Regex.Replace(line2, @"<\/?think>", "\n");
                    // 去掉开头的换行符
                    line2 = line2.TrimStart('\r', '\n');
                    ChatListBox.Items.Add("-----------DeepSeek: -----------");
                    //Console.WriteLine();  AI回话DeePSeek回话 line2
                    ChatListBox.Items.Add(line2);
                    conversationHistory.AppendLine($"DeepSeek: {line2}");
                    line2 = "";
                }
                InputTextBox.Text = "";
            }
            catch (WebException ex)
            {
                MessageBox.Show("请求异常: " + ex.Message);
                InputTextBox.Text = "";
            }
        }


        /// <summary>
        /// 开启新的对话
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SendButton_Click1(object sender, RoutedEventArgs e)
        {
            //1 清空历史记录
            conversationHistory.Clear();
            //2 清空 ListBox 的内容
            ChatListBox.Items.Clear();
            //3 清空输入框
            InputTextBox.Text = "";
        }

    }
}

四、内容介绍

static string apiUrl = "http://localhost:11434/api/generate";

其中这个代码是本地DeepSeek默认的调用接口,如果自己修改了相关内容将此修改就可以

model = "deepseek-r1:1.5b"

这串代码的意思是指定使用本地安装的某个DeepSeek版本。
在这里插入图片描述
因为7b的版本在我电脑上太慢。所以直接使用最快的模型。

五、完成效果如下

在这里插入图片描述
这样就搭建了基础的对话模型。大家可以不断优化,做一个自己的对话模型。

相关文章:

  • 用Prim算法求解最小生成树:代码实现与分析
  • AIGC(生成式AI)试用 21 -- Python调用deepseek API
  • 多线程之两阶段终止模式
  • 【DeepSeek】本地部署,保姆级教程
  • scala中为什么能用常量的地方就不用变量
  • Miniconda + VSCode 的Python环境搭建
  • 解锁观察者模式:Java编程中的高效事件管理之道
  • 【Windows软件 - HeidiSQL】导出数据库
  • golang常用库之-swaggo/swag根据注释生成接口文档
  • halcon 条形码、二维码识别、opencv识别
  • Java零基础入门笔记:(4)方法
  • 每日一题——将数字字符串转化为IP地址
  • 深入解析 iOS 视频录制(三):完整录制流程的实现与整合
  • 如何连接别人的redis服务器吗?
  • 嵌入式八股文(四)计算机网络篇
  • selenium环境搭建
  • 【故障处理】- 11G expdp导出缓慢 + Streams AQ: enqueue blocked on low memory等待事件
  • mybatis 批量提交-提升效率
  • P11071 「QMSOI R1」 Distorted Fate Solution
  • C# 使用 CSRedis 来操作 Redis 队列
  • 习近平圆满结束对俄罗斯国事访问并出席纪念苏联伟大卫国战争胜利80周年庆典
  • 碧桂园境外债务重组:相当于现有公众票据本金额逾50%的持有人已加入协议
  • 850亿元!2025年中央金融机构注资特别国债(一期)拟第一次续发行
  • 海南省三亚市委原常委、秘书长黄兴武被“双开”
  • 治沙“异瞳”男生疑似摆拍,团队称合作12天多期视频为策划拍摄
  • 青岛双星名人集团管理权之争:公司迁址,管理层更迭