C#调用 AI学习从0开始-第1阶段(基础与工具)-第7天多轮对话记忆

  1. 什么是AI多轮对话记忆?
    就是让AI记住你之前说过的话,能像真人聊天一样连续对话。
    为什么需要记忆?例:
csharp 复制代码
	无记忆
	
	你:什么是List?
	AI:List是C#中的动态数组...

	你:它有什么优点?     ← AI不知道"它"是什么
	AI:请问您说的是什么?  ← 回答不出来 😓
csharp 复制代码
	有记忆
	
	你:什么是List?
	AI:List是C#中的动态数组...

	你:它有什么优点?     ← AI知道"它"指的是List
	AI:List的优点有:1. 大小可变 2. 有丰富的方法... 😊
  1. 怎么实现AI多轮对话记忆
    每次问问题,都把之前聊过的所有内容一起发给AI。

核心代码:

csharp 复制代码
		//1. 添加:保存对话历史
        private List<ChatMessage> _history=new List<ChatMessage>();

        public async Task<string> RequstAI_Message_Multi(string userMessage, string model = "qwen-turbo", float? temperature = null, int? maxTokens = null)
        {
            string resp_answer = "";

            // 替换成你的阿里云百炼 API Key
            const string apiKey = ConfigCommon.apiKey;  //此处写你申请的API Key
            const string url = ConfigCommon.url_chat;  //"https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions";

            var client = new HttpClient();
            client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");

            //1 把用户的消息加入历史
            _history.Add(new ChatMessage("user", userMessage));

            //请求体
            var requestBody = new
            {
                model = "qwen-turbo",
                messages = _history,  //MessagesIn
                temperature = temperature,  // 低温度让输出更稳定 高温度更创新
                maxTokens = maxTokens,
                stream = false
            };

            var json = JsonSerializer.Serialize(requestBody);
            var content = new StringContent(json, Encoding.UTF8, "application/json");  //使用 response_format: json_object 时,必须在 messages 中的某个地方明确提到"json"这个词,否则会调用报错。
            //Console.WriteLine("正在调用阿里云百炼 AI...\n");

            try
            {
                var response = await client.PostAsync(url, content);
                var responseString = await response.Content.ReadAsStringAsync();

                if (response.IsSuccessStatusCode)
                {
                    var doc = JsonDocument.Parse(responseString);
                    var answer = doc.RootElement
                        .GetProperty("choices")[0]
                        .GetProperty("message")
                        .GetProperty("content")
                        .GetString();
                    Console.WriteLine($"AI 回答:{answer}");

                    resp_answer = answer;

                    // 把AI的回答也加入历史
                    _history.Add(new ChatMessage("assistant", answer));
                }
                else
                {
                    Console.WriteLine($"HTTP 错误:{response.StatusCode}");
                    Console.WriteLine($"响应内容:{responseString}");
                }

                
            }
            catch (Exception ex)
            {
                Console.WriteLine($"异常:{ex.Message}");

            }
            return resp_answer;
        }
        
/// <summary>
        /// 2. 设置系统提示词(可选,放在历史第一位)
        /// </summary>
        public void SetSystemPrompt(string systemPrompt)
        {
            // 如果已经有system消息,先移除
            if (_history.Count > 0 && _history[0].Role == "system")
            {
                _history.RemoveAt(0);
            }
            // 插入到最前面
            _history.Insert(0, new ChatMessage("system", systemPrompt));
        }

        /// <summary>
        /// 3. 清空历史记录(重新开始对话)
        /// </summary>
        public void ClearHistory()
        {
            _history.Clear();
        }
        /// <summary>
        /// 4. 清空历史但保留system prompt
        /// </summary>
        public void ClearHistoryKeepSystem()
        {
            string systemPrompt = null;
            if (_history.Count > 0 && _history[0].Role == "system")
            {
                systemPrompt = _history[0].Content;
            }
            _history.Clear();
            if (!string.IsNullOrEmpty(systemPrompt))
            {
                _history.Add(new ChatMessage("system", systemPrompt));
            }
        }

        /// <summary>
        /// 5. 查看当前历史记录
        /// </summary>
        public IReadOnlyList<ChatMessage> GetHistory()
        {
            return _history.AsReadOnly();
        }

        /// <summary>
        /// 6. 打印历史记录(调试用)
        /// </summary>
        public void PrintHistory()
        {
            Console.WriteLine($"\n=== 对话历史(共{_history.Count}条)===");
            foreach (var msg in _history)
            {
                string preview = msg.Content.Length > 50
                    ? msg.Content.Substring(0, 50) + "..."
                    : msg.Content;
                Console.WriteLine($"[{msg.Role}]: {preview}");
            }
            Console.WriteLine("================================\n");
        }

调用代码:

csharp 复制代码
public static async Task Day()
        {
            try
            {
                Console.WriteLine($"多轮对话记忆\r\n");

                CommonClass client = new CommonClass();
                client.SetSystemPrompt("你是一个C#编程助手,回答要简洁专业");

                Console.WriteLine("用户:什么是C#的List<T>?");
                var reply1 = await client.RequstAI_Message_Multi("什么是C#的List<T>?");
                Console.WriteLine($"AI:{reply1}\n");

                // 第2轮(AI需要知道"它"指的是什么)
                Console.WriteLine("用户:它有什么优点?");
                var reply2 = await client.RequstAI_Message_Multi("它有什么优点?");
                Console.WriteLine($"AI:{reply2}\n");

                // 第3轮
                Console.WriteLine("用户:那它和数组有什么区别?");
                var reply3 = await client.RequstAI_Message_Multi("那它和数组有什么区别?");
                Console.WriteLine($"AI:{reply3}\n");

                // 查看历史
                client.PrintHistory();


                // 测试清空
                Console.WriteLine("--- 清空历史后 ---");
                client.ClearHistory();
                Console.WriteLine($"清空后历史条数:{client.GetHistory().Count}");

                Console.WriteLine("\n用户:刚才我们聊了什么?");
                var reply4 = await client.RequstAI_Message_Multi("刚才我们聊了什么?");
                Console.WriteLine($"AI:{reply4}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"异常:{ex.Message}");

            }
        }

辅助类:

csharp 复制代码
public class ChatMessage
    {
        /// <summary>
        /// 消息角色:system / user / assistant
        /// </summary>
        [JsonPropertyName("role")]
        public string Role { get; set; } = string.Empty;

        /// <summary>
        /// 消息内容
        /// </summary>
        [JsonPropertyName("content")]
        public string Content { get; set; } = string.Empty;

        public ChatMessage() { }

        public ChatMessage(string role, string content)
        {
            Role = role;
            Content = content;
        }

        public override string ToString()
        {
            return $"{Role}: {Content}";
        }
    }

public class ChatResponse
    {
        [JsonPropertyName("choices")]
        public List<Choice> Choices { get; set; } = new List<Choice>();
    }

    public class Choice
    {
        [JsonPropertyName("message")]
        public ChatMessage Message { get; set; } = new ChatMessage();
    }

总结:多轮对话记忆 = 用List _history 保存所有对话,每次请求都传给API,以达到有记忆的效果。

相关推荐
Justin3go3 分钟前
AI 引荐流量报告:哪些独立产品正在从 ChatGPT 获客?
人工智能·seo
风流 少年16 分钟前
Spring AI 2.0:SSE
java·人工智能·spring
深小乐38 分钟前
AI 项目上线:折腾 Cloudflare,真香也藏不少坑
人工智能
ACP广源盛139246256731 小时前
Qwen3.8‑2.4T 开源落地@ACP#国产 MoE 私有化部署下 GSV2221 视频转换芯片机遇分析
大数据·数据库·人工智能
学运维的Kysan2 小时前
暑假运维学习打卡第二十六天8.17
学习
冬奇Lab2 小时前
开源项目第190期:claude-video — 给 Claude 装上「眼睛」看视频,一条命令分析 YouTube/Loom/本地视频
人工智能·开源·claude
七牛开发者2 小时前
为什么 Go 很适合 AI 辅助开发?
数据库·人工智能·python·elasticsearch·log4j
dear_bi_MyOnly2 小时前
AI人工智能分类识别——机器如何学习
人工智能·学习·分类
冬奇Lab2 小时前
Code Agent 解剖(04):系统提示词是怎么组装的,agent 的「人格」从哪来?
人工智能·开源·agent