- 什么是AI多轮对话记忆?
就是让AI记住你之前说过的话,能像真人聊天一样连续对话。
为什么需要记忆?例:
csharp
无记忆
你:什么是List?
AI:List是C#中的动态数组...
你:它有什么优点? ← AI不知道"它"是什么
AI:请问您说的是什么? ← 回答不出来 😓
csharp
有记忆
你:什么是List?
AI:List是C#中的动态数组...
你:它有什么优点? ← AI知道"它"指的是List
AI:List的优点有:1. 大小可变 2. 有丰富的方法... 😊
- 怎么实现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,以达到有记忆的效果。