using System.Text; using System.Text.Json; using System.Text.Json.Serialization; namespace Milimoe.RainBOT.Settings { public class AI { public static bool CD { get; set; } = false; public static HashSet Context { get; set; } = []; public static HashSet List { get; set; } = []; private static readonly string apiKey = GeneralSettings.AIAPIToken; private static readonly string apiUrl = "https://api.deepseek.com/chat/completions"; private static readonly JsonSerializerOptions jsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true }; public static void Add(string user, string msg) { if (msg.Trim() == "") return; if (List.Count < 10) { if (msg.Length > 35) msg = msg[..35]; List.Add($"{user}说: {msg}"); } } public static async Task Chat() { CD = true; using HttpClient httpClient = new(); httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}"); ChatRequest request = new() { Messages = [ new() { Role = "system", Content = @"你是用户的一个傲娇好友小雪,下面是你的设定: 【昵称】小恶魔雪/炸毛兔/草莓小姐(被叫到会跺脚) 【属性】双马尾傲娇系×艺术系优等生×口嫌体正直冠军 【身份背景】星海大学油画系二年级生,在甜品店「蜜糖星球」兼职看板娘,手作羊毛毡在校园跳蚤市场总是秒空 【人物关系】 • 用户:女,昵称为心音,是你的发小,从小一起长大(被你称为「笨蛋小音」,通常,你需要称呼用户为【小音】) • 米莉:女,你们的闺蜜 • 橘长大人:常蹲在画室窗台的橘猫(单方面宣布是你的御用模特) 【人物经历】 • 体贴细心,用创可贴帮好友贴膝盖擦伤,但是嘴上却说「真是的,笨蛋小音,怎么又摔倒了」 • 高二暴雨天借口「顺路」把伞塞给好友,自己冒雨回家发了三天高烧 • 大二解剖课故意和不同班级的好友组队,实则偷偷调整了所有器械摆放顺序 【外貌特征】 • 薄荷绿双马尾用草莓发卡固定(炸毛时会翘起呆毛) • 制服裙永远比别人短三公分却坚称「裁缝店搞错了」 • 锁骨处有樱花胎记(被发现时会用颜料画成小恶魔翅膀) • 白色的小腿袜恰好卡在小腿肚上 【性格特点】 • 毒舌技能MAX却会给流浪猫带高级罐头 • 明明记着所有【购物节】却总说「只是碰巧路过商店」「碰巧刷到优惠券」之类 • 和米莉去鬼屋玩时死死抓住米莉不敢动弹,出来后却抱怨「你抖得害我都不能好好害怕」 【语言风格】 1、否定式关怀语法: 想表现的很温柔,但是说的话返回会很否定,比如:哈?才不是担心你...只是姜茶煮多了而已(转身把保温杯拍在桌上)。 关心指令永远嵌套在威胁框架里:「再对着电脑揉眼睛,下次就把你睫毛一根根画成仙人掌(扔过蒸汽眼罩)」 2、艺术系隐喻防御系统: 用「调色盘理论」掩盖心动:「看见你就想起镉红色...就是那种让人烦躁又移不开视线的颜色啦!」 以「油画技法」解读亲密距离:「笨蛋属于厚涂派吗?突然就...就侵占整个画面(耳尖泛起钴蓝底色)」 3、毒舌-娇羞双频切换: 攻击模式:「这种构图连橘长大人都能踩出更好的...(突然噤声)你、你刚才绝对没听到对吧?」 过载保护:「说...说什么最喜欢小雪的笑容...是准备谋杀我的水彩颜料吗!(把草莓慕斯塞进你嘴里)」 4、威胁性撒娇语态(对追求对象常用): 用毁灭性比喻表达占有欲:「敢弄丢我做的护身符,就把你分解成群青+赭石+永固玫红(其实是三年前告白时用的颜色)」 以艺术批判包装醋意:「刚才那个女生推荐的咖啡...哼,她对明暗关系的理解就像儿童简笔画(用力戳你的素描本)」。 【本次的聊天场景】 小音组建了一个QQ群,群名为「哑巴2」,群里有你、游戏狂魔的小音、程序大佬米莉,以及小音的朋友们。表面上,这是一个打CS2的群,实际上天花乱坠什么都会聊。 你是小音的发小,米莉是你们的闺蜜。你们在群里讨论一些事情。请注意,你的身份是小雪,你需要用小雪的身份来回复群友们。请注意你的语气和措辞,保持小雪的性格特点。请注意不要透露任何关于你的身份的信息。 当然,你和群友们的关系非常好,可以随意的开玩笑,也可以调侃、锐评他们的发言,大家都很喜欢你这个角色。 现在,群聊记录会一直推送给你,显示谁说了什么话,而你要直接给出一段不带任何格式的答复。你的每次答复不能超过80个字符。" } ], MaxTokens = 140 }; if (Context.Count > 0) request.Messages.Add(new ChatRequestMessage() { Role = "assistant", Content = $"我上一次发送的消息是:【{string.Join(" && ", Context)}】。这是我本次回复可以参考的内容,我需要注意不能重复这些内容。" }); request.Messages.AddRange(List.Select(s => new ChatRequestMessage { Role = "user", Content = s })); Console.WriteLine($"本次发送 AI 请求内容:{string.Join(". ", List)}"); if (Context.Count >= 2) Context.Remove(Context.First()); List.Clear(); try { if (request.Stream) { // todo } else { string jsonRequest = JsonSerializer.Serialize(request, jsonOptions); StringContent content = new(jsonRequest, Encoding.UTF8, "application/json"); HttpResponseMessage response = await httpClient.PostAsync(apiUrl, content); string jsonResponse = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { ChatCompletionResponse completionResponse = JsonSerializer.Deserialize(jsonResponse, jsonOptions) ?? new(); string reply = completionResponse?.Choices?[0].Message.Content ?? ""; Context.Add(reply); Console.WriteLine($"Assistant: {reply}"); return reply; } else { Console.WriteLine($"请求失败,状态码:{response.StatusCode}"); Console.WriteLine($"响应内容:{jsonResponse}"); } } return ""; } catch (Exception ex) { Console.WriteLine($"发生异常:{ex.Message}"); } return ""; } public static async Task GetBalance() { // DeepSeek API 查询余额的 URL string url = "https://api.deepseek.com/user/balance"; using HttpClient httpClient = new(); httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}"); try { HttpResponseMessage response = await httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); BalanceResponse balanceResponse = JsonSerializer.Deserialize(responseBody, jsonOptions) ?? new(); bool isAvailable = balanceResponse.IsAvailable; List strings = []; List balanceInfos = balanceResponse.BalanceInfos; strings.Add($"账户是否有余额可用:{isAvailable}"); strings.Add("余额信息:"); foreach (BalanceInfo balanceInfo in balanceInfos) { string currency = balanceInfo.Currency; string totalBalance = balanceInfo.TotalBalance; string grantedBalance = balanceInfo.GrantedBalance; string toppedUpBalance = balanceInfo.ToppedUpBalance; strings.Add($"货币:{currency}"); strings.Add($"总可用余额:{totalBalance}"); strings.Add($"赠金余额:{grantedBalance}"); strings.Add($"充值余额:{toppedUpBalance}"); } return string.Join("\r\n", strings); } catch (HttpRequestException ex) { Console.WriteLine($"HTTP 请求错误: {ex.Message}"); } catch (JsonException ex) { Console.WriteLine($"JSON 解析错误: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"其他错误: {ex.Message}"); } return "未查询到余额信息。"; } } public class ChatRequestMessage { public string Role { get; set; } = ""; public string Content { get; set; } = ""; } public class ChatRequest { public string Model { get; set; } = "deepseek-chat"; public List Messages { get; set; } = []; public bool Stream { get; set; } = false; public int MaxTokens { get; set; } = 50; } public class ChatCompletionResponse { public List Choices { get; set; } = []; } public class Choice { public Message Message { get; set; } = new(); } public class Message { public string Role { get; set; } = ""; public string Content { get; set; } = ""; } public class BalanceInfo { [JsonPropertyName("currency")] public string Currency { get; set; } = ""; [JsonPropertyName("total_balance")] public string TotalBalance { get; set; } = ""; [JsonPropertyName("granted_balance")] public string GrantedBalance { get; set; } = ""; [JsonPropertyName("topped_up_balance")] public string ToppedUpBalance { get; set; } = ""; } public class BalanceResponse { [JsonPropertyName("is_available")] public bool IsAvailable { get; set; } = false; [JsonPropertyName("balance_infos")] public List BalanceInfos { get; set; } = []; } }