C#与AI的交互(以DeepSeek为例)

C#与ai的交互

与AI的交互使用的Http请求的方式,通过发送请求,服务器响应ai生成的文本

下面是完整的代码,我这里使用的是Ollama本地部署的deepseek,在联网调用api时,则url会有不同

csharp 复制代码
public class OllamaRequester
{
    [Serializable]
    public class RequestData
    {
        public string model;	//模型名称
        public string prompt;	//对话文本
        public int[] context;	//上下文
        public bool stream;	//是否使用流式传输
    }

    [Serializable]
    public class ResponseData
    {
        public string model;
        public string created_at;
        public string response;	//相应内容
        public bool done;	//生成是否结束
        public string done_reason;	//结束的状态
        public int[] context;	//上下文
        public long total_duration;
        public long load_duration;
    }

    private static OllamaRequester instance;
    public static OllamaRequester Instance
    {
        get
        {
            if(instance == null)
            {
                instance = new OllamaRequester();
                instance.Init();
            }
            return instance;
        }
    }


    private int[] context;
    private HttpClient client;

    private void Init()
    {
        client = new HttpClient();
    }

    public async Task SendReq(string str, Action<ResponseData> onResOnce)
    {
    	//注意!这里是本地Ollama的地址,如果你是联网调用ai接口的的话,需要改成官网提供的url
        string url = "http://localhost:11434/api/generate"; //ollama端口默认11434

		//如果使用联网调用ai接口,则请求的参数会有不同,我这使用的是本地部署的请求参数
        RequestData data = new RequestData()
        {
            model = "deepseek-r1:7b",
            prompt = str,
            context = context,
            stream = true, //建议用流式传输,不然响应比较慢
        };
        string json = JsonUtility.ToJson(data);
        HttpContent content = new StringContent(json);
        content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
        Debug.Log("发送请求..");
        try
        {
            var request = new HttpRequestMessage(HttpMethod.Post, url);
            request.Content = content;
            
            //这个HttpCompletionOption.ResponseHeadersRead至关重要,流式传输必须使用这个
            HttpResponseMessage msg = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
            try
            {
                //不是200则直接报错
                if (msg.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    Debug.LogError($"错误!statusCode=={msg.StatusCode}, 错误消息=={msg.Content}");
                    return;
                }
                Stream stream = await msg.Content.ReadAsStreamAsync();

                StreamReader reader = new StreamReader(stream);
                while (true)
                {
                    string resStr = await reader.ReadLineAsync();
                    Debug.Log("str==" + resStr);
                    ResponseData res = JsonUtility.FromJson<ResponseData>(resStr);
                    onResOnce?.Invoke(res);
                    if (res.done)
                    {
                        break;
                    }
                }
                reader.Dispose();
                stream.Dispose();
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        }
        catch(Exception e)
        {
            Debug.LogError(e);
        }
    }
}

注意代码中SendAynsc时,使用了HttpCompletionOption.ResponseHeadersRead ,这个枚举表示的是读取响应头部信息,并且允许你从响应流中逐步读取信息。

默认情况下,Http会等待整个响应体全部下载完,才会返回响应,这样在文本很长时响应会非常慢!所以通常建议开启流式传输

下面是ai响应的数据格式示例

lua 复制代码
--api返回的数据格式是json(因为csdn没有json格式的代码段,所以我用了lua表示)
{
    "model": "deepseek-r1:7b",	--模型
    "created_at": "2025-02-24T02:03:41.8641806Z",
    "response": "",	--响应内容,我这里因为已经结束生成了,所以resposne是空
    "done": true,	--done==true,表示结束生成
    "done_reason": "stop",	--done_reason==stop,表示正常结束,会有其他非正常结束的情况
    "context": [	--上下文,在下次发送请求的时候,需要发送context,可以让ai保持连续对话
        151644,
        108386,
        151645,
        151648,
        271,
        151649,
        271,
        108386,
        6313,
        112169,
        104639,
        56568,
        3837,
        104139,
        109944,
        106128,
        9370,
        101037,
        11319,
        102215,
        86119,
        5373,
        101898,
        99998,
        100836,
        100281,
        3837,
        35946,
        102070,
        108896,
        101036,
        6313,
        144236
    ],
    "total_duration": 4234560000,
    "load_duration": 18329400,
    "prompt_eval_count": 4,
    "prompt_eval_duration": 274000000,
    "eval_count": 31,
    "eval_duration": 3941000000
}
相关推荐
带刺的坐椅21 小时前
LangChain4j 比 SolonAI 强在哪?弱在哪?
java·ai·langchain·solon·mcp
YuanlongWang21 小时前
C# 基础——值类型与引用类型的本质区别
java·jvm·c#
渡我白衣1 天前
《未来的 AI 操作系统(四)——AgentOS 的内核设计:调度、记忆与自我反思机制》
人工智能·深度学习·机器学习·语言模型·数据挖掘·人机交互·语音识别
Kay_Liang1 天前
大语言模型如何精准调用函数—— Function Calling 系统笔记
java·大数据·spring boot·笔记·ai·langchain·tools
唐青枫1 天前
C#.NET FluentValidation 全面解析:优雅实现对象验证
c#·.net
递归不收敛1 天前
大语言模型(LLM)入门笔记:嵌入向量与位置信息
人工智能·笔记·语言模型
之墨_1 天前
【大语言模型】—— 自注意力机制及其变体(交叉注意力、因果注意力、多头注意力)的代码实现
人工智能·语言模型·自然语言处理
从孑开始1 天前
ManySpeech.MoonshineAsr 使用指南
人工智能·ai·c#·.net·私有化部署·语音识别·onnx·asr·moonshine
YuanlongWang1 天前
C# 中,依赖注入(DI)的实现方式
c#
SmartSoftHelp开发辅助优化1 天前
C# WinForm 编程高手:程序,进程,线程。程序,窗体,UI,后台。是如何协调工作的?深度解析>SmartSoftHelp魔法精灵工作室
microsoft·ui·c#