C#实现一个HttpClient集成通义千问-多轮对话功能实现
多轮对话功能实现
- 视频教程
- 实现原理
- 消息的类型
- 功能开发
- 消息类
- 修改请求体
- 修改发送请求函数
- 修改用户消息输入
- 多轮对话的token
- 消息完整文档
- 消息类型
视频教程
.Net+AI开发入门HttpClient实现通义千问集成-多轮对话功能实现
实现原理
一直保留更新messages

现在设置的meessages只设置了两条内容
- system:系统消息,给AI设置一个角色,
- user:用户消息,你提的问题
消息的类型
根据OpenAI API官网,消息有以下几种类型

我们现在主要用的就三个:
- System Message :系统消息,用于指定模型的目标或角色(放在messages第一位)
- User Message:用户消息,用户发送给模型的消息。
- Assistant Message:助手消息,模型对用户消息的回复。
实现的效果:
messages:
system:xx
user:xxx
assistant:xxx
user:xxx
assistant:xxx
功能开发
消息类
创建一个消息类
public class ChatMessage{public string role { get; set; }public string message { get; set; }}
修改请求体
修改请求体,将message内容改成一个占位字符串,用于后面修改

增加一个消息集合messages 用于存储消息
List<ChatMessage> messages = new List<ChatMessage>();messages.Add(new ChatMessage() { role = "system", content = "你是一个C#高手" });
修改发送请求函数
增加一个result,获取流式输出的content完整内容,返回完整的助手消息内容,用于后续添加到messages中
private static async Task<string> SendPostRequestAsync(string url,string jsonContent,string apiKey){using (var content = new StringContent(jsonContent, Encoding.UTF8, "application/json")){// 发送请求并获取响应HttpResponseMessage response = await httpClient.PostAsync(url, content);// 处理响应if (response.IsSuccessStatusCode){string result = "";using (Stream stream = await response.Content.ReadAsStreamAsync())using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)){string line;while ((line = await reader.ReadLineAsync()) != null){if (string.IsNullOrEmpty(line))continue;string data = line.Substring(6);if (data == "[DONE]"){//结束标志break;}var streamObject = JsonSerializer.Deserialize<StreamObject>(data);if (streamObject.choices.Count() > 0){var contentRes = streamObject.choices[0].delta.content;Console.Write(contentRes);result += contentRes;}if (streamObject.usage != null){Console.WriteLine($"Usage: prompt_tokens:{streamObject.usage.prompt_tokens}, completion_tokens:{streamObject.usage.completion_tokens}, total_tokens:{streamObject.usage.total_tokens}");}Thread.Sleep(200);}Console.WriteLine();}return result;// return await response.Content.ReadAsStringAsync();}else{Console.WriteLine($"请求失败: {response.StatusCode}");return $"请求失败: {response.StatusCode}";}}}
将httpclient设置请求头的代码拿到一开始,只设置一次

修改用户消息输入
- 修改用户消息,改成用户直接在控制台上输入,输入之后再加入到消息中
- 然后将消息集合
messages序列化成字符串,替换掉jsonContent里面的消息占位符messagesContent,再发送出去 - 接收到模型返回的助手消息之后,将助手消息也添加到
messages中去,role为"assistant" - 然后下次发送,这些消息累加一起再发送
while (true){Console.Write("User:");var usermessage = Console.ReadLine();if (string.IsNullOrEmpty(usermessage)){continue;}if (usermessage == "exit"){break;}var user = new ChatMessage() { role = "user", content = usermessage };messages.Add(user);var str = JsonSerializer.Serialize(messages);var send = jsonContent.Replace("messagesContent", str);// 发送请求并获取响应Console.WriteLine("assistant:");var result = await SendPostRequestAsync(url, send, apiKey);messages.Add(new ChatMessage() { role = "assistant", content = result });}
多轮对话的token
多轮对话的token是持续累加的,第二次发送的时候相当于第一次发送和返回的消息也发送了,都算在第二次发送的token中

消息完整文档
以下详细内容来着OpenAI API翻译
https://platform.openai.com/docs/api-reference/chat/create
消息类型
系统消息 (System message)
object
-
content(字符串或数组) 必填系统消息的内容。
-
role(字符串) 必填消息作者的角色,此处为
"system"。 -
name(字符串) 可选用于区分相同角色参与者的可选名称。
用户消息 (User message)
object
-
content(字符串或数组) 必填用户消息的内容。
-
role(字符串) 必填消息作者的角色,此处为
"user"。 -
name(字符串) 可选用于区分相同角色参与者的可选名称。
助手消息 (Assistant message)
object
-
content(字符串或数组) 可选助手消息的内容。除非指定
tool_calls或function_call,否则必填。 -
refusal(字符串或 null) 可选助手的拒绝消息。
-
role(字符串) 必填消息作者的角色,此处为
"assistant"。 -
name(字符串) 可选用于区分相同角色参与者的可选名称。
-
audio(对象或 null) 可选与助手之前的音频响应相关的数据。
-
id(字符串)必填唯一标识模型生成的音频响应。
-
-
tool_call(数组) 必填模型生成的工具调用列表(例如函数调用)。
-
id(字符串)必填具调用的唯一 ID。
-
type(字符串)必填工具类型,目前仅支持
function。 -
function(对象)必填模型调用的函数。
-
name(字符串)必填要调用的函数名称。
-
arguments(字符串)必填模型以 JSON 格式生成的函数调用参数。
- 注意:模型生成的参数可能无效,或者包含未在函数定义中描述的参数。
- 建议: 在调用函数之前,应在代码中验证参数
-
-
-
function_call已弃用 (对象 或者 null) 选填模型生成的工具调用列表(例如函数调用)。
-
name(字符串)必填要调用的函数名称。
-
arguments(字符串)必填模型以 JSON 格式生成的函数调用参数。
-
工具消息 (Tool message)
object
-
role(字符串) 必填消息作者的角色,此处为
"tool"。 -
content(字符串或数组) 必填工具消息的内容。
-
tool_call_id(字符串) 必填对应工具调用的消息 ID。
函数消息 (Function message)
(已弃用)
object
-
role(字符串) 必填消息作者的角色,此处为
"function"。 -
content(字符串或 null) 必填函数消息的内容。
-
name(字符串) 必填函数名称。
相关文章:
C#实现一个HttpClient集成通义千问-多轮对话功能实现
多轮对话功能实现 视频教程实现原理消息的类型 功能开发消息类修改请求体修改发送请求函数修改用户消息输入 多轮对话的token消息完整文档消息类型 视频教程 .NetAI开发入门HttpClient实现通义千问集成-多轮对话功能实现 实现原理 一直保留更新messages 现在设置的meessages只…...
Java Web 7 请求响应(Postman)
前言(SpringBoot程序请求响应流程) 以上一章的程序为例,一个基于SpringBoot的方式开发一个web应用,浏览器发起请求 /hello 后 ,给浏览器返回字符串 “Hello World ~”。 而我们在开发web程序时呢,定义了一…...
Android APP自学笔记
摘抄于大学期间记录在QQ空间的一篇自学笔记,当前清理空间,本来想直接删除掉的,但是感觉有些舍不得,因此先搬移过来。 Android导入已有外部数据库 2015.06.26在QQ空间记录:在Android中不能直接打开res aw目录中的数据…...
Linux 系统报打开的文件过多
1.问题 1804012290 [reactor-http-epoll-1] WARN i.n.channel.DefaultChannelPipeline - An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception. - io.nett…...
javaWeb之过滤器(Filter)
目录 前言 过滤器概述 什么是过滤器 过滤器详细 过滤器的生命周期 过滤器的应用 创建一个简单的Filter类步骤 注意:指定拦截路径,我们有两种方式 实例 前言 本篇博客的核心 知道过滤器的整个拦截过程知道如何指定拦截路径知道过滤器的生命周期…...
ModStartBlog v10.0.0 发布时间自定义,多图快速粘贴,博客编辑器升级
ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用,支持后台一键快速安装,让开发者能快的实现业务功能开发。 系统完全开源,基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场,后台一键快速安装 …...
Unexpected token ‘<‘, “<!doctype “... is not valid JSON
Unexpected token ‘<’, "<!doctype "… is not valid JSON 在前端开发时,遇到以下报错内容。 1.报错内容如下: // 报错内容 Uncaught (in promise) SyntaxError: Unexpected token <, "<!doctype "... is not valid…...
24/12/9 算法笔记<强化学习> PPO,DPPO
PPO是目前非常流行的增强学习算法,OpenAI把PPO作为目前baseline算法,首选PPO,可想而知,PPO可能不是最强的,但是是最广泛的。 PPO是基于AC架构,因为AC架构有一个好处,就是解决了连续动作空间的问…...
Linux下编译安装METIS
本文记录Linux下编译安装METIS的流程。 零、环境 操作系统Ubuntu 22.04.4 LTSVS Code1.92.1Git2.34.1GCC11.4.0CMake3.22.1 一、安装依赖 1.1 下载GKlib sudo apt-get install build-essential sudo apt-get install cmake 2.2 编译安装GKlib 下载GKlib代码, …...
【数据库】关系代数和SQL语句
一 对于教学数据库的三个基本表 学生S(S#,SNAME,AGE,SEX) 学习SC(S#,C#,GRADE) 课程(C#,CNAME,TEACHER) (1)试用关系代数表达式和SQL语句表示:检索WANG同学不学的课程号 select C# from C where C# not in(select C# from SCwhere S# in…...
amazon亚马逊滑动识别验证码
注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 本文识别已同步上线至OCR识别网站: http://yxlocr.nat300.top/ocr/other/15 亚马逊的滑动还原验证码数据集如下: 和某顶象的差不多,图片分割高度是中间固定的,…...
Android Studio 创建虚拟设备的详细图文操作教程
本篇文章主要讲解 Android Studio 创建模拟器详细图文操作,包含了每一步的详细操作,便于理解和掌握对模拟的创建。 日期:2024年12月9日 作者:任聪聪 运行效果: 说明:创建运行后,点击右侧如下图…...
网络安全法-附则
第七章 附 则 第七十六条 本法下列用语的含义: (一)网络,是指由计算机或者其他信息终端及相关设备组成的按照一定的规则和程序对信息进行收集、存储、传输、交换、处理的系统。 (二)网络安全ÿ…...
CSS核心(上)
CSS 介绍 层叠样式表(英语:Cascading Style Sheets, 缩写:CSS; 又叫串样式列表,级联样式表,串接样式表,阶层式样式表)是一种用来为结构化文档(HTML或XML应用)添加样式(…...
深度学习常用损失函数介绍
均方差损失(Mean Square Error,MSE) 均方误差损失又称为二次损失、L2损失,常用于回归预测任务中。均方误差函数通过计算预测值和实际值之间距离(即误差)的平方来衡量模型优劣。即预测值和真实值越接近&…...
HarmonyOS-中级(四)
文章目录 Native适配开发三方库的基本使用 🏡作者主页:点击! 🤖HarmonyOS专栏:点击! ⏰️创作时间:2024年12月09日11点12分 Native适配开发 Node-API HarmonyOS Node-API 是 HarmonyOS 提供的…...
React v19稳定版发布12.5
🤖 作者简介:水煮白菜王 ,一位资深前端劝退师 👻 👀 文章专栏: 前端专栏 ,记录一下平时在博客写作中,总结出的一些开发技巧✍。 感谢支持💕💕💕 目…...
【毕业设计选题】深度学习类毕业设计选题参考 开题指导
目录 前言 毕设选题 开题指导建议 更多精选选题 选题帮助 最后 前言 大家好,这里是海浪学长毕设专题! 大四是整个大学期间最忙碌的时光,一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整…...
NanoLog起步笔记-4-Server端的两个线程
nonolog起步笔记-4-Server端的两个线程 Server端的两个线程两个线程的角色与各自的职责RuntimeLogger::compressionThreadMain线程 详细学习一下相关的代码第三个线程第一次出现原位置swip buffer Server端的两个线程 如前所述,nanolog的server端,相对而…...
linux zookeeper安装并服务化
1.版本信息 系统:centos7.6 java版本:java 8(已经安装好) zookeeper版本:3.6.3 2.zookeeper安装并测试 1.上传文件至指定目录并解压 切换至cd downloads 目录下, rz上传文件 解压:tar -zxvf apache-zookeeper-3.…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
