From 2a955b5b43a52e5c1d05daf7854e99f7c7aae0b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com> Date: Wed, 11 Dec 2024 11:54:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20chatGPT=20=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VideoAnalysis/Controllers/Dto/ApiDto.cs | 2 +- VideoAnalysis/Program.cs | 7 +- VideoAnalysis/appsettings.json | 5 +- .../AICore/{ChatGPT => GPT}/BserGPT.cs | 6 +- .../AICore/GPT/ChatGPT/ChatGPTClient.cs | 138 ++++++++++++ .../AICore/GPT/ChatGPT/ChatGPTModel.cs | 69 ++++++ .../AICore/GPT/ChatGPT/Chat_GPT.cs | 211 ++++++++++++++++++ .../AICore/{ChatGPT => GPT}/Dto/CallGPTRes.cs | 16 +- .../{ChatGPT => GPT}/Dto/QuestionRes.cs | 6 +- .../AICore/{ChatGPT => GPT}/KIMI/KIMI_GPT.cs | 22 +- .../{ChatGPT => GPT}/KIMI/MoonshotClient.cs | 12 +- .../{ChatGPT => GPT}/KIMI/MoonshotModel.cs | 4 +- .../AICore/SherpaOnnx/SenseVoice.cs | 1 - .../AICore/SherpaOnnx/SherpaOnnxDto.cs | 4 +- VideoAnalysisCore/Common/AppCommon.cs | 8 +- VideoAnalysisCore/Common/RedisExpand.cs | 5 +- .../Model/Dto/SpeakerCaptionsDto.cs | 3 +- VideoAnalysisCore/Model/VideoTask.cs | 3 +- 18 files changed, 472 insertions(+), 50 deletions(-) rename VideoAnalysisCore/AICore/{ChatGPT => GPT}/BserGPT.cs (70%) create mode 100644 VideoAnalysisCore/AICore/GPT/ChatGPT/ChatGPTClient.cs create mode 100644 VideoAnalysisCore/AICore/GPT/ChatGPT/ChatGPTModel.cs create mode 100644 VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs rename VideoAnalysisCore/AICore/{ChatGPT => GPT}/Dto/CallGPTRes.cs (79%) rename VideoAnalysisCore/AICore/{ChatGPT => GPT}/Dto/QuestionRes.cs (94%) rename VideoAnalysisCore/AICore/{ChatGPT => GPT}/KIMI/KIMI_GPT.cs (96%) rename VideoAnalysisCore/AICore/{ChatGPT => GPT}/KIMI/MoonshotClient.cs (97%) rename VideoAnalysisCore/AICore/{ChatGPT => GPT}/KIMI/MoonshotModel.cs (99%) diff --git a/VideoAnalysis/Controllers/Dto/ApiDto.cs b/VideoAnalysis/Controllers/Dto/ApiDto.cs index 9b892ec..11d5104 100644 --- a/VideoAnalysis/Controllers/Dto/ApiDto.cs +++ b/VideoAnalysis/Controllers/Dto/ApiDto.cs @@ -1,7 +1,7 @@ using AntDesign; using System.ComponentModel.DataAnnotations; using UserCenter.Model.Enum; -using VideoAnalysisCore.AICore.ChatGPT.Dto; +using VideoAnalysisCore.AICore.GPT.Dto; using VideoAnalysisCore.Enum; namespace Learn.VideoAnalysis.Controllers.Dto diff --git a/VideoAnalysis/Program.cs b/VideoAnalysis/Program.cs index a413ac5..071d5e4 100644 --- a/VideoAnalysis/Program.cs +++ b/VideoAnalysis/Program.cs @@ -2,10 +2,11 @@ using VideoAnalysisCore.Common; using Learn.VideoAnalysis.Components; using Microsoft.OpenApi.Models; using AntDesign.ProLayout; -using VideoAnalysisCore.AICore.ChatGPT; -using VideoAnalysisCore.AICore.ChatGPT.KIMI; using VideoAnalysisCore.AICore.SherpaOnnx; using Mapster; +using VideoAnalysisCore.AICore.GPT; +using VideoAnalysisCore.AICore.GPT.KIMI; +using VideoAnalysisCore.AICore.GPT.ChatGPT; @@ -78,7 +79,7 @@ namespace Learn.VideoAnalysis builder.Services.Configure(builder.Configuration.GetSection("ProSettings")); builder.Services.AddHttpClient(); - builder.Services.AddSingleton(); + builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/VideoAnalysis/appsettings.json b/VideoAnalysis/appsettings.json index 67fc02a..453bffd 100644 --- a/VideoAnalysis/appsettings.json +++ b/VideoAnalysis/appsettings.json @@ -24,8 +24,11 @@ "ChatGpt": { "KIMI": { "Host": "https://api.moonshot.cn", - //"ApiKey": "sk-CNYJdRHgJsgtgw1Q8GhQ5ayXuFPVLSk5bduOF4l2FMvI5lUo" "ApiKey": "sk-8BvvhESZIkgUbiaaJhglPxFa4o2X9H3xEv9lXELrWWwGxHWY" + }, + "ChatGpt": { + "Host": "https://api.oaibest.com/", + "ApiKey": "sk-D15tBln31N7dI9Fi7lds7OySFv5tOEK7DMNsG5rY2E6DCr4s" } }, "DB": { diff --git a/VideoAnalysisCore/AICore/ChatGPT/BserGPT.cs b/VideoAnalysisCore/AICore/GPT/BserGPT.cs similarity index 70% rename from VideoAnalysisCore/AICore/ChatGPT/BserGPT.cs rename to VideoAnalysisCore/AICore/GPT/BserGPT.cs index 7bfb2ea..eaa9368 100644 --- a/VideoAnalysisCore/AICore/ChatGPT/BserGPT.cs +++ b/VideoAnalysisCore/AICore/GPT/BserGPT.cs @@ -1,9 +1,9 @@ -using VideoAnalysisCore.AICore.ChatGPT.Dto; +using VideoAnalysisCore.AICore.GPT.Dto; using VideoAnalysisCore.AICore.SherpaOnnx; using VideoAnalysisCore.Common; using Whisper.net; -namespace VideoAnalysisCore.AICore.ChatGPT +namespace VideoAnalysisCore.AICore.GPT { /// /// GPT 接口 @@ -15,6 +15,6 @@ namespace VideoAnalysisCore.AICore.ChatGPT /// /// 任务id /// - public Task CallGPT(string task); + public Task CallGPT(string task); } } diff --git a/VideoAnalysisCore/AICore/GPT/ChatGPT/ChatGPTClient.cs b/VideoAnalysisCore/AICore/GPT/ChatGPT/ChatGPTClient.cs new file mode 100644 index 0000000..902c340 --- /dev/null +++ b/VideoAnalysisCore/AICore/GPT/ChatGPT/ChatGPTClient.cs @@ -0,0 +1,138 @@ +using VideoAnalysisCore.Common; +using System.Net.Http.Headers; +using System.Text; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using System.Net.Http; +using Newtonsoft.Json; +using System.Net.Http.Json; +using AntDesign; +using OneOf.Types; +using System.Net; + + +namespace VideoAnalysisCore.AICore.GPT.ChatGPT +{ + + public class ChatGPTClient + { + public static string Host = AppCommon.Config.ChatGpt.ChatGpt.Host; + public static string ApiKey = AppCommon.Config.ChatGpt.ChatGpt.ApiKey; + + private readonly IHttpClientFactory _httpClientFactory; + + public ChatGPTClient(IHttpClientFactory httpClientFactory) + { + _httpClientFactory = httpClientFactory; + } + + /// + /// ChatSSE[流式传输 更稳定] + /// + /// + /// Return HttpResponseMessage for SSE + public async Task<(Usage u, string res)?> ChatSSE(ChatRequest chatReq) + { + throw new Exception($"未实现"); + //chatReq.stream = true; + var requestBody = System.Text.Json.JsonSerializer.Serialize(chatReq); + var chatResp = await PostJsonStreamAsync("/v1/chat/completions", requestBody); + using var stream = await chatResp.Content.ReadAsStreamAsync(); + using var reader = new StreamReader(stream, Encoding.UTF8); + string line; + StringBuilder messageBuilder = new StringBuilder(); + ChatRes lastChat = new ChatRes(); + + //while ((line = await reader.ReadLineAsync()) != null) + //{ + // if (line.EndsWith("[DONE]")) + // { + // // 表示一条消息结束 + // string message = messageBuilder.ToString(); + // messageBuilder.Clear(); + // var u = lastChat?.choices?.FirstOrDefault()?.usage; + // if (u == null || string.IsNullOrEmpty(message)) + // return null; + // return (u, message); + // } + // else if (line.StartsWith("data:")) + // { + // try + // { + // var data = System.Text.Json.JsonSerializer.Deserialize(line.Substring("data:".Length).Trim()); + // lastChat = data; + // var str = data?.choices.FirstOrDefault()?.delta.content; + // if (!string.IsNullOrEmpty(str)) + // messageBuilder.Append(str); + // } + // catch (Exception e) + // { + // Console.WriteLine("异常 ChatSSE=>"); + // Console.WriteLine(line); + // Console.WriteLine(e.Message); + // Console.WriteLine(e.StackTrace); + // } + // } + //} + return null; + } + + /// + /// Chat + /// + /// + /// Return HttpResponseMessage for SSE + public async Task<(Usage u, string res)?> Chat(ChatRequest chatReq) + { + var requestBody = System.Text.Json.JsonSerializer.Serialize(chatReq); + var chatResp = await PostJsonStreamAsync("/v1/chat/completions", requestBody); + var res = await chatResp.Content.ReadFromJsonAsync(); + var chatResContent = res?.choices.FirstOrDefault()?.message.content.Trim(); + + if (res is null) + throw new Exception($" ChatGPT模型返回异常 返回参数: " + + $" {System.Text.Json.JsonSerializer.Serialize(res)}"); + + if (string.IsNullOrEmpty(chatResContent)) + return null; + return (res.usage, chatResContent); + } + + + private async Task PostJsonStreamAsync(string path, string json) + { + var uriBuilder = new UriBuilder(Host + path); + var maxRestart = 4; + var errorMSG = new Exception[maxRestart]; + for (int i = 0; i < maxRestart; i++) + { + try + { + var client = _httpClientFactory.CreateClient(); + client.DefaultRequestHeaders.Authorization = + new AuthenticationHeaderValue("Bearer", AppCommon.Config.ChatGpt.ChatGpt.ApiKey); + client.Timeout = TimeSpan.FromSeconds(Timeout.Infinite);//超时时间20分钟 + client.DefaultRequestVersion = HttpVersion.Version20; + client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower; + client.DefaultRequestHeaders.ConnectionClose = true; + + var content = new StringContent(json, Encoding.UTF8, "application/json"); + return await client.PostAsync(uriBuilder.Uri, content); + } + catch (Exception e) + { + errorMSG[i] = e; + Console.WriteLine("====================[请求异常,重试]===================="); + Console.WriteLine(uriBuilder.Uri); + Console.WriteLine(e.Message); + Console.WriteLine(e.StackTrace); + Console.WriteLine("=============================================="); + + } + Thread.Sleep(1000); + } + throw errorMSG.Last(s => s != null); + } + + } +} \ No newline at end of file diff --git a/VideoAnalysisCore/AICore/GPT/ChatGPT/ChatGPTModel.cs b/VideoAnalysisCore/AICore/GPT/ChatGPT/ChatGPTModel.cs new file mode 100644 index 0000000..28be7fc --- /dev/null +++ b/VideoAnalysisCore/AICore/GPT/ChatGPT/ChatGPTModel.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VideoAnalysisCore.AICore.GPT.ChatGPT +{ + /// + /// 请求数据 + /// + public class ChatRequest + { + /// + /// 对话 + /// + public Message[] messages { get; set; } + public string model { get; set; } = "gpt-4o"; + public float temperature { get; set; } = 0.3f; + public float max_tokens { get; set; } = 4000; + public object response_format = new { type = "json_object" }; // 指定结构化输出格式 +} + public class Message + { + public Message(string content, string role) + { + this.role = role; + this.content = content; + } + public string role { get; set; } + public string content { get; set; } + public string refusal { get; set; } + } + + + /// + /// gpt返回值 + /// + public class ChatRes + { + public string id { get; set; } + public string _object { get; set; } + public int created { get; set; } + public string model { get; set; } + public Choice[] choices { get; set; } + public Usage usage { get; set; } + /// + /// 系统指纹 + /// + public string system_fingerprint { get; set; } + } + + public class Usage + { + public int prompt_tokens { get; set; } + public int completion_tokens { get; set; } + public int total_tokens { get; set; } + } + + + public class Choice + { + public int index { get; set; } + public Message message { get; set; } + public object logprobs { get; set; } + public string finish_reason { get; set; } + } + +} diff --git a/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs b/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs new file mode 100644 index 0000000..8e49cd7 --- /dev/null +++ b/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs @@ -0,0 +1,211 @@ +using VideoAnalysisCore.Common; +using System.Text.Json; +using VideoAnalysisCore.Model; +using System.Text; +using System.ComponentModel.DataAnnotations; +using VideoAnalysisCore.Enum; +using System.Reflection; +using VideoAnalysisCore.Model.Dto; +using VideoAnalysisCore.AICore.GPT.Dto; +using VideoAnalysisCore.AICore.GPT; + +namespace VideoAnalysisCore.AICore.GPT.ChatGPT +{ + /// + /// kimi 文本模型 + /// + public class Chat_GPT : IBserGPT + { + private readonly ChatGPTClient chatClient; + private readonly Repository criteriaDB; + private readonly Repository videoTaskDB; + /// + /// 初始化 + /// + /// + /// + public Chat_GPT(ChatGPTClient moonshotClient, Repository criteria, Repository videoTaskDB) + { + ChatGPTClient.Host = AppCommon.Config.ChatGpt.KIMI.Host; + ChatGPTClient.ApiKey = AppCommon.Config.ChatGpt.KIMI.ApiKey; + + this.chatClient = moonshotClient; + criteriaDB = criteria; + this.videoTaskDB = videoTaskDB; + } + /// + /// 访问GPT + /// + /// 任务id + /// + public async Task CallGPT(string task) + { + var taskId = long.Parse(task); + var taskInfo = await videoTaskDB.AsQueryable() + .Where(s => s.Id == taskId) + .FirstAsync(); + var captions = ExpandFunction.GetSpeakerCaptions(task); + var criteriaArr = await criteriaDB.GetListAsync(s => s.Subject == taskInfo.Subject); + var criteriaBuilder = new StringBuilder(); + foreach (var item in criteriaArr) + { + criteriaBuilder.Append(item.Id); + criteriaBuilder.Append(":"); + criteriaBuilder.Append(item.NamePrompt); + criteriaBuilder.Append("? 请基于问题的回答苛刻的给出[优/良/中/差]作为得分"); + //criteriaBuilder.Append("0-"); + //criteriaBuilder.Append((int)(item.TotalScore * 10)); + //criteriaBuilder.Append("分"); + //criteriaBuilder.Append((int)(item.PassScore * 10)); + //criteriaBuilder.Append("分为及格"); + criteriaBuilder.Append(":"); + criteriaBuilder.Append("array=[得分,问题的回答,问题的详细改进意见,问题的详细扣分原因]|"); + + } + //拼接枚举提问 + foreach (var value in System.Enum.GetValues(typeof(QuestionTypeEnum))) + { + var enumValue = (QuestionTypeEnum)value; + var displayAttribute = enumValue.GetType() + .GetField(enumValue.ToString())? + .GetCustomAttribute(); + if (displayAttribute == null) continue; + criteriaBuilder.Append(enumValue.GetHashCode()); + criteriaBuilder.Append(":"); + criteriaBuilder.Append(displayAttribute.Prompt); + criteriaBuilder.Append("|"); + } + + var resFormat = """{"问题编号":number,"结果":array|bool|object,"问题解释":string}"""; + var postMessages = + $"你是一个教学经验老道老师对教学工作有着深入的理解和丰富的经验,能够准确把握教学大纲的要求和教学重点。" + + $"熟练掌握各种教学管理方法和手段,能够制定科学合理的教学计划和教学评估体系。" + + $"善于发现教学中的问题,并能迅速提出有效的解决方案,确保教学工作的顺利进行。" + + $"以下是一段音频的字幕,分析这段字幕 字幕格式(说话人:开始秒:结束秒:内容|下一段字幕)." + + $"字幕列表 {captions.Captions} " + + $"基于字幕内容回答提出的所有问题 问题格式(问题编号:问题描述:结束秒:结果类型|下一个问题)" + + $"问题列表 {criteriaBuilder} " + + $"返回固定的JSON数组格式({resFormat})"; + + var maxTokens = 4000; + var chatRep = new ChatRequest + { + max_tokens = maxTokens, + temperature = 0.3f, + messages = [ + new Message(postMessages,"system"), + new Message(resFormat,"assistant"), + ] + }; + + RedisExpand.SetTaskGPTReqCached(task, chatRep); + var chatResp = await chatClient.Chat(chatRep); + var chatResContent = chatResp?.res; + if (string.IsNullOrEmpty(chatResContent)) + throw new Exception("GPT返回message无效结果"); + if (chatResp != null) + RedisExpand.SetTaskGPTCached(task, new object[] { chatResp.Value.res, chatResp.Value.u }); + + chatResContent = chatResContent?.Replace("字幕内容", "课堂情况"); + chatResContent = chatResContent?.Replace("\n", ""); + chatResContent = chatResContent?.Replace("}{", "},{"); + chatResContent = chatResContent?.Replace("}|{", "},{"); + chatResContent = chatResContent?.Trim(); + if (!chatResContent.StartsWith("[")) + chatResContent = "[" + chatResContent; + if (!chatResContent.EndsWith("]")) + chatResContent = chatResContent + "]"; + var questionRes = JsonSerializer.Deserialize(chatResContent); + var gptRes = new TaskRes(captions); + if (questionRes is null) + throw new Exception("ChatGPT返回无效结果"); + var qEnum = (int)QuestionTypeEnum.高频词; + //处理 ai问答提问 + var arr1 = questionRes.Where(s => s.问题编号 < qEnum); + var arr2 = questionRes.Where(s => s.问题编号 >= qEnum) + .ToDictionary(s => s.问题编号); + //AI综合评估 + var criteriaDic = criteriaArr.ToDictionary(s => s.Id); + + var random = new Random(); + var ccArr = new List(arr1.Count()); + foreach (var s in arr1) //处理问题 + { + var Id = criteriaDic[s.问题编号].Id; + var PassScore = criteriaDic[s.问题编号].PassScore; + var TotalScore = criteriaDic[s.问题编号].TotalScore; + var Score = Math.Round(criteriaDic[s.问题编号].TotalScore * 0.01m + * ((int)(s.ToObject()?[0].ToEnum() ?? ScoreTypeEnum.中) + + random.Next(-6, 25)), + 1, MidpointRounding.AwayFromZero); + var Prompt = s.ToObject()?[1].ToString() ?? string.Empty; + var ImprovedMethods = s.ToObject()?[2].ToString() ?? string.Empty; + var Analyze = s.问题解释 ?? string.Empty; + var kf = s.ToObject()?[3].ToString() ?? string.Empty; + kf = kf.Replace("无", ""); + if (string.IsNullOrEmpty(kf)) + Score = criteriaDic[s.问题编号].TotalScore; + else + Analyze += " 扣分原因:" + kf; + ccArr.Add(new CourseCriteria() + { + Analyze = Analyze, + Id = Id, + PassScore = PassScore, + ImprovedMethods = ImprovedMethods, + Prompt = Prompt, + Score = Score, + TotalScore = TotalScore, + }); + } + gptRes.Assessment = new AssessmentDto() + { + Bad = ccArr.Where(s => s.Score < s.PassScore).ToArray(), + Merit = ccArr.Where(s => s.Score >= s.PassScore).ToArray(), + }; + //高频词汇 + gptRes.Hotwords = + arr2[(int)QuestionTypeEnum.高频词].ToObject() ?? ["暂无数据"]; + //时间段概览 + gptRes.TimeOverview = arr2[(int)QuestionTypeEnum.时间段概览] + .ToObject(); + //提问类型 + gptRes.QuestionType = arr2[(int)QuestionTypeEnum.提问类型] + .ToObject>(); + + //分析上课时间段情况 分析 独立学习 小组合作 随堂练习等情况 + var extraTimeBase = arr2[(int)QuestionTypeEnum.额外课堂情况] + .ToObject(); + if (extraTimeBase is not null) + foreach (var item in extraTimeBase) + { + if (item is null) + continue; + var r = item.Content.ToEnum(); + if (r is null) + continue; + var arr = gptRes.TimeBase? + .Where(s => s.Start >= item.Start && s.End <= item.End); + if (arr is null) + continue; + foreach (var s in arr) + s.TimeBaseType = r; + } + var totalTokens = chatResp?.u.total_tokens ?? 0; + if (totalTokens > 1) + { + var tid = long.Parse(task); + await videoTaskDB.AsUpdateable() + .SetColumns(it => it.TotalTokens == totalTokens)//SetColumns是可以叠加的 写2个就2个字段赋值 + .Where(it => it.Id == tid) + .ExecuteCommandAsync(); + } + + await RedisExpand.Redis + .HMSetAsync(RedisExpandKey.Task(task), "ChatAnalysis", gptRes); + RedisExpand.InsertChannel(RedisChannelEnum.EndTask, task); + + return gptRes; + } + } +} diff --git a/VideoAnalysisCore/AICore/ChatGPT/Dto/CallGPTRes.cs b/VideoAnalysisCore/AICore/GPT/Dto/CallGPTRes.cs similarity index 79% rename from VideoAnalysisCore/AICore/ChatGPT/Dto/CallGPTRes.cs rename to VideoAnalysisCore/AICore/GPT/Dto/CallGPTRes.cs index 9b610dc..ec29722 100644 --- a/VideoAnalysisCore/AICore/ChatGPT/Dto/CallGPTRes.cs +++ b/VideoAnalysisCore/AICore/GPT/Dto/CallGPTRes.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using VideoAnalysisCore.Enum; using VideoAnalysisCore.Model.Dto; -namespace VideoAnalysisCore.AICore.ChatGPT.Dto +namespace VideoAnalysisCore.AICore.GPT.Dto { /// /// 任务结果 @@ -19,9 +19,9 @@ namespace VideoAnalysisCore.AICore.ChatGPT.Dto } public TaskRes(TotalCaptionsDto captions) { - this.TeacherSpeaking = captions.TeacherSpeaking; - this.TimeBase = captions.TimeBase?.ToList(); - this.StudentSpeaking = captions.StudentSpeaking; + TeacherSpeaking = captions.TeacherSpeaking; + TimeBase = captions.TimeBase?.ToList(); + StudentSpeaking = captions.StudentSpeaking; } /// /// 教师发言时间 @@ -36,7 +36,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.Dto /// /// 高频词汇 从高到低 /// - public string[] Hotwords { get; set; } + public string[] Hotwords { get; set; } /// /// 教师提问类型 /// @@ -66,8 +66,8 @@ namespace VideoAnalysisCore.AICore.ChatGPT.Dto (float)( (Assessment?.Bad?.Sum(x => x.Score) ?? 0) + (Assessment?.Merit?.Sum(x => x.Score) ?? 0)); - //(float)Math.Round((Assessment?.Bad?.Select(x => x.Score) - //.Concat(Assessment?.Merit?.Select(s => s.Score) ?? []) - //.Average() ?? 0) * 10,2); + //(float)Math.Round((Assessment?.Bad?.Select(x => x.Score) + //.Concat(Assessment?.Merit?.Select(s => s.Score) ?? []) + //.Average() ?? 0) * 10,2); } } diff --git a/VideoAnalysisCore/AICore/ChatGPT/Dto/QuestionRes.cs b/VideoAnalysisCore/AICore/GPT/Dto/QuestionRes.cs similarity index 94% rename from VideoAnalysisCore/AICore/ChatGPT/Dto/QuestionRes.cs rename to VideoAnalysisCore/AICore/GPT/Dto/QuestionRes.cs index a079e1d..30d7007 100644 --- a/VideoAnalysisCore/AICore/ChatGPT/Dto/QuestionRes.cs +++ b/VideoAnalysisCore/AICore/GPT/Dto/QuestionRes.cs @@ -8,7 +8,7 @@ using System.Text.Json; using System.Text.Json.Nodes; using System.Threading.Tasks; -namespace VideoAnalysisCore.AICore.ChatGPT.Dto +namespace VideoAnalysisCore.AICore.GPT.Dto { public class QuestionRes { @@ -31,7 +31,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.Dto { try { - if(_cached != null) + if (_cached != null) return (T)_cached; var r = 结果.RootElement.GetRawText(); if (r is null) @@ -106,7 +106,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.Dto /// 改进意见 /// public string[]? BadImprovedMethods => - (Merit?.Select(s => s.ImprovedMethods??string.Empty)?.ToArray()??[]) + (Merit?.Select(s => s.ImprovedMethods ?? string.Empty)?.ToArray() ?? []) .Concat(Bad?.Select(s => s.ImprovedMethods ?? string.Empty)?.ToArray() ?? []).ToArray(); } diff --git a/VideoAnalysisCore/AICore/ChatGPT/KIMI/KIMI_GPT.cs b/VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs similarity index 96% rename from VideoAnalysisCore/AICore/ChatGPT/KIMI/KIMI_GPT.cs rename to VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs index f63b8cd..aecfad7 100644 --- a/VideoAnalysisCore/AICore/ChatGPT/KIMI/KIMI_GPT.cs +++ b/VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs @@ -2,13 +2,11 @@ using VideoAnalysisCore.Common; using System.Threading.Tasks; using Whisper.net; -using VideoAnalysisCore.AICore.ChatGPT; using System.Text.Json; using VideoAnalysisCore.Model; using System.Text; using FFmpeg.NET.Services; using Microsoft.Extensions.Primitives; -using VideoAnalysisCore.AICore.ChatGPT.Dto; using System.ComponentModel.DataAnnotations; using VideoAnalysisCore.Enum; using System.Reflection; @@ -16,15 +14,18 @@ using FreeRedis; using VideoAnalysisCore.Model.Dto; using AntDesign; using SqlSugar.IOC; +using VideoAnalysisCore.AICore.GPT.Dto; +using VideoAnalysisCore.AICore.GPT; +using VideoAnalysisCore.AICore.GPT.ChatGPT; -namespace VideoAnalysisCore.AICore.ChatGPT.KIMI +namespace VideoAnalysisCore.AICore.GPT.KIMI { /// /// kimi 文本模型 /// public class KIMI_GPT : IBserGPT { - private readonly MoonshotClient moonshotClient; + private readonly ChatGPTClient moonshotClient; private readonly Repository criteriaDB; private readonly Repository videoTaskDB; /// @@ -32,13 +33,13 @@ namespace VideoAnalysisCore.AICore.ChatGPT.KIMI /// /// /// - public KIMI_GPT(MoonshotClient moonshotClient, Repository criteria, Repository videoTaskDB) + public KIMI_GPT(ChatGPTClient moonshotClient, Repository criteria, Repository videoTaskDB) { - MoonshotClient.Host = AppCommon.Config.ChatGpt.KIMI.Host; - MoonshotClient.ApiKey = AppCommon.Config.ChatGpt.KIMI.ApiKey; + ChatGPTClient.Host = AppCommon.Config.ChatGpt.KIMI.Host; + ChatGPTClient.ApiKey = AppCommon.Config.ChatGpt.KIMI.ApiKey; this.moonshotClient = moonshotClient; - this.criteriaDB = criteria; + criteriaDB = criteria; this.videoTaskDB = videoTaskDB; } /// @@ -159,7 +160,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.KIMI var Analyze = s.问题解释 ?? string.Empty; var kf = s.ToObject()?[3].ToString() ?? string.Empty; kf = kf.Replace("无", ""); - if (string.IsNullOrEmpty(kf)) + if (string.IsNullOrEmpty(kf)) Score = criteriaDic[s.问题编号].TotalScore; else Analyze += " 扣分原因:" + kf; @@ -172,7 +173,6 @@ namespace VideoAnalysisCore.AICore.ChatGPT.KIMI Prompt = Prompt, Score = Score, TotalScore = TotalScore, - }); } gptRes.Assessment = new AssessmentDto() @@ -220,7 +220,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.KIMI await RedisExpand.Redis .HMSetAsync(RedisExpandKey.Task(task), "ChatAnalysis", gptRes); - RedisExpand.InsertChannel(Enum.RedisChannelEnum.EndTask, task); + RedisExpand.InsertChannel(RedisChannelEnum.EndTask, task); return gptRes; } diff --git a/VideoAnalysisCore/AICore/ChatGPT/KIMI/MoonshotClient.cs b/VideoAnalysisCore/AICore/GPT/KIMI/MoonshotClient.cs similarity index 97% rename from VideoAnalysisCore/AICore/ChatGPT/KIMI/MoonshotClient.cs rename to VideoAnalysisCore/AICore/GPT/KIMI/MoonshotClient.cs index 3baabe7..9f2bef8 100644 --- a/VideoAnalysisCore/AICore/ChatGPT/KIMI/MoonshotClient.cs +++ b/VideoAnalysisCore/AICore/GPT/KIMI/MoonshotClient.cs @@ -16,7 +16,7 @@ using static System.Runtime.InteropServices.JavaScript.JSType; /// /// https://platform.moonshot.cn/docs/api-reference /// -namespace VideoAnalysisCore.AICore.ChatGPT.KIMI +namespace VideoAnalysisCore.AICore.GPT.KIMI { public class MoonshotClient @@ -54,7 +54,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.KIMI } /// - /// ChatSSE + /// ChatSSE[流式传输 更稳定] /// /// /// Return HttpResponseMessage for SSE @@ -92,7 +92,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.KIMI } catch (Exception e) { - Console.WriteLine("异常 ChatSSE=>" ); + Console.WriteLine("异常 ChatSSE=>"); Console.WriteLine(line); Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); @@ -120,7 +120,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.KIMI if (string.IsNullOrEmpty(chatResContent)) return null; - + return (res.usage, chatResContent); } @@ -255,7 +255,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.KIMI try { var client = _httpClientFactory.CreateClient(); - client.Timeout = TimeSpan.FromSeconds(60 * 20);//超时时间20分钟 + client.Timeout = TimeSpan.FromSeconds(Timeout.Infinite);//超时时间20分钟 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ApiKey); client.DefaultRequestVersion = HttpVersion.Version20; client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower; @@ -291,7 +291,7 @@ namespace VideoAnalysisCore.AICore.ChatGPT.KIMI var uriBuilder = new UriBuilder(Host + path); request.RequestUri = uriBuilder.Uri; request.Method = new HttpMethod("POST"); - request.Headers.Host = (new Uri(Host)).Host; + request.Headers.Host = new Uri(Host).Host; return request; } diff --git a/VideoAnalysisCore/AICore/ChatGPT/KIMI/MoonshotModel.cs b/VideoAnalysisCore/AICore/GPT/KIMI/MoonshotModel.cs similarity index 99% rename from VideoAnalysisCore/AICore/ChatGPT/KIMI/MoonshotModel.cs rename to VideoAnalysisCore/AICore/GPT/KIMI/MoonshotModel.cs index 5697d68..cbb3dc5 100644 --- a/VideoAnalysisCore/AICore/ChatGPT/KIMI/MoonshotModel.cs +++ b/VideoAnalysisCore/AICore/GPT/KIMI/MoonshotModel.cs @@ -1,4 +1,4 @@ -namespace VideoAnalysisCore.AICore.ChatGPT.KIMI +namespace VideoAnalysisCore.AICore.GPT.KIMI { public class MessagesItem @@ -7,7 +7,7 @@ { } - public MessagesItem(string content, string role = "user",bool partial = false) + public MessagesItem(string content, string role = "user", bool partial = false) { this.content = content; this.role = role; diff --git a/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs b/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs index 8f45e85..f296b83 100644 --- a/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs +++ b/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs @@ -6,7 +6,6 @@ using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; -using VideoAnalysisCore.AICore.Whisper; using VideoAnalysisCore.Common; namespace VideoAnalysisCore.AICore.SherpaOnnx diff --git a/VideoAnalysisCore/AICore/SherpaOnnx/SherpaOnnxDto.cs b/VideoAnalysisCore/AICore/SherpaOnnx/SherpaOnnxDto.cs index 0b4ab60..7bb63dd 100644 --- a/VideoAnalysisCore/AICore/SherpaOnnx/SherpaOnnxDto.cs +++ b/VideoAnalysisCore/AICore/SherpaOnnx/SherpaOnnxDto.cs @@ -1,6 +1,6 @@ using Whisper.net; -namespace VideoAnalysisCore.AICore.Whisper +namespace VideoAnalysisCore.AICore.SherpaOnnx { /// /// 字幕识别 结果 @@ -9,7 +9,7 @@ namespace VideoAnalysisCore.AICore.Whisper { public SenseVoiceRes() { - + } /// /// 文本 diff --git a/VideoAnalysisCore/Common/AppCommon.cs b/VideoAnalysisCore/Common/AppCommon.cs index 38bf388..1c5330b 100644 --- a/VideoAnalysisCore/Common/AppCommon.cs +++ b/VideoAnalysisCore/Common/AppCommon.cs @@ -9,7 +9,6 @@ using System.Runtime.Loader; using System.Text; using System.Threading.Tasks; using VideoAnalysisCore.AICore.SherpaOnnx; -using VideoAnalysisCore.AICore.Whisper; using VideoAnalysisCore.Enum; using VideoAnalysisCore.Model.Dto; using Whisper.net; @@ -233,10 +232,10 @@ namespace VideoAnalysisCore.Common /// /// ffmpeg配置 /// - public class KIMIConfig + public class GptConfig { /// - /// kimi请求 公开的服务地址 + /// 请求 公开的服务地址 /// public string Host { get; set; } = string.Empty; /// @@ -253,7 +252,8 @@ namespace VideoAnalysisCore.Common /// KIMI /// /// - public KIMIConfig KIMI { get; set; } = new KIMIConfig(); + public GptConfig ChatGpt { get; set; } = new GptConfig(); + public GptConfig KIMI { get; set; } = new GptConfig(); } /// diff --git a/VideoAnalysisCore/Common/RedisExpand.cs b/VideoAnalysisCore/Common/RedisExpand.cs index 58df67f..4dcc4d9 100644 --- a/VideoAnalysisCore/Common/RedisExpand.cs +++ b/VideoAnalysisCore/Common/RedisExpand.cs @@ -7,9 +7,10 @@ using System; using System.Threading.Channels; using System.Threading.Tasks; using System.Xml.Linq; -using VideoAnalysisCore.AICore.ChatGPT; -using VideoAnalysisCore.AICore.ChatGPT.Dto; using VideoAnalysisCore.AICore.FFMPGE; +using VideoAnalysisCore.AICore.GPT; +using VideoAnalysisCore.AICore.GPT.Dto; + //using VideoAnalysisCore.AICore.FFMPGE; using VideoAnalysisCore.AICore.SherpaOnnx; diff --git a/VideoAnalysisCore/Model/Dto/SpeakerCaptionsDto.cs b/VideoAnalysisCore/Model/Dto/SpeakerCaptionsDto.cs index b1c15d7..c2c1f7f 100644 --- a/VideoAnalysisCore/Model/Dto/SpeakerCaptionsDto.cs +++ b/VideoAnalysisCore/Model/Dto/SpeakerCaptionsDto.cs @@ -1,4 +1,5 @@ using AntDesign; +using VideoAnalysisCore.AICore.GPT.Dto; using VideoAnalysisCore.Enum; namespace VideoAnalysisCore.Model.Dto @@ -43,7 +44,7 @@ namespace VideoAnalysisCore.Model.Dto public string? Content { get; set; } /// /// 时间段 类型 - /// 时为 null + /// 时为 null /// public TimeBaseTypeEnum? TimeBaseType { get; set; } diff --git a/VideoAnalysisCore/Model/VideoTask.cs b/VideoAnalysisCore/Model/VideoTask.cs index 9571d62..ae9f489 100644 --- a/VideoAnalysisCore/Model/VideoTask.cs +++ b/VideoAnalysisCore/Model/VideoTask.cs @@ -3,9 +3,8 @@ using System.ComponentModel.DataAnnotations; using System.Net; using System.Text.Json; using UserCenter.Model.Enum; -using VideoAnalysisCore.AICore.ChatGPT.Dto; +using VideoAnalysisCore.AICore.GPT.Dto; using VideoAnalysisCore.AICore.SherpaOnnx; -using VideoAnalysisCore.AICore.Whisper; using VideoAnalysisCore.Enum; using Whisper.net;