C# .NET Framework中Google Gemini API对话记忆实现技术求助
实现Gemini API对话记忆的可行方案
核心思路
Gemini API的对话记忆需要通过在请求的contents数组中包含完整的历史对话轮次来实现,每个轮次必须明确指定role(user代表用户消息,model代表AI回复)和对应的文本内容。我们需要在客户端维护一个对话历史列表,每轮对话后更新历史,请求时将整个历史传入API即可实现上下文记忆。
实现步骤及修改后的代码
1. 引入依赖(可选但强烈推荐)
使用Newtonsoft.Json(Json.NET)处理JSON序列化/反序列化,避免手动拼接JSON时的转义错误。通过NuGet包管理器安装Newtonsoft.Json。
2. 完整修改后的代码
using System; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Newtonsoft.Json; namespace KJAI { // 定义对话轮次的强类型类 public class ConversationTurn { public string role { get; set; } public List<Part> parts { get; set; } = new List<Part>(); } public class Part { public string text { get; set; } } // 请求体结构 public class GeminiRequest { public List<ConversationTurn> contents { get; set; } = new List<ConversationTurn>(); public GenerationConfig generationConfig { get; set; } = new GenerationConfig(); public List<object> safetySettings { get; set; } = new List<object>(); } public class GenerationConfig { public float temperature { get; set; } = 0.9f; public int topK { get; set; } = 50; public float topP { get; set; } = 0.95f; public int maxOutputTokens { get; set; } = 4096; public List<string> stopSequences { get; set; } = new List<string>(); } // 响应解析类 public class GeminiResponse { public List<Candidate> candidates { get; set; } } public class Candidate { public ConversationTurn content { get; set; } } public partial class Form1 : Form { private string apiKey = "YOUR_API_KEY"; // 维护对话历史 private List<ConversationTurn> _chatHistory = new List<ConversationTurn>(); public Form1() { InitializeComponent(); } private async void button1_Click(object sender, EventArgs e) { string userInput = textBox1.Text.Trim(); if (string.IsNullOrEmpty(userInput)) return; // 添加用户消息到对话历史 _chatHistory.Add(new ConversationTurn { role = "user", parts = new List<Part> { new Part { text = userInput } } }); try { string aiResponse = await SendRequestAndGetResponse(); // 添加AI回复到对话历史 _chatHistory.Add(new ConversationTurn { role = "model", parts = new List<Part> { new Part { text = aiResponse } } }); // 更新UI显示完整对话 UpdateChatDisplay(); // 清空输入框 textBox1.Clear(); } catch (Exception ex) { richTextBox1.Text += $"错误:{ex.Message}{Environment.NewLine}"; } } private async Task<string> SendRequestAndGetResponse() { var requestBody = new GeminiRequest { contents = _chatHistory, generationConfig = new GenerationConfig() }; string jsonBody = JsonConvert.SerializeObject(requestBody); using var client = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Post, $"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro:generateContent?key={apiKey}"); request.Content = new StringContent(jsonBody, Encoding.UTF8); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var response = await client.SendAsync(request).ConfigureAwait(false); if (response.IsSuccessStatusCode) { string responseBody = await response.Content.ReadAsStringAsync(); var geminiResponse = JsonConvert.DeserializeObject<GeminiResponse>(responseBody); if (geminiResponse?.candidates?.Count > 0) { return geminiResponse.candidates[0].content.parts[0].text; } return "未获取到有效回复"; } else { string errorContent = await response.Content.ReadAsStringAsync(); throw new Exception($"{response.StatusCode} - {response.ReasonPhrase}{Environment.NewLine}{errorContent}"); } } private void UpdateChatDisplay() { StringBuilder chatBuilder = new StringBuilder(); foreach (var turn in _chatHistory) { string roleLabel = turn.role == "user" ? "你:" : "AI:"; chatBuilder.AppendLine($"{roleLabel}{turn.parts[0].text}"); chatBuilder.AppendLine(); // 分隔对话 } richTextBox1.Text = chatBuilder.ToString(); // 滚动到最新消息 richTextBox1.SelectionStart = richTextBox1.Text.Length; richTextBox1.ScrollToCaret(); } } }
关键说明
- 对话历史维护:通过
_chatHistory列表存储每一轮用户和AI的对话,每个轮次包含明确的角色标识和文本内容。 - JSON序列化:使用强类型类+Json.NET生成请求体,彻底避免手动拼接JSON时的转义错误(比如用户输入包含引号的场景)。
- 响应解析:通过强类型类解析API响应,比手动截取字符串更稳定,能适配API结构的小范围调整。
- UI优化:
UpdateChatDisplay方法将完整对话历史格式化后展示,同时自动滚动到最新消息,提升用户体验。
额外建议
- 若对话历史过长触发API的token限制,可实现历史截断逻辑(比如只保留最近10轮对话)。
- 可添加清空对话历史的按钮,方便用户快速重置会话。
内容的提问来源于stack exchange,提问作者정혜성
相关产品推荐
相关产品推荐

