From 8fd3d4ef4bad3f343641f188bc5bad981a521ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com> Date: Thu, 22 May 2025 17:16:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20AI=E5=AD=97=E5=B9=95?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8F=90=E7=A4=BA=E8=AF=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AICore/GPT/ChatGPT/Chat_GPT.cs | 10 +++--- .../AICore/GPT/DeepSeek/DeepSeek_GPT.cs | 36 ++++++++++--------- VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs | 5 +-- VideoAnalysisCore/Common/RedisExpand.cs | 8 ++--- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs b/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs index 5bae611..aab917f 100644 --- a/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs +++ b/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs @@ -204,13 +204,14 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT messages = messageArr }; - RedisExpand.SetTaskGPTReqCached(task, chatRep); + var time = DateTime.Now.ToString("MMddHHmmss"); + RedisExpand.SetTaskGPTCached(task, time,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 }); + RedisExpand.SetTaskGPTCached(task, time, new object[] { chatResp.Value.res, chatResp.Value.u }); chatResContent = chatResContent?.Replace("字幕内容", "课堂情况"); chatResContent = chatResContent?.Replace("\n", ""); @@ -307,13 +308,14 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT ] }; - RedisExpand.SetTaskGPTReqCached(task, chatRep); + var time = DateTime.Now.ToString("MMddHHmmss"); + RedisExpand.SetTaskGPTCached(task, time, 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 }); + RedisExpand.SetTaskGPTCached(task, time, new object[] { chatResp.Value.res, chatResp.Value.u }); chatResContent = chatResContent?.Replace("字幕内容", "课堂情况"); chatResContent = chatResContent?.Replace("\n", ""); diff --git a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs index 3910804..e744bf8 100644 --- a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs +++ b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs @@ -81,7 +81,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek $" 格式 (方法点Id|方法点名称) " + $"提供的知识点名称({knows})。"; Console.WriteLine(DateTime.Now + "=>2.开始分析视频内容知识点"); - var konwRes = await ChatAsync(taskInfo.Id.ToString(), knowMessages, null); + var konwRes = await ChatAsync(taskInfo.Id.ToString(), knowMessages, "知识点"); for (int i = 0; i < konwRes.Count(); i++) questionRes[i].KnowPoint = konwRes[i].KnowPoint; @@ -144,7 +144,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek $"输出格式 json字符串 对象格式{fileNameResFormat}"; var task = taskInfo.Id.ToString(); var fileNameInfoRes = await ChatAsync - (task, fileNamePostMessages, null); + (task, fileNamePostMessages, "授课章节"); taskInfo.Sections = fileNameInfoRes.授课章节; await videoTaskDB.AsUpdateable() .SetColumns(it => it.Sections == fileNameInfoRes.授课章节) @@ -174,7 +174,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek $"字幕格式(说话人:开始秒:结束秒:内容|下一段字幕).以下是包含时间的视频字幕文本。字幕列表 {captions.Captions}。" + $"最后输出格式为json({checkResFormat})"; Console.WriteLine(DateTime.Now + "=>3.开始检查视频分段结果"); - return await ChatAsync(taskInfo.Id.ToString(), checkMessage, null); + return await ChatAsync(taskInfo.Id.ToString(), checkMessage, "结果检查"); } /// @@ -202,20 +202,20 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek .Take(spanCount); if (cArr.Count() == 0) return; - var nowCaptionStr = string.Join('|', cArr.Select(s => /*s.Start + ":" +*/ s.Text)); + var nowCaptionStr =JsonSerializer.Serialize(cArr.Select(s =>s.Text)); var resFormat = """[string(修改结果)]"""; var postMessages = $"这是一堂中国课的字幕由结果是语音识别提供。" + $"字幕内容与{subject}学科{sections}章节相关。" + $"需要你帮我修复其中的错别字,修复公式。" + $"请注意 只允许对字幕进行修改不允许删除字幕的字或者添加字。" + - $"请确保输出字幕条数与输入字幕条数一致!!!" + $"输出内容只返回json格式({resFormat})" + - $"字幕内容(使用|符号分割)" + + $"字幕内容(JSON字符串)" + $"`{nowCaptionStr}`" + - $"字幕结束。 "; + $"字幕结束。" + + $"最后请确保输出字幕条数与输入字幕条数一致!!! 如果不一致则重新优化并且确保字幕条数一致!!!!"; Console.WriteLine(DateTime.Now + $"=>字幕优化 分段{s}/{totalCount}开始..."); - var resData = await ChatAsync(taskInfo.Id.ToString(), postMessages, null, "deepseek-chat"); + var resData = await ChatAsync(taskInfo.Id.ToString(), postMessages, "优化字幕", "deepseek-chat"); if (resData.Count() != cArr.Count()) { Console.WriteLine(DateTime.Now + $"=>字幕优化 分段{s}/{totalCount} AI结果数量不匹配,重试"); @@ -280,7 +280,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek $"字幕列表 {nowCaptionStr} 字幕结束!"; Console.WriteLine(DateTime.Now + $"=>{taskInfo.Id.ToString()}.开始分析视频内容 {lastTime}~{endTime}"); - questionRes.AddRange(await ChatAsync(taskInfo.Id.ToString(), postMessages, null)); + questionRes.AddRange(await ChatAsync(taskInfo.Id.ToString(), postMessages, "分析字幕")); lastTime = (int)questionRes.Last().EndTime.Value - (lastTime == 0 ? 0 : 30); } catch (Exception ex) @@ -371,11 +371,10 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek return null; } - public async Task ChatAsync(string task, string postMessages, string postMessages1, string model = "deepseek-reasoner") + public async Task ChatAsync(string task, string postMessages, string title, string model = "deepseek-reasoner") { Message[] messageArr = [ new Message(postMessages,"user"), - string.IsNullOrEmpty(postMessages1)?null:new Message(postMessages1,"user"), ]; messageArr = messageArr.Where(s => s != null).ToArray(); var chatRep = new ChatRequest @@ -391,14 +390,17 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek { try { - RedisExpand.SetTaskGPTReqCached(task, chatRep); + var time = title+DateTime.Now.ToString("MMddHHmmss"); + var redisCached = new object[2] { chatRep, null }; + RedisExpand.SetTaskGPTCached(task, time,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, chatResp.Value.reasoning }); - + if (chatResp != null) { + redisCached[1] = new object[] { chatResp.Value.res, chatResp.Value.u, chatResp.Value.reasoning }; + RedisExpand.SetTaskGPTCached(task, time, redisCached); + } chatResContent = chatResContent?.Replace("字幕内容", "课堂情况"); chatResContent = chatResContent?.Replace("\n", ""); chatResContent = chatResContent?.Replace("```json", ""); @@ -437,7 +439,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek /// - /// 优化字幕 + /// 提取试题 /// /// private async Task AnalysisVideoQuestions(VideoTask taskInfo) @@ -474,7 +476,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek $"输出内容只返回json格式为({resFormat})" + $"以下是试题内容" + $"`{sRes.Result.res.info.markdown}`"; - var resData = await ChatAsync(taskInfo.Id.ToString(), postMessages, null, "deepseek-chat"); + var resData = await ChatAsync(taskInfo.Id.ToString(), postMessages, "提取试题", "deepseek-chat"); foreach (var q in resData) { q.VideoTaskId = taskInfo.Id; diff --git a/VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs b/VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs index 6b9ad23..ce6b74e 100644 --- a/VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs +++ b/VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs @@ -114,14 +114,15 @@ namespace VideoAnalysisCore.AICore.GPT.KIMI } }; - RedisExpand.SetTaskGPTReqCached(task, chatRep); + var time = DateTime.Now.ToString("MMddHHmmss"); + RedisExpand.SetTaskGPTCached(task, time,chatRep); var chatResp = await moonshotClient.ChatSSE(chatRep); //chatResp = await moonshotClient.Chat(chatRep); var chatResContent = chatResp?.res; if (string.IsNullOrEmpty(chatResContent)) throw new Exception("KIMIGPT返回message无效结果"); if (chatResp != null) - RedisExpand.SetTaskGPTCached(task, new object[] { chatResp.Value.res, chatResp.Value.u }); + RedisExpand.SetTaskGPTCached(task, time, new object[] { chatResp.Value.res, chatResp.Value.u }); //chatResContent = """[{ "问题编号": 10, "结果": [ "良", "教学目标在授课中有提及,如提到了圆锥曲线的学习以及数列的概念和简单表示,但未明确指出具体的教学目标,如学生应掌握的具体知识点或技能。", "教师可以在课程开始时明确列出本节课的教学目标,让学生清楚知道本节课的学习重点。", "教学目标不够明确,缺乏具体的教学目标描述。" ], "问题解释": "授课中提到了学习圆锥曲线和数列的概念及简单表示,但未明确具体的教学目标。"},{ "问题编号": 11, "结果": [ "优", "授课语言简明、准确,且在解释概念时使用了生动的例子,如通过王芳同学的身高数据来解释数列的概念。", "无需改进,授课语言已经非常清晰和生动。", "无" ], "问题解释": "授课中使用了简明、准确、生动的语言,并通过实例来解释概念。"},{ "问题编号": 12, "结果": [ "优", "教师在授课过程中表现出对学生的重视,语言友善温和,如在解释概念时多次询问学生是否理解。", "无需改进,教师已经很好地表现出对学生的重视和友善。", "无" ], "问题解释": "教师在授课中重视学生需求,表现出友善和温和的态度。"},{ "问题编号": 13, "结果": [ "良", "授课中教师给学生留有一定的思考时间,但部分时间较短,可能不足以让学生充分思考。", "教师可以在解释概念或提出问题后,适当延长学生的思考时间,确保学生能够充分理解和消化。", "部分思考留白时间较短,不足以让学生充分思考。" ], "问题解释": "授课中给学生留有思考时间,但部分时间较短。"},{ "问题编号": 14, "结果": [ "优", "教学重难点突出,如对数列的概念、表示方法等进行了详细讲解,并使用了实例来帮助学生理解。", "无需改进,教学重难点已经很好地突出。", "无" ], "问题解释": "教学中对重难点进行了突出讲解,并使用实例帮助学生理解。"},{ "问题编号": 15, "结果": [ "中", "学生在授课中的参与度一般,教师虽有询问学生是否理解,但缺乏更积极的互动方式。", "教师可以通过提问、让学生回答问题等方式,增加学生的参与度和互动。", "学生参与度一般,缺乏更积极的互动。" ], "问题解释": "授课中教师虽有询问学生是否理解,但学生参与互动的程度一般。"},{ "问题编号": 16, "结果": [ "优", "知识点讲解逻辑清晰明了,如对数列的概念、分类、表示方法等进行了条理清晰的讲解。", "无需改进,知识点讲解逻辑已经非常清晰。", "无" ], "问题解释": "授课中知识点讲解逻辑清晰明了,条理性强。"},{ "问题编号": 17, "结果": [ "良", "例题讲解过程中,教师进行了一定的留白,但留白的时间和深度可以进一步加强。", "教师可以在例题讲解中设置更多的问题,引导学生思考,增加留白的时间和深度。", "例题讲解中的留白时间和深度有待加强。" ], "问题解释": "授课中例题讲解进行了留白,但可以进一步加强。"},{ "问题编号": 18, "结果": [ "良", "练习时给到学生的时间一般,部分练习时间较短,可能不足以让学生充分练习。", "教师可以在练习环节给学生更多的时间,确保学生能够充分练习和理解。", "练习时间部分较短,不足以让学生充分练习。" ], "问题解释": "授课中练习环节给到学生的时间一般。"},{ "问题编号": 19, "结果": [ "优", "课程内容不冗杂,讲解清楚,如对数列的概念、分类、表示方法等进行了清晰的讲解。", "无需改进,课程内容和讲解已经非常清晰。", "无" ], "问题解释": "授课中课程内容不冗杂,讲解清楚。"},{ "问题编号": 20, "结果": [ "优", "授课中进行了举例阐述知识点,如通过王芳同学的身高数据来解释数列的概念,便于学生理解。", "无需改进,授课中已经很好地使用了举例来阐述知识点。", "无" ], "问题解释": "授课中使用了举例来阐述知识点,便于学生理解。"},{ "问题编号": 5001, "结果": [ "数列", "圆锥曲线", "学习", "例子", "身高", "数据", "表示", "函数", "同向公式" ], "问题解释": "分析了授课中的高频词,提取了出现频率最高的10个词汇。"},{ "问题编号": 5002, "结果": [ { "Start": 0, "End": 120, "Content": "课程开始,教师介绍了圆锥曲线的学习情况,并提到了数列的学习。" }, { "Start": 120, "End": 240, "Content": "教师详细讲解了数列的概念,并通过王芳同学的身高数据作为例子。" }, { "Start": 240, "End": 360, "Content": "教师解释了数列的分类,包括递增数列、递减数列和常数列,并给出了相应的定义。" }, { "Start": 360, "End": 480, "Content": "教师讨论了数列的表示方法,包括列表法、图像法和通项公式,并提供了相应的例子。" } ], "问题解释": "基于课堂情况提取了课堂上的事件,并分析了每个事件的时间片段和内容概览。"},{ "问题编号": 5003, "结果": { "重复回答": 3, "老师追问": 5, "简单性表扬": 2, "老师补充答案": 4, "表扬并补充答案": 1 }, "问题解释": "统计了授课中教师回答类型的次数,包括重复回答、老师追问、简单性表扬、老师补充答案和表扬并补充答案。"},{ "问题编号": 5004, "结果": [ { "Start": 150, "End": 180, "Content": "独立学习" }, { "Start": 300, "End": 330, "Content": "小组合作" }, { "Start": 450, "End": 480, "Content": "随堂练习" } ], "问题解释": "分析了授课中教师提到独立学习、小组合作和随堂练习的时间段,并提取了相应的字幕开始秒和结束秒。"}]"""; chatResContent = chatResContent?.Replace("字幕内容", "课堂情况"); diff --git a/VideoAnalysisCore/Common/RedisExpand.cs b/VideoAnalysisCore/Common/RedisExpand.cs index 5443354..711352e 100644 --- a/VideoAnalysisCore/Common/RedisExpand.cs +++ b/VideoAnalysisCore/Common/RedisExpand.cs @@ -106,13 +106,9 @@ namespace VideoAnalysisCore.Common /// 缓存GPT任务缓存 /// /// - public static void SetTaskGPTCached(object taskId, object? data) + public static void SetTaskGPTCached(object taskId,string time, object? data) { - Redis.Set(RedisExpandKey.TaskGPT(taskId) + ":" + DateTime.Now.ToString("MMddHHmmss") + "01", data, 3600 * 24); - } - public static void SetTaskGPTReqCached(object taskId, object? data) - { - Redis.Set(RedisExpandKey.TaskGPT(taskId) + ":" + DateTime.Now.ToString("MMddHHmmss")+ "00", data, 3600 * 24); + Redis.Set(RedisExpandKey.TaskGPT(taskId) + ":" + time, data, 3600 * 24); } /// /// 加入到消费队列