调整 部分文件代码命名
This commit is contained in:
parent
929d6f8a98
commit
deb7f80bce
|
|
@ -15,7 +15,7 @@ using System.Text.Json.Serialization;
|
|||
namespace VideoAnalysisCore.AICore.GPT
|
||||
{
|
||||
|
||||
public interface IBserGPT
|
||||
public interface IBserGPTWorkflow
|
||||
{
|
||||
/// <summary>
|
||||
/// 访问GPT
|
||||
|
|
@ -190,8 +190,8 @@ namespace VideoAnalysisCore.AICore.GPT
|
|||
public static void AddGPTService(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<DeepSeekGPTClient>();
|
||||
services.AddSingleton<ChatGPTClient>();
|
||||
services.AddSingleton<IBserGPT, DeepSeek_GPT>();
|
||||
services.AddSingleton<BestAIClient>();
|
||||
services.AddSingleton<IBserGPTWorkflow, GTP_Analysis_1>();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,10 @@ using System.Text.Json;
|
|||
namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
||||
{
|
||||
|
||||
public class ChatGPTClient : GPTClient
|
||||
/// <summary>
|
||||
/// 接入oaibest
|
||||
/// </summary>
|
||||
public class BestAIClient : GPTClient
|
||||
{
|
||||
|
||||
public override GptConfig Config { get; set; } = AppCommon.Config.ChatGpt.ChatGpt;
|
||||
|
|
@ -23,7 +26,7 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
|||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly RedisManager redisManager;
|
||||
|
||||
public ChatGPTClient(IHttpClientFactory httpClientFactory, RedisManager redisManager) : base(httpClientFactory, redisManager)
|
||||
public BestAIClient(IHttpClientFactory httpClientFactory, RedisManager redisManager) : base(httpClientFactory, redisManager)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
this.redisManager = redisManager;
|
||||
|
|
|
|||
|
|
@ -16,5 +16,9 @@ namespace VideoAnalysisCore.AICore.GPT
|
|||
public static string Deepseek_Chat = "deepseek-chat";
|
||||
|
||||
|
||||
public static string Gemini_3_Chat_thinking = "gemini-3-pro-preview-thinking";
|
||||
public static string Gemini_3_Chat = "gemini-3-pro-preview";
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ namespace VideoAnalysisCore.AICore.GPT
|
|||
var chatResp = await Chat(chatRep);
|
||||
var chatResContent = chatResp?.res;
|
||||
if (string.IsNullOrEmpty(chatResContent))
|
||||
throw new Exception("GPT返回message无效结果");
|
||||
throw new Exception($"GPT返回message无效结果 => res:{chatResp?.res} reasoning:{chatResp?.reasoning}");
|
||||
if (chatResp != null)
|
||||
{
|
||||
redisCached[1] = new object[] { chatResp.Value.res, chatResp.Value.u, chatResp.Value.reasoning };
|
||||
|
|
|
|||
|
|
@ -26,12 +26,13 @@ using System.Text.RegularExpressions;
|
|||
namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||
{
|
||||
/// <summary>
|
||||
/// chatgpt 文本模型
|
||||
/// 视频分析工作流1
|
||||
/// </summary>
|
||||
public class DeepSeek_GPT : IBserGPT
|
||||
public class GTP_Analysis_1 : IBserGPTWorkflow
|
||||
{
|
||||
private readonly GeminiGPTClient geminiClient;
|
||||
private readonly DeepSeekGPTClient chatClient;
|
||||
private readonly ChatGPTClient chatGPTClient;
|
||||
private readonly BestAIClient chatGPTClient;
|
||||
private readonly Repository<CourseGradingCriteria> criteriaDB;
|
||||
private readonly RedisManager redisManager;
|
||||
private readonly Repository<VideoTask> videoTaskDB;
|
||||
|
|
@ -46,9 +47,9 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
/// </summary>
|
||||
/// <param name="moonshotClient"></param>
|
||||
/// <param name="logger"></param>
|
||||
public DeepSeek_GPT(DeepSeekGPTClient moonshotClient, Repository<CourseGradingCriteria> criteria, Repository<VideoTask> videoTaskDB,
|
||||
public GTP_Analysis_1(DeepSeekGPTClient moonshotClient, Repository<CourseGradingCriteria> criteria, Repository<VideoTask> videoTaskDB,
|
||||
Repository<KnowledgeInfo> knowledgeInfoDB, Repository<VideoKonwPoint> videoKonwPointDB, SimpLetexClient simpLetexClient,
|
||||
Repository<VideoQuestion> videoQuestionDB, OssClient ossClient, Repository<VideoQuestionKonw> videoQuestionKonwDB, RedisManager redisManager, ChatGPTClient chatGPTClient)
|
||||
Repository<VideoQuestion> videoQuestionDB, OssClient ossClient, Repository<VideoQuestionKonw> videoQuestionKonwDB, RedisManager redisManager, BestAIClient chatGPTClient, GeminiGPTClient geminiClient)
|
||||
{
|
||||
chatClient = moonshotClient;
|
||||
criteriaDB = criteria;
|
||||
|
|
@ -61,6 +62,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
this.videoQuestionKonwDB = videoQuestionKonwDB;
|
||||
this.redisManager = redisManager;
|
||||
this.chatGPTClient = chatGPTClient;
|
||||
this.geminiClient = geminiClient;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取分段内容对应的章节知识点
|
||||
|
|
@ -297,8 +299,8 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
try
|
||||
{
|
||||
var keyFrameArr = string.IsNullOrEmpty(taskInfo?.PPTVideoCode) || string.IsNullOrEmpty(taskInfo?.PPTKeyFrame)
|
||||
? string.Empty
|
||||
: $"授课PPT发生了变化的时间是{taskInfo.PPTKeyFrame},所以在这些时间段附近应该发生了授课内容得变化,授课阶段结果尽量参考这些时间节点(PPT与字幕有一定的延时)。";
|
||||
? $""
|
||||
: $"授课PPT发生了变化的时间是{taskInfo.PPTKeyFrame},基于PPT变化时间点,将字幕内容分割成时间段。每个时间段的起始和结束应接近这些时间点(例如,以时间点为中心,扩展至内容自然过渡处)。";
|
||||
var resFormat = """[{"StartTime":开始秒(number),"EndTime":结束秒(number),"Stage":阶段(string),"Theme":主题(string),"Content":内容总结(string)}]""";
|
||||
|
||||
var postMessages = string.Empty;
|
||||
|
|
@ -306,46 +308,27 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
{
|
||||
case AttachmentsInfoType.其他资料:
|
||||
case AttachmentsInfoType.新课:
|
||||
postMessages =
|
||||
$"请通过视频字幕内容分析出视频中课堂的授课阶段。" +
|
||||
$"课堂内容与{taskInfo.Subject}学科下的{sections}章节相关。" +
|
||||
$"{keyFrameArr}" +
|
||||
$"完整的课堂标准流程包含以下5个阶段:课程引入/新知讲解/例题精讲/课堂练习/知识总结。" +
|
||||
$"每个类型的授课阶段允许有多个 例如 多个新知讲解/例题精讲..." +
|
||||
$"1.初步划分阶段:基于PPT变化时间点,将字幕内容分割成时间段。每个时间段的起始和结束应接近这些时间点(例如,以时间点为中心,扩展至内容自然过渡处)。" +
|
||||
$"2.内容分析:对每个时间段,提取主要讲解内容:识别关键词(如“例题”“证明”“练习”“总结”)和内容结构。" +
|
||||
$"3.判断阶段类型:如果内容以解题为主,归类为“例题精讲”;如果涉及新知识讲解,归类为“新知讲解”;以此类推。" +
|
||||
$"4.生成内容总结与主题:内容总结:用1-2句话简述该阶段的核心讲解内容(例如,“通过例题演示柯西不等式在求最值中的应用”)。" +
|
||||
$"5.阶段主题:基于内容总结,提炼一个具体主题(例如,“柯西不等式的基本应用”)。" +
|
||||
$"6.时长检查与调整:计算每个阶段的时长(结束时间减开始时间)。如果阶段时长低于50秒,则合并相邻的类似内容阶段(例如,将两个连续的例题讲解合并为一个阶段),或扩展时间段以确保最低50秒。调整时需保持内容连贯性。" +
|
||||
$"7.输出要求:最终分析结果应列出每个阶段的开始时间、结束时间、阶段类型、主题和详细的内容总结(50~100字不包含提示词内容),确保划分合理、无重叠,且时长符合要求。" +
|
||||
$"输出内容只返回json格式({resFormat})" +
|
||||
$"字幕格式(开始秒:内容|下一段字幕).以下是包含时间的视频字幕文本。" +
|
||||
$"字幕列表 {captions.Captions} 字幕结束!";
|
||||
break;
|
||||
case AttachmentsInfoType.复习:
|
||||
postMessages =
|
||||
$"请通过视频字幕内容分析出视频中课堂的授课阶段。" +
|
||||
$"课堂内容与{taskInfo.Subject}学科下的{sections}章节相关。" +
|
||||
$"{keyFrameArr}" +
|
||||
$"完整的课堂标准流程包含以下5个阶段:课程引入/新知讲解/例题精讲/课堂练习/知识总结。" +
|
||||
$"但本堂课是习题课,所以大部分阶段是不同的例题讲解内容。" +
|
||||
$"1.初步划分阶段:基于PPT变化时间点,将字幕内容分割成时间段。每个时间段的起始和结束应接近这些时间点(例如,以时间点为中心,扩展至内容自然过渡处)。" +
|
||||
$"2.内容分析:对每个时间段,提取主要讲解内容:识别关键词(如“例题”“证明”“练习”“总结”)和内容结构。" +
|
||||
$"3.判断阶段类型:如果内容以解题为主,归类为“例题精讲”;如果涉及新知识讲解,归类为“新知讲解”;以此类推。" +
|
||||
$"4.生成内容总结与主题:内容总结:用1-2句话简述该阶段的核心讲解内容(例如,“通过例题演示柯西不等式在求最值中的应用”)。" +
|
||||
$"5.阶段主题:基于内容总结,提炼一个具体主题(例如,“柯西不等式的基本应用”)。" +
|
||||
$"6.时长检查与调整:计算每个阶段的时长(结束时间减开始时间)。如果阶段时长低于50秒,则合并相邻的类似内容阶段(例如,将两个连续的例题讲解合并为一个阶段),或扩展时间段以确保最低50秒。调整时需保持内容连贯性。" +
|
||||
$"7.输出要求:最终分析结果应列出每个阶段的开始时间、结束时间、阶段类型、主题和详细的内容总结(50~100字不包含提示词内容),确保划分合理、无重叠,且时长符合要求。" +
|
||||
$"输出格式要求:内容只返回json格式({resFormat})" +
|
||||
$"字幕格式(开始秒:内容|下一段字幕).以下是包含时间的视频字幕文本。" +
|
||||
$"字幕列表 {captions.Captions} 字幕结束!";
|
||||
break;
|
||||
case AttachmentsInfoType.活动:
|
||||
case AttachmentsInfoType.班会:
|
||||
break;
|
||||
default:
|
||||
throw new Exception("无效的课程类型");
|
||||
}
|
||||
postMessages =
|
||||
$"请通过视频字幕内容分析出视频中课堂的授课阶段。" +
|
||||
$"课堂内容与{taskInfo.Subject}学科下的{sections}章节相关。" +
|
||||
$"完整的课堂标准流程包含以下5个阶段:课程引入/新知讲解/例题精讲/课堂练习/知识总结。" +
|
||||
(taskInfo?.VideoType == AttachmentsInfoType.复习 ? $"但本堂课是习题课,所以大部分阶段是不同的例题讲解内容。" : string.Empty) +
|
||||
$"初步划分阶段:{keyFrameArr}" +
|
||||
$"内容分析:对每个时间段,提取主要讲解内容:识别关键词(如“例题”“证明”“练习”“总结”)和内容结构。" +
|
||||
$"判断阶段类型:如果内容以解题为主,归类为“例题精讲”;如果涉及新知识讲解,归类为“新知讲解”;以此类推。" +
|
||||
$"内容总结:简述该阶段的核心讲解内容70~200字,确保内容与阶段时间内授课内容符合。" +
|
||||
$"阶段主题:基于内容总结,提炼一个恰当的主题(例如,“柯西不等式的基本应用”)。" +
|
||||
$"输出要求:确保阶段划分合理、无重叠,且时长符合要求" +
|
||||
$"输出格式要求:内容只返回json格式({resFormat})" +
|
||||
$"字幕格式(开始秒:内容|下一段字幕).以下是包含时间的视频字幕文本。" +
|
||||
$"字幕列表 {captions.Captions} 字幕结束!";
|
||||
|
||||
await redisManager.AddTaskLog(taskInfo.Id, $"开始分析视频内容 {tryCount}");
|
||||
//return await chatGPTClient.ChatAsync<VideoKnowRes[]>(taskInfo.Id.ToString(), postMessages, "分析字幕");
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
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 System.Net;
|
||||
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
||||
using VideoAnalysisCore.AICore.GPT;
|
||||
using System.Text.Json;
|
||||
|
||||
|
||||
namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
||||
{
|
||||
|
||||
public class GeminiGPTClient : GPTClient
|
||||
{
|
||||
|
||||
public override GptConfig Config { get; set; } = AppCommon.Config.ChatGpt.ChatGpt;
|
||||
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly RedisManager redisManager;
|
||||
|
||||
public GeminiGPTClient(IHttpClientFactory httpClientFactory, RedisManager redisManager) : base(httpClientFactory, redisManager)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
this.redisManager = redisManager;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 请求AI
|
||||
/// </summary>
|
||||
/// <typeparam name="T">返回JSON类型</typeparam>
|
||||
/// <param name="task">任务id</param>
|
||||
/// <param name="postMessages">提示词</param>
|
||||
/// <param name="title">任务类型</param>
|
||||
/// <param name="model">GPT版本</param>
|
||||
/// <param name="max_tokens">最大token <para>不设置默认最大值 16000/8000</para></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public async Task<T> ChatAsync<T>(string task, string postMessages, string title, string model = null, int max_tokens = 8000)
|
||||
{
|
||||
Message[] messageArr = [
|
||||
new Message(postMessages,"user"),
|
||||
];
|
||||
model = model ?? ChatGPTType.Gemini_3_Chat;
|
||||
messageArr = messageArr.Where(s => s != null).ToArray();
|
||||
var chatReq = new ChatRequest
|
||||
{
|
||||
taskId = task,
|
||||
model = model,
|
||||
max_tokens =12000,
|
||||
stream = true,
|
||||
temperature = 0.2f,
|
||||
messages = messageArr
|
||||
};
|
||||
|
||||
chatReq.modalities = null;
|
||||
chatReq.max_tokens = null;
|
||||
chatReq.top_p = null;
|
||||
|
||||
return await base.ChatAsync<T>(chatReq);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -137,26 +137,26 @@ namespace VideoAnalysisCore.Common
|
|||
SubscribeList.Add(RedisChannelEnum.AI课程类型, async (task) =>
|
||||
{
|
||||
using var scope = AppCommon.Services?.CreateScope();
|
||||
if (scope is null || scope.ServiceProvider.GetService<IBserGPT>() is null)
|
||||
if (scope is null || scope.ServiceProvider.GetService<IBserGPTWorkflow>() is null)
|
||||
throw new Exception("IBserGPT 未注入");
|
||||
else
|
||||
await scope.ServiceProvider.GetService<IBserGPT>()?.GetVideoType(task);
|
||||
await scope.ServiceProvider.GetService<IBserGPTWorkflow>()?.GetVideoType(task);
|
||||
});
|
||||
SubscribeList.Add(RedisChannelEnum.AI模型分析, async (task) =>
|
||||
{
|
||||
using var scope = AppCommon.Services?.CreateScope();
|
||||
if (scope is null || scope.ServiceProvider.GetService<IBserGPT>() is null)
|
||||
if (scope is null || scope.ServiceProvider.GetService<IBserGPTWorkflow>() is null)
|
||||
throw new Exception("IBserGPT 未注入");
|
||||
else
|
||||
await scope.ServiceProvider?.GetService<IBserGPT>()?.GetKnow(task);
|
||||
await scope.ServiceProvider?.GetService<IBserGPTWorkflow>()?.GetKnow(task);
|
||||
});
|
||||
SubscribeList.Add(RedisChannelEnum.AI分析试题, async (task) =>
|
||||
{
|
||||
using var scope = AppCommon.Services?.CreateScope();
|
||||
if (scope is null || scope.ServiceProvider.GetService<IBserGPT>() is null)
|
||||
if (scope is null || scope.ServiceProvider.GetService<IBserGPTWorkflow>() is null)
|
||||
throw new Exception("IBserGPT 未注入");
|
||||
else
|
||||
await scope.ServiceProvider?.GetService<IBserGPT>()?.GetVideoQuestion(task);
|
||||
await scope.ServiceProvider?.GetService<IBserGPTWorkflow>()?.GetVideoQuestion(task);
|
||||
});
|
||||
SubscribeList.Add(RedisChannelEnum.结束任务, redisManager.TaskEnd);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue