feat: 优化会议状态解析和章节边界识别逻辑
- 在 `MeetingUnifiedStatusServiceImpl` 中添加 `MeetingUnifiedStageContext` 参数,优化阶段解析逻辑 - 在 `MeetingTranscriptChapterServiceImpl` 中更新章节边界识别的系统提示,使其更清晰 - 在 `AiTaskServiceImpl` 和 `MeetingProgressServiceImpl` 中增加对 AI 目录启用状态的检查,优化任务调度逻辑dev_na
parent
a036c14673
commit
033ffaacc9
|
|
@ -1121,7 +1121,7 @@ public class AiTaskServiceImpl extends ServiceImpl<AiTaskMapper, AiTask> impleme
|
|||
meetingPointsService.recordSummarySuccessCharge(meeting, taskRecord);
|
||||
|
||||
AiTask latestChapterTask = findLatestTask(meeting.getId(), "CHAPTER");
|
||||
if (latestChapterTask != null && Integer.valueOf(2).equals(latestChapterTask.getStatus())) {
|
||||
if (!resolveAiCatalogEnabled() ||(latestChapterTask != null && Integer.valueOf(2).equals(latestChapterTask.getStatus()))) {
|
||||
updateProgress(meeting.getId(), 100, "全流程分析完成", 0);
|
||||
} else {
|
||||
updateProgress(meeting.getId(), 95, "总结生成完成,等待 AI 目录完成...", 0);
|
||||
|
|
@ -1369,7 +1369,7 @@ public class AiTaskServiceImpl extends ServiceImpl<AiTaskMapper, AiTask> impleme
|
|||
updateMeetingStatus(meetingId, 4);
|
||||
return;
|
||||
}
|
||||
if (isTaskCompleted(chapterTask) && isTaskCompleted(summaryTask)) {
|
||||
if ( isTaskCompleted(summaryTask) && (!resolveAiCatalogEnabled() || isTaskCompleted(chapterTask))) {
|
||||
updateMeetingStatus(meetingId, 3);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,6 +241,14 @@ public class MeetingProgressServiceImpl implements MeetingProgressService {
|
|||
if (latestChapter != null && Integer.valueOf(1).equals(latestChapter.getStatus())) {
|
||||
return buildSnapshot(meetingId, latestChapter, meeting.getStatus(), MeetingProgressStage.CHAPTER_RUNNING, 85, "正在生成会议章节...", 0);
|
||||
}
|
||||
if (MeetingStatusEnum.isCode(meeting.getStatus(), MeetingStatusEnum.SUMMARIZING)) {
|
||||
if (latestSummary != null && Integer.valueOf(2).equals(latestSummary.getStatus())) {
|
||||
return buildSnapshot(meetingId, latestSummary, meeting.getStatus(), MeetingProgressStage.SUMMARY_RUNNING, 90, "正在生成会议总结...", 0);
|
||||
}
|
||||
if (latestChapter != null && Integer.valueOf(0).equals(latestChapter.getStatus())) {
|
||||
return buildSnapshot(meetingId, latestChapter, meeting.getStatus(), MeetingProgressStage.CHAPTER_RUNNING, 85, "正在生成会议章节...", 0);
|
||||
}
|
||||
}
|
||||
AiTask latestAsr = findLatestTask(meetingId, "ASR");
|
||||
if (latestAsr != null) {
|
||||
if (Integer.valueOf(1).equals(latestAsr.getStatus())) {
|
||||
|
|
|
|||
|
|
@ -369,28 +369,29 @@ public class MeetingTranscriptChapterServiceImpl implements MeetingTranscriptCha
|
|||
|
||||
private String buildChapterSystemPrompt() {
|
||||
return """
|
||||
你负责对会议转录分段做章节边界识别。
|
||||
只允许返回 JSON。
|
||||
只能返回 chapters 数组。
|
||||
JSON里面必须包含chapters 数组,就算只有一个章节
|
||||
每个章节只允许包含:
|
||||
chapterNo,title,summary,keywords,startTranscriptId,endTranscriptId,confidence
|
||||
不得改写原文。
|
||||
不得输出章节正文。
|
||||
不得归一化数字、日期、金额、时间点。
|
||||
所有章节必须完整覆盖全部 transcript。
|
||||
章节必须严格连续:
|
||||
- 第一个章节 startTranscriptId 必须为 转录原文的起始transcriptId
|
||||
- 下一个章节的 startTranscriptId 必须等于上一个章节的 endTranscriptId + 1
|
||||
- 最后一个章节必须覆盖最后一条 transcript
|
||||
禁止:
|
||||
- transcript 遗漏
|
||||
- transcript 重复
|
||||
- 章节重叠
|
||||
- 跳跃式分段
|
||||
章节标题、摘要、关键词必须基于对应章节原文生成,不得虚构。
|
||||
若无法识别明确的话题边界,则将全部 transcript 作为一个章节返回.
|
||||
|
||||
你是会议转录分段任务中的“章节边界识别器”。
|
||||
基于输入 transcript 列表,进行语义分段,输出章节结构。
|
||||
输出格式(严格)
|
||||
只允许输出 JSON,且必须符合以下结构:
|
||||
{
|
||||
"chapters": [
|
||||
{
|
||||
"chapterNo": number,
|
||||
"title": string,
|
||||
"summary": string,
|
||||
"keywords": [string],
|
||||
"startTranscriptId": number,
|
||||
"endTranscriptId": number,
|
||||
"confidence": number
|
||||
}
|
||||
]
|
||||
}
|
||||
规则:
|
||||
1. 必须按顺序分段,不允许交叉或跳跃
|
||||
2. 必须覆盖全部 transcript
|
||||
3. 若无明显边界,则合并为一个章节
|
||||
4. title 必须基于该段内容生成
|
||||
5. 只输出 JSON,不要任何解释
|
||||
""";
|
||||
}
|
||||
|
||||
|
|
@ -1017,9 +1018,9 @@ public class MeetingTranscriptChapterServiceImpl implements MeetingTranscriptCha
|
|||
Long startTranscriptId = longValue(item.path("startTranscriptId").asText(null));
|
||||
Long endTranscriptId = longValue(item.path("endTranscriptId").asText(null));
|
||||
Integer chapterNo = item.path("chapterNo").isInt() ? item.path("chapterNo").asInt() : null;
|
||||
if (chapterNo == null || startTranscriptId == null || endTranscriptId == null) {
|
||||
throw new RuntimeException("章节模型返回了不完整的章节边界");
|
||||
}
|
||||
// if (chapterNo == null || startTranscriptId == null || endTranscriptId == null) {
|
||||
// throw new RuntimeException("章节模型返回了不完整的章节边界");
|
||||
// }
|
||||
List<String> keywords = new ArrayList<>();
|
||||
if (item.path("keywords").isArray()) {
|
||||
for (JsonNode keyword : item.path("keywords")) {
|
||||
|
|
|
|||
|
|
@ -90,12 +90,12 @@ public class MeetingUnifiedStatusServiceImpl implements MeetingUnifiedStatusServ
|
|||
if (isAndroidOfflineMeetingWaitingUpload(meeting)) {
|
||||
return UnifiedMeetingStatusStage.WAITING_UPLOAD;
|
||||
}
|
||||
UnifiedMeetingStatusStage stageFromSnapshot = resolveStageFromSnapshot(snapshot);
|
||||
MeetingUnifiedStageContext context = buildStageContext(meeting.getId(), snapshot);
|
||||
UnifiedMeetingStatusStage stageFromSnapshot = resolveStageFromSnapshot(snapshot, context);
|
||||
if (stageFromSnapshot != null) {
|
||||
return stageFromSnapshot;
|
||||
}
|
||||
|
||||
MeetingUnifiedStageContext context = buildStageContext(meeting.getId(), snapshot);
|
||||
if (isTranscribing(context)) {
|
||||
return UnifiedMeetingStatusStage.TRANSCRIBING;
|
||||
}
|
||||
|
|
@ -106,7 +106,8 @@ public class MeetingUnifiedStatusServiceImpl implements MeetingUnifiedStatusServ
|
|||
return UnifiedMeetingStatusStage.INITIALIZING;
|
||||
}
|
||||
|
||||
private UnifiedMeetingStatusStage resolveStageFromSnapshot(MeetingProgressSnapshot snapshot) {
|
||||
private UnifiedMeetingStatusStage resolveStageFromSnapshot(MeetingProgressSnapshot snapshot,
|
||||
MeetingUnifiedStageContext context) {
|
||||
if (snapshot == null || snapshot.getStage() == null || snapshot.getStage().isBlank()) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -115,11 +116,24 @@ public class MeetingUnifiedStatusServiceImpl implements MeetingUnifiedStatusServ
|
|||
case "completed" -> UnifiedMeetingStatusStage.COMPLETED;
|
||||
case "summary_running", "chapter_running" -> UnifiedMeetingStatusStage.SUMMARIZING;
|
||||
case "asr_running", "asr_completed", "asr_submitted" -> UnifiedMeetingStatusStage.TRANSCRIBING;
|
||||
case "queued" -> UnifiedMeetingStatusStage.INITIALIZING;
|
||||
case "queued" -> resolveQueuedSnapshotStage(context);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private UnifiedMeetingStatusStage resolveQueuedSnapshotStage(MeetingUnifiedStageContext context) {
|
||||
if (context == null) {
|
||||
return UnifiedMeetingStatusStage.INITIALIZING;
|
||||
}
|
||||
if (isSummarizing(context)) {
|
||||
return UnifiedMeetingStatusStage.SUMMARIZING;
|
||||
}
|
||||
if (isTranscribing(context)) {
|
||||
return UnifiedMeetingStatusStage.TRANSCRIBING;
|
||||
}
|
||||
return UnifiedMeetingStatusStage.INITIALIZING;
|
||||
}
|
||||
|
||||
private UnifiedMeetingStatusStage resolveFailedStage(MeetingVO meeting) {
|
||||
if (meeting == null || !MeetingStatusEnum.isCode(meeting.getStatus(), MeetingStatusEnum.FAILED)) {
|
||||
return null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue