You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者정혜성

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:38:13