优化 新版ai内容分段关键词

This commit is contained in:
小肥羊 2025-01-17 18:22:20 +08:00
parent cbb6315fac
commit b48c86936b
6 changed files with 87 additions and 57 deletions

View File

@ -3,8 +3,11 @@
<div id="video-container"> <div id="video-container">
@if (videoKnows != null) @if (videoKnows != null)
{ {
<div id="segmentsContainer"> <div id="segmentsContainer" class="sc">
<h2>@nowTask.MediaName</h2>
<h2>
<button class="gudingBtn" onclick="gd(this)">🔒</button>
@nowTask.MediaName</h2>
@for (int i = 0; i < videoKnows.Length; i++) @for (int i = 0; i < videoKnows.Length; i++)
{ {
var item = videoKnows[i]; var item = videoKnows[i];
@ -70,4 +73,14 @@
function spClick(i, button) { function spClick(i, button) {
videoPlayer.currentTime = displayButton[i].startTime; videoPlayer.currentTime = displayButton[i].startTime;
} }
function gd(btn) {
let e = btn.parentElement.parentElement
if (e.style.right == "0px") {
btn.innerHTML = "🔒"
e.style.right = "-300px"
} else {
e.style.right = "0px"
btn.innerHTML = "🔓"
}
}
</script> </script>

View File

@ -57,10 +57,10 @@ namespace Learn.VideoAnalysis.Components.Pages
} }
public string getF(VideoKnowRes segment) public string getF(VideoKnowRes segment)
{ {
var sf = (int)((segment.StartTime ?? 0) / 60); var sf = ((int)((segment.StartTime ?? 0) / 60)).ToString().PadLeft(2,'0');
var sm = (int)((segment.StartTime ?? 0) % 60); var sm = ((int)((segment.StartTime ?? 0) % 60)).ToString().PadLeft(2, '0');
var ef = (int)((segment.EndTime ?? 0) / 60); var ef = ((int)((segment.EndTime ?? 0) / 60)).ToString().PadLeft(2, '0');
var em = (int)((segment.EndTime ?? 0) % 60); var em = ((int)((segment.EndTime ?? 0) % 60)).ToString().PadLeft(2, '0');
return $"{sf}:{sm} - {ef}: {em}"; return $"{sf}:{sm} - {ef}: {em}";
} }
/// <summary> /// <summary>

View File

@ -16,7 +16,13 @@ video {
width: 94%; width: 94%;
height: 85%; height: 85%;
} }
.gudingBtn {
width: 32px;
height: 32px;
/* border-radius: 16px; */
line-height: 27px;
text-align: center;
}
.subtitles { .subtitles {
position: absolute; position: absolute;
bottom: 200px; bottom: 200px;
@ -28,7 +34,7 @@ video {
} }
#segmentsContainer:is(:hover) { #segmentsContainer:is(:hover) {
width: 400px; width: 400px;
right: 0px; right: 0px!important;
} }
#segmentsContainer { #segmentsContainer {
transition: right 0.7s; transition: right 0.7s;
@ -36,10 +42,10 @@ video {
overflow-x: hidden; overflow-x: hidden;
background-color: #e3e3e3c2; background-color: #e3e3e3c2;
position: absolute; position: absolute;
right: -180px; right: -300px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 265px; width: 400px;
height: 850px; height: 850px;
gap: 10px; gap: 10px;
overflow: hidden; overflow: hidden;
@ -52,7 +58,7 @@ video {
align-items: center; align-items: center;
} }
#segmentsContainer button { .kBtn {
width: 100%; width: 100%;
height: 60px; height: 60px;
font-size: 1.3rem; font-size: 1.3rem;
@ -63,7 +69,7 @@ video {
border: 1px solid rgb(179, 225, 157); border: 1px solid rgb(179, 225, 157);
} }
#segmentsContainer button:hover { .kBtn:hover {
background-color: rgb(248, 230, 191) !important; background-color: rgb(248, 230, 191) !important;
border: 1px solid rgb(206, 187, 81); border: 1px solid rgb(206, 187, 81);
} }

View File

@ -16,7 +16,7 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
/// </summary> /// </summary>
public Message[] messages { get; set; } public Message[] messages { get; set; }
public string model { get; set; } = "gpt-4o"; public string model { get; set; } = "gpt-4o";
public float temperature { get; set; } = 0.3f; public float temperature { get; set; } = 0.2f;
public float max_tokens { get; set; } = 4000; public float max_tokens { get; set; } = 4000;
public object response_format = new { type = "json_object" }; // 指定结构化输出格式 public object response_format = new { type = "json_object" }; // 指定结构化输出格式
} }

View File

@ -87,47 +87,55 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
$"1.分析出高中{subject}课堂授课的主要章节(例如 章节: 数列),章节范围限定在[{string.Join(',', xkwKnows)}]范围." + $"1.分析出高中{subject}课堂授课的主要章节(例如 章节: 数列),章节范围限定在[{string.Join(',', xkwKnows)}]范围." +
$"2.分析出这堂课的主要授课内容." + $"2.分析出这堂课的主要授课内容." +
$"输出格式 json字符串 对象格式{fileNameResFormat}"; $"输出格式 json字符串 对象格式{fileNameResFormat}";
var fileNameInfoRes = await ChatAsync<FileNameInfo>(task, fileNamePostMessages, fileNameResFormat); var fileNameInfoRes = await ChatAsync<FileNameInfo>(task, fileNamePostMessages,null, fileNameResFormat);
var captions = ExpandFunction.GetSpeakerCaptions(task); var captions = ExpandFunction.GetSpeakerCaptions(task);
var criteriaBuilder = new StringBuilder(); var criteriaBuilder = new StringBuilder();
var resFormat = """[{"StartTime":开始秒(number),"EndTime":结束秒(number),"Section":章节(string),"Theme":主题(string),"NewTheme":主题(string),"Content":内容总结(string)}]"""; var resFormat = """[{"StartTime":开始秒(number),"EndTime":结束秒(number),"Section":章节(string),"Theme":主题(string),"ThemeDetalis":主题详情(string),"Content":内容总结(string)}]""";
var know = await knowledgeInfoDB.GetFirstAsync(s => s.Name == fileNameInfoRes.); var know = await knowledgeInfoDB.GetFirstAsync(s => s.Name == fileNameInfoRes.);
var knowledgeInfos = await knowledgeInfoDB.AsQueryable().ToChildListAsync(s => s.Parent_Id, know.Id); var knowledgeInfos = await knowledgeInfoDB.AsQueryable().ToChildListAsync(s => s.Parent_Id, know.Id);
var knows = "数列的概念,数列的定义,项的表示,数列的表示方法,通项公式,递推公式,图像表示,数列的类型,等差数列,等比数列,其他特殊数列,数列的性质,单调性,有限性,数列的求和,等差数列求和公式,等比数列求和公式,数列极限,递推关系"; var knows = "数列的概念,数列的定义,项的表示,数列的表示方法,通项公式,递推公式,图像表示,数列的类型,等差数列,等比数列,其他特殊数列,数列的性质,单调性,有限性,数列的求和,等差数列求和公式,等比数列求和公式,数列极限,递推关系";
knows = string.Join(',', knowledgeInfos.Select(s => s.Name)); knows = string.Join(',', knowledgeInfos.Select(s => s.Name));
var postMessages = var postMessages =
$"你的任务是分析视频字幕内容并提取出中国高考考试试题方法点,然后根据步骤分析出内容片段" + $"你的任务是分析视频字幕内容并提取出中国高考考试试题方法点,然后根据步骤分析出内容片段" +
$"按以下步骤完成:" + $"按以下步骤完成:" +
$"1.识别方法点:提取字幕内容中与{subject}考试相关的方法点。" + $"1.识别方法点:提取字幕内容中与{subject}考试属于{fileNameInfoRes.授课章节}章节相关的方法点。" +
$"2.分类方法点:按学科方法点,细化到具体章节与主题(例如“章节:数列 主题:数列的基本概念”)。" + $"2.分析总结:基于提取出的方法点名称来匹配我提供的方法点名称" +
$"3.分析总结:基于提取出的方法点名称来匹配我提供的方法点名称" + $"提供的方法点名称(基本概念,课堂练习,例题讲解,{knows})。" +
$"提供的方法点名称(基本概念,课堂练习,{knows},例题讲解)。" + $"3.关联合并相似的知识点来合并为内容片段。" +
$"4.关联合并相似的知识点来合并为内容片段。" +
$"内容片段使用关联知识点中的最小(开始秒)和(最大)结束秒,主题为关联知识点的主题分析,内容总结为关联知识点的内容总结分析。" + $"内容片段使用关联知识点中的最小(开始秒)和(最大)结束秒,主题为关联知识点的主题分析,内容总结为关联知识点的内容总结分析。" +
$"延长内容片段时间区间来获取更加详细的上下文。" + $"4.基于内容片段的内容总结加上主题来分析这个片段对主题的讲解内容为新的主题 例(数列的基本概念)。" +
$"基于内容片段的内容总结加上主题来分析这个片段对主题的讲解内容为新的主题 例(数列的基本概念)。" + $"5.分配空余未使用的时间段到内容相近的内容片段时间区间来获取更加详细的上下文,但是请避免内容片段之间时间重合。" +
$"输入:包含时间戳的视频字幕文本。" + $"输入:包含时间戳的视频字幕文本。" +
$"以下是包含时间的视频字幕文本。" + $"以下是包含时间的视频字幕文本。" +
$"字幕格式(说话人:开始秒:结束秒:内容|下一段字幕).字幕列表 {captions.Captions}" + $"字幕格式(说话人:开始秒:结束秒:内容|下一段字幕).字幕列表 {captions.Captions}" +
$"输出格式({resFormat})"; $"输出格式({resFormat})";
var questionRes = await ChatAsync<VideoKnowRes[]>(task, postMessages, null, resFormat);
//var postMessages = //var postMessages =
// $"你是一名专业教育视频内容分析助手,主要任务是分析视频字幕内容,精准提取出与中国高考数学考试相关的试题方法点。" + // $"你的任务是分析视频字幕内容,精准提取出与中国高考数学考试相关的试题方法点。" +
// $"按以下步骤完成:" + // $"按以下步骤完成:" +
// $"1.准确识别方法点:从字幕中提取与{subject}考试紧密相关的方法点,尤其关注与给定方法点类别相关的内容" + // $"1.准确识别方法点:从字幕中提取与考试紧密相关的方法点,尤其关注与给定方法点类别相关的内容" +
// $"2.深入分析总结:依据给定的方法点类别进行约束,确定提取出的方法点所属类别。" + // $"2.深入分析总结:依据给定的方法点类别进行约束,确定提取出的方法点所属类别。" +
// $"给定方法点包括(基本概念,课堂练习,例题讲解,解题技巧,{gjz})。" + // $"给定方法点包括(基本概念,课堂练习,例题讲解,解题技巧...)。" +
// $"3.细致分类方法点:按照学科方法点进行分类,具体细化到特定章节与主题,格式为 “章节:具体章节名称 主题:具体主题名称" + // $"3.细致分类方法点:按照学科方法点进行分类,具体细化到特定章节与主题,格式为 “章节:具体章节名称 主题:具体主题名称" +
// $"4.合理合并相似方法点为内容片段,确保内容的连贯性和逻辑性" + // $"4.合理合并相似方法点为内容片段,确保内容的连贯性和逻辑性" +
// $"5.关联每个内容片段的方法点所有的时间并结构化输出。" + // $"5.关联每个内容片段的方法点所有的时间并结构化输出。" +
// $"6.基于内容片段的内容总结加上主题来分析这个片段对主题的讲解内容为新的主题 例(数列的基本概念)。" +
// $"尽可能延内容片段时间区间,以获取详细的方法点上下文。" + // $"尽可能延内容片段时间区间,以获取详细的方法点上下文。" +
// $"输入:包含时间戳的视频字幕文本。输出格式:开始秒,结束秒,主题,内容总结" + // $"输入:包含时间戳的视频字幕文本。输出格式:开始秒,结束秒,主题,内容总结" ;
// $"以下是包含时间的视频字幕文本。" + //var postM2 = $"以下是包含时间的视频字幕文本。" +
// $"字幕格式(说话人:开始秒:结束秒:内容|下一段字幕).字幕列表 {captions.Captions}" + // $"字幕格式(说话人:开始秒:结束秒:内容|下一段字幕).字幕列表 {captions.Captions}" +
// $"返回固定的JSON格式({resFormat})"; // $"返回固定的JSON格式({resFormat})";
var questionRes =await ChatAsync<VideoKnowRes[]>(task, postMessages, resFormat); //var questionRes = await ChatAsync<VideoKnowRes[]>(task, postMessages, postM2, resFormat);
if (questionRes.Length <= 3)
throw new Exception("视频分段数量过低 =>"+ questionRes.Length);
if (questionRes.Count(s=>s.ThemeDetalis == questionRes.First().ThemeDetalis) >= 3)
throw new Exception("视频分段主题重复 =>" + questionRes.First().ThemeDetalis);
await RedisExpand.Redis await RedisExpand.Redis
.HMSetAsync(RedisExpandKey.Task(task), "VideoKnows", questionRes); .HMSetAsync(RedisExpandKey.Task(task), "VideoKnows", questionRes);
@ -152,17 +160,20 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
RedisExpand.InsertChannel(RedisChannelEnum.EndTask, task); RedisExpand.InsertChannel(RedisChannelEnum.EndTask, task);
return gptRes; return gptRes;
} }
public async Task<T> ChatAsync<T>(string task,string postMessages,string resFormat) public async Task<T> ChatAsync<T>(string task, string postMessages,string postMessages1, string resFormat)
{ {
var maxTokens = 4000; var maxTokens = 4000;
Message[] messageArr = [
new Message(postMessages,"system"),
string.IsNullOrEmpty(postMessages1)?null:new Message(postMessages1,"user"),
new Message(resFormat,"assistant"),
];
messageArr = messageArr.Where(s => s != null).ToArray();
var chatRep = new ChatRequest var chatRep = new ChatRequest
{ {
max_tokens = maxTokens, max_tokens = maxTokens,
temperature = 0.3f, temperature = 0.2f,
messages = [ messages = messageArr
new Message(postMessages,"system"),
new Message(resFormat,"assistant"),
]
}; };
RedisExpand.SetTaskGPTReqCached(task, chatRep); RedisExpand.SetTaskGPTReqCached(task, chatRep);

View File

@ -26,9 +26,9 @@ namespace VideoAnalysisCore.AICore.GPT.Dto
/// </summary> /// </summary>
public string? Theme { get; set; } public string? Theme { get; set; }
/// <summary> /// <summary>
/// 主题 /// 主题详情
/// </summary> /// </summary>
public string? NewTheme { get; set; } public string? ThemeDetalis { get; set; }
/// <summary> /// <summary>
/// 章节 /// 章节
/// </summary> /// </summary>