From 02c6ef84d140b05875f6f957ae863afc99ab736f Mon Sep 17 00:00:00 2001 From: cst61 Date: Tue, 21 Apr 2026 00:07:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=8B=BC=E6=8E=A5=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E8=AF=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/rj/common/AudioAnalysisSceneType.java | 25 ++++++++--- .../controller/AudioManagementController.java | 13 +++--- .../com/rj/service/IAiPromptsService.java | 7 ++++ .../rj/service/impl/AiPromptsServiceImpl.java | 16 +++++++ .../impl/AudioTextAnalysisLlmServiceImpl.java | 42 +++++++++++++------ ...o_text_analysis_soft_sale_user_prompts.txt | 2 - 6 files changed, 78 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/rj/common/AudioAnalysisSceneType.java b/src/main/java/com/rj/common/AudioAnalysisSceneType.java index 5b59755..610c4dd 100644 --- a/src/main/java/com/rj/common/AudioAnalysisSceneType.java +++ b/src/main/java/com/rj/common/AudioAnalysisSceneType.java @@ -1,5 +1,7 @@ package com.rj.common; +import com.rj.controller.AudioManagementController; + /** * 音频文本分析场景类型 * 不同场景对应不同的系统/用户提示词以及大模型配置。 @@ -12,17 +14,20 @@ public enum AudioAnalysisSceneType { SCENARIO_FURNITURE_SALE( "prompts/audio_text_analysis_furniture_system.txt", "prompts/audio_text_analysis_furniture_user.txt", - "qwen-plus" + "qwen-plus", + AudioManagementController.SCENARIO_FURNITURE_SALE ), SCENARIO_SOFT_SALE( "prompts/audio_text_analysis_soft_sale_system_prompts.txt", "prompts/audio_text_analysis_soft_sale_user_prompts.txt", - "qwen-plus" + "qwen-plus", + AudioManagementController.SCENARIO_SOFT_SALE ), SCENARIO_SMALL_BEEUTIFUL_SALE( "prompts/audio_text_analysis_soft_sale_system_prompts.txt", "prompts/audio_text_analysis_soft_sale_user_prompts.txt", - "qwen-plus" + "qwen-plus", + AudioManagementController.SCENARIO_SMALL_BEEUTIFUL_SALE ), /** * 会议纪要/会议分析场景 @@ -31,7 +36,8 @@ public enum AudioAnalysisSceneType { SCENARIO_SUMMARY( "prompts/audio_text_analysis_summary_system_prompts.txt", "prompts/audio_text_analysis_summary_user_prompts.txt", - "qwen-plus" + "qwen-plus", + AudioManagementController.SCENARIO_SUMMARY ), /** @@ -40,17 +46,20 @@ public enum AudioAnalysisSceneType { SCENARIO_CAR_SALE( "prompts/audio_text_analysis_real_estate_system.txt", "prompts/audio_text_analysis_real_estate_user.txt", - "qwen-plus" + "qwen-plus", + AudioManagementController.SCENARIO_CAR_SALE ); private final String systemPromptPath; private final String userPromptPath; private final String modelName; + private final String sceneName; - AudioAnalysisSceneType(String systemPromptPath, String userPromptPath, String modelName) { + AudioAnalysisSceneType(String systemPromptPath, String userPromptPath, String modelName,String sceneName) { this.systemPromptPath = systemPromptPath; this.userPromptPath = userPromptPath; this.modelName = modelName; + this.sceneName = sceneName; } public String getSystemPromptPath() { @@ -64,6 +73,10 @@ public enum AudioAnalysisSceneType { public String getModelName() { return modelName; } + + public String getSceneName() { + return sceneName; + } } diff --git a/src/main/java/com/rj/controller/AudioManagementController.java b/src/main/java/com/rj/controller/AudioManagementController.java index b975a7c..accdab0 100644 --- a/src/main/java/com/rj/controller/AudioManagementController.java +++ b/src/main/java/com/rj/controller/AudioManagementController.java @@ -45,12 +45,11 @@ import java.util.UUID; public class AudioManagementController { // 场景常量,避免在解析逻辑中硬编码字符串 - private static final String SCENARIO_SOFT_SALE = "SOFT_SALE"; - private static final String SCENARIO_FURNITURE_SALE = "FURNITURE"; - private static final String SCENARIO_SMALL_BEEUTIFUL_SALE = "smallBeautiful_sales"; - private static final String SCENARIO_CAR_SALE = "CAR_SALE"; - private static final String SCENARIO_SUMMARY = "SUMMARY"; - private static final String SCENARIO_SPEAKING_TRAINING= "SPEAKING_TRAINING"; //租赁模式 + public static final String SCENARIO_SOFT_SALE = "soft_sales"; + public static final String SCENARIO_FURNITURE_SALE = "furniture"; + public static final String SCENARIO_SMALL_BEEUTIFUL_SALE = "smallBeautiful_sales"; + public static final String SCENARIO_CAR_SALE = "car_sale"; + public static final String SCENARIO_SUMMARY = "summary"; @Autowired @@ -860,7 +859,7 @@ public class AudioManagementController { return AudioAnalysisSceneType.SCENARIO_CAR_SALE; } // 未识别场景时,默认按会议场景处理 - return AudioAnalysisSceneType.SCENARIO_CAR_SALE; + return AudioAnalysisSceneType.SCENARIO_SOFT_SALE; } diff --git a/src/main/java/com/rj/service/IAiPromptsService.java b/src/main/java/com/rj/service/IAiPromptsService.java index ca2881c..54e4b8b 100644 --- a/src/main/java/com/rj/service/IAiPromptsService.java +++ b/src/main/java/com/rj/service/IAiPromptsService.java @@ -3,8 +3,15 @@ package com.rj.service; import com.baomidou.mybatisplus.extension.service.IService; import com.rj.entity.AiPrompts; +import java.util.List; + /** * 表 ai_prompts 服务;常规 CRUD 与分页见 {@link IService}。 */ public interface IAiPromptsService extends IService { + + /** + * 根据场景、分类、提示词类型、字段编码精确匹配查询。 + */ + List listByBizKeys(String scenarioCode, String categoryCode, String promptType, String fieldCode); } diff --git a/src/main/java/com/rj/service/impl/AiPromptsServiceImpl.java b/src/main/java/com/rj/service/impl/AiPromptsServiceImpl.java index 9036fb7..8466efe 100644 --- a/src/main/java/com/rj/service/impl/AiPromptsServiceImpl.java +++ b/src/main/java/com/rj/service/impl/AiPromptsServiceImpl.java @@ -1,14 +1,30 @@ package com.rj.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.rj.entity.AiPrompts; import com.rj.mapper.AiPromptsMapper; import com.rj.service.IAiPromptsService; import org.springframework.stereotype.Service; +import java.util.List; + /** * 表 ai_prompts 服务实现 */ @Service public class AiPromptsServiceImpl extends ServiceImpl implements IAiPromptsService { + + @Override + public List listByBizKeys(String scenarioCode, String categoryCode, String promptType, String fieldCode) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(AiPrompts::getScenarioCode, scenarioCode) + .eq(AiPrompts::getCategoryCode, categoryCode) + .eq(AiPrompts::getPromptType, promptType); + if (fieldCode != null) { + queryWrapper.eq(AiPrompts::getFieldCode, fieldCode); + } + + return this.list(queryWrapper); + } } diff --git a/src/main/java/com/rj/service/impl/AudioTextAnalysisLlmServiceImpl.java b/src/main/java/com/rj/service/impl/AudioTextAnalysisLlmServiceImpl.java index 63911d6..fc001eb 100644 --- a/src/main/java/com/rj/service/impl/AudioTextAnalysisLlmServiceImpl.java +++ b/src/main/java/com/rj/service/impl/AudioTextAnalysisLlmServiceImpl.java @@ -15,11 +15,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.rj.common.AudioAnalysisSceneType; import com.rj.common.LocalLlmSummaryResult; import com.rj.entity.*; -import com.rj.service.IAudioManagementService; -import com.rj.service.IAudioTextAnalysisFurnitureService; -import com.rj.service.IAudioTextAnalysisLlmService; -import com.rj.service.IAudioTextAnalysisSopService; -import com.rj.service.ITodoItemService; +import com.rj.service.*; import dev.langchain4j.model.chat.response.ChatResponse; import dev.langchain4j.model.chat.response.StreamingChatResponseHandler; import dev.langchain4j.model.openai.OpenAiStreamingChatModel; @@ -116,19 +112,38 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer } } + @Autowired + IAiPromptsService aiPromptsService; + @Override public GenerationResult generateSummaryByLLM(AudioAnalysisSceneType sceneType, String recordingText) { long startTime = System.currentTimeMillis(); log.info("开始调用大模型生成总结,场景: {}", sceneType); - String systemPrompt = getSystemPrompt(sceneType); - String userPromptTemplate = getUserPromptTemplate(sceneType); - String userPrompt = buildPrompt(userPromptTemplate, recordingText); + AiPrompts sysTotalItemPrompts = aiPromptsService.listByBizKeys(sceneType.getSceneName(), "total_item", "systemPrompt", "total_item").get(0); + AiPrompts userTotalItemPrompts = aiPromptsService.listByBizKeys(sceneType.getSceneName(), "total_item", "userPrompt", "total_item").get(0); + List userFieldsItemPrompts = aiPromptsService.listByBizKeys(sceneType.getSceneName(), "fields", "userPrompt", null); + AiPrompts userReplyStructureRequirementsItemPrompts = aiPromptsService.listByBizKeys(sceneType.getSceneName(), "reply_tructure_requirements", "userPrompt", null).get(0); + AiPrompts userTecordingTextItemPrompts = aiPromptsService.listByBizKeys(sceneType.getSceneName(), "recording_text", "userPrompt", null).get(0); + StringBuilder userItemPrompts = new StringBuilder(); + userItemPrompts.append(userTotalItemPrompts.getPromptText()).append("\n"); + int i=0; + for (AiPrompts userFieldItemPrompt : userFieldsItemPrompts) { + userItemPrompts.append((++i) +", \""+userFieldItemPrompt.getFieldCode()+"\":"+ "\""+userFieldItemPrompt.getPromptText()+"\";").append("\n"); + } + + userItemPrompts.append(userReplyStructureRequirementsItemPrompts.getPromptText()).append("\n"); + + userItemPrompts.append(userTecordingTextItemPrompts.getPromptText()); + + String userPrompt = buildPrompt(userItemPrompts.toString(), recordingText); + log.info("userPrompt------------------------------\n: {}", userPrompt); + log.info("total length: recordingText------------------------------ \n: {}:{}", userPrompt.length() ,recordingText.length()); Generation gen = new Generation(); Message systemMsg = Message.builder() .role(Role.SYSTEM.getValue()) - .content(systemPrompt) + .content(sysTotalItemPrompts.getPromptText()) .build(); Message userMsg = Message.builder() .role(Role.USER.getValue()) @@ -561,8 +576,11 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer log.info(" AudioManagementSegments 总数是: {} ,未转文本记录条数是: {}",segmentList.size(), emptyCount); - LocalLlmSummaryResult llmResult = generateSummaryByLocalLLM(sceneType, mergedText.toString()); - String rawContent = llmResult.rawContent(); + GenerationResult generationResult = generateSummaryByLLM(sceneType, mergedText.toString()); + log.info("大模型生成总结完成,token花费,总token: {}, 输入token: {}, 输出token: {}, 输出token详情: {}", + generationResult.getUsage().getTotalTokens(),generationResult.getUsage().getInputTokens(),generationResult.getUsage().getOutputTokens(),generationResult.getUsage().getOutputTokensDetails()); + // 1. 调用大模型生成总结 + String rawContent = generationResult.getOutput().getChoices().get(0).getMessage().getContent(); if (rawContent == null || rawContent.trim().isEmpty()) { log.warn("大模型返回内容为空"); return null; @@ -571,7 +589,7 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer AudioManagement audioManagement = new AudioManagement(); audioManagement.setId(parentId); audioManagement.setSummary(rawContent); - applyLocalLlmTokenCountsToAudioManagement(audioManagement, llmResult); +// applyLocalLlmTokenCountsToAudioManagement(audioManagement, llmResult); audioManagementService.updateById(audioManagement); return furniture; diff --git a/src/main/resources/prompts/audio_text_analysis_soft_sale_user_prompts.txt b/src/main/resources/prompts/audio_text_analysis_soft_sale_user_prompts.txt index fbaab79..401a4f2 100644 --- a/src/main/resources/prompts/audio_text_analysis_soft_sale_user_prompts.txt +++ b/src/main/resources/prompts/audio_text_analysis_soft_sale_user_prompts.txt @@ -30,8 +30,6 @@ 34. polite_farewell:礼貌道别得分,评估销售顾问在服务结束时的表现,是否礼貌送别,是否表达感谢,是否留下良好印象,是否约定后续跟进。 - - 重要:每个软件功能维度(soft_function_audio_assets、soft_function_customer_assets、soft_function_pain_points_analysis 、soft_function_customer_profile)必须是一个JSON对象,包含以下10个维度: 1. efficiencyImprovement:使用之后的效率提升多少 2. stability:功能的稳定性