c# OllamaSharp DeepSeek 有上下文可连续对话

 使用 ollama 安装完 deepseek 后, nuget 安装 OllamaSharp ,使用如下代码可实现完整对话,我使用的模型是 DeepSeek-Coder-V2-Lite,以下是核心代码:

复制代码
public class DeepSeekChat
{
    IChatClient chatClient = new OllamaApiClient("http://127.0.0.1:11434", "DeepSeek-Coder-V2-Lite:latest");
    List<ChatMessage> chatHistory = new();
    CancellationTokenSource cts = null;
    CancellationToken? cancellationToken = null;

    public delegate void PartialResponse(string text);

    public DeepSeekChat() 
    {
        //chatHistory.Add(new ChatMessage(Microsoft.Extensions.AI.ChatRole.System, "你是一个代码助手,请用中文回答所有问题。"));
    }

    public async Task Chat(string prompt, PartialResponse partialResponse)
    {
        chatHistory.Add(new ChatMessage(Microsoft.Extensions.AI.ChatRole.User, prompt));

        try
        {
            var response = string.Empty;
            cts = new CancellationTokenSource();
            cancellationToken = cts.Token;

            await foreach (var item in
                chatClient.GetStreamingResponseAsync(chatHistory,null,cancellationToken.Value))
            {
                // 在此处调用 ThrowIfCancellationRequested
                cancellationToken?.ThrowIfCancellationRequested();

                var content = (item.Text ?? string.Empty).Replace("<think>", "").Replace("</think>", "");

                if (content.Length > 0)
                    partialResponse(content);

                System.Diagnostics.Debug.Print(item.Text);

                response += item.Text;
            }
            chatHistory.Add(new ChatMessage(Microsoft.Extensions.AI.ChatRole.Assistant, response));
        }
        catch (Exception ex)
        {
            chatHistory.RemoveAt(chatHistory.Count - 1);
            partialResponse(Environment.NewLine + $"Error: {ex.Message}" + Environment.NewLine);
        }
    }

    public void Cancel()
    {
        cts?.Cancel();
        cts = null;
    }
}
复制代码

使用 wpf markdig:MarkdownViewer 来显示输出:
private DeepSeekChat chat = new DeepSeekChat();

复制代码
async Task startRequest(string question)
{
    PartialResponse pr = delegate (string text)
    {
        Dispatcher.Invoke(async () =>
        {
            await Task.Delay(1);
            if((markdownViewer.Markdown.EndsWith(Environment.NewLine) 
                || markdownViewer.Markdown.EndsWith("\n")) && text.StartsWith(" "))
                // Markdown行首空格会被忽略,所以用零宽空格代替行首第一个空格,以便保留缩进
                markdownViewer.Markdown += "\u200B" + text;
            else
                markdownViewer.Markdown += text;
        });
    };

    Debug.Print("开始请求");

    await chat.Chat(question, pr);

    Debug.Print("结束请求");
}
复制代码

请求:

复制代码
Task.Run(async () =>
{
    try
    {
        await startRequest("用C#写一个冒泡排序算法?");
    }
    catch (Exception ex)
    {
        Dispatcher.Invoke(() =>
        {
            markdownViewer.Markdown += "  \n" + ex.Message;
        });
    }
    finally
    {
        Dispatcher.Invoke(() =>
        {
            markdownViewer.Markdown += "  \n";
        });
    }
});
复制代码

 以下是输出效果截图:

 

posted on   空明流光  阅读(34)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
历史上的今天:
2023-03-06 C# 如何正确关闭 socket 连接释放占用的端口?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示