本地大漠模型联调,阿里百炼token
This commit is contained in:
11
src/main/java/com/rj/common/LocalLlmSummaryResult.java
Normal file
11
src/main/java/com/rj/common/LocalLlmSummaryResult.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package com.rj.common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地 OpenAI 兼容接口生成总结的文本与 token 用量(来自 LangChain4j / 服务端 usage 字段)。
|
||||||
|
*/
|
||||||
|
public record LocalLlmSummaryResult(
|
||||||
|
String rawContent,
|
||||||
|
Integer totalTokens,
|
||||||
|
Integer inputTokens,
|
||||||
|
Integer outputTokens) {
|
||||||
|
}
|
||||||
@@ -720,16 +720,7 @@ public class AudioManagementController {
|
|||||||
|
|
||||||
|
|
||||||
// 4. 通过业务层通用服务调用大模型生成总结并保存数据
|
// 4. 通过业务层通用服务调用大模型生成总结并保存数据
|
||||||
AudioTextAnalysisFurniture furniture = audioTextAnalysisLlmService.generateSummaryAndSave(
|
// AudioTextAnalysisFurniture furniture = audioTextAnalysisLlmService.generateSummaryAndSave(
|
||||||
sceneType,
|
|
||||||
recordingText,
|
|
||||||
audioManagement.getId(),
|
|
||||||
audioManagement.getSalesName(),
|
|
||||||
audioManagement.getSalesPhone(),
|
|
||||||
audioManagement.getCustomerName(),
|
|
||||||
audioManagement.getCustomerPhone()
|
|
||||||
);
|
|
||||||
// AudioTextAnalysisFurniture furniture = audioTextAnalysisLlmService.generateSummaryAndSave_V2(
|
|
||||||
// sceneType,
|
// sceneType,
|
||||||
// recordingText,
|
// recordingText,
|
||||||
// audioManagement.getId(),
|
// audioManagement.getId(),
|
||||||
@@ -738,6 +729,15 @@ public class AudioManagementController {
|
|||||||
// audioManagement.getCustomerName(),
|
// audioManagement.getCustomerName(),
|
||||||
// audioManagement.getCustomerPhone()
|
// audioManagement.getCustomerPhone()
|
||||||
// );
|
// );
|
||||||
|
AudioTextAnalysisFurniture furniture = audioTextAnalysisLlmService.generateSummaryAndSave_V2(
|
||||||
|
sceneType,
|
||||||
|
recordingText,
|
||||||
|
audioManagement.getId(),
|
||||||
|
audioManagement.getSalesName(),
|
||||||
|
audioManagement.getSalesPhone(),
|
||||||
|
audioManagement.getCustomerName(),
|
||||||
|
audioManagement.getCustomerPhone()
|
||||||
|
);
|
||||||
log.info("llm return furniture Analysis : ",furniture.toString() );
|
log.info("llm return furniture Analysis : ",furniture.toString() );
|
||||||
if (recordingText == null || recordingText.trim().isEmpty()) {
|
if (recordingText == null || recordingText.trim().isEmpty()) {
|
||||||
result.put("success", false);
|
result.put("success", false);
|
||||||
|
|||||||
@@ -28,6 +28,6 @@ public class AiQaCustomerAskRequestDto {
|
|||||||
@Schema(description = "可选系统提示词,不传则使用默认助手设定")
|
@Schema(description = "可选系统提示词,不传则使用默认助手设定")
|
||||||
private String systemPrompt;
|
private String systemPrompt;
|
||||||
|
|
||||||
@Schema(description = "max_tokens,不传则使用配置 ai.qa.local.max-tokens(默认 512)")
|
@Schema(description = "max_tokens,不传则使用配置 ai.qa.local.max-tokens(默认 2048)")
|
||||||
private Integer maxTokens;
|
private Integer maxTokens;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,6 +189,18 @@ public class AudioManagement implements Serializable {
|
|||||||
@TableField("summary")
|
@TableField("summary")
|
||||||
private String summary;
|
private String summary;
|
||||||
|
|
||||||
|
@Schema(description = "大模型调用总 token 数")
|
||||||
|
@TableField("total_tokens")
|
||||||
|
private Integer totalTokens;
|
||||||
|
|
||||||
|
@Schema(description = "大模型输入 token 数")
|
||||||
|
@TableField("input_tokens")
|
||||||
|
private Integer inputTokens;
|
||||||
|
|
||||||
|
@Schema(description = "大模型输出 token 数")
|
||||||
|
@TableField("output_tokens")
|
||||||
|
private Integer outputTokens;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前端上传的录音文件
|
* 前端上传的录音文件
|
||||||
* 此字段不保存在数据库中,仅用于接收前端上传的文件
|
* 此字段不保存在数据库中,仅用于接收前端上传的文件
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.rj.service;
|
package com.rj.service;
|
||||||
|
|
||||||
|
import com.alibaba.dashscope.aigc.generation.GenerationResult;
|
||||||
import com.rj.common.AudioAnalysisSceneType;
|
import com.rj.common.AudioAnalysisSceneType;
|
||||||
|
import com.rj.common.LocalLlmSummaryResult;
|
||||||
import com.rj.entity.AudioTextAnalysisFurniture;
|
import com.rj.entity.AudioTextAnalysisFurniture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,7 +21,7 @@ public interface IAudioTextAnalysisLlmService {
|
|||||||
* @param recordingText 录音转写文本
|
* @param recordingText 录音转写文本
|
||||||
* @return 大模型返回的原始内容(一般是 JSON 字符串或结构化文本)
|
* @return 大模型返回的原始内容(一般是 JSON 字符串或结构化文本)
|
||||||
*/
|
*/
|
||||||
String generateSummaryByLLM(AudioAnalysisSceneType sceneType, String recordingText);
|
GenerationResult generateSummaryByLLM(AudioAnalysisSceneType sceneType, String recordingText);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 与 {@link #generateSummaryByLLM} 相同的提示词与场景逻辑,但通过本地 OpenAI 兼容接口调用大模型
|
* 与 {@link #generateSummaryByLLM} 相同的提示词与场景逻辑,但通过本地 OpenAI 兼容接口调用大模型
|
||||||
@@ -28,9 +30,9 @@ public interface IAudioTextAnalysisLlmService {
|
|||||||
*
|
*
|
||||||
* @param sceneType 业务场景类型
|
* @param sceneType 业务场景类型
|
||||||
* @param recordingText 录音转写文本
|
* @param recordingText 录音转写文本
|
||||||
* @return 大模型返回的原始内容
|
* @return 大模型返回的原始内容及 token 用量(若接口未返回 usage 则对应字段可能为 null)
|
||||||
*/
|
*/
|
||||||
String generateSummaryByLocalLLM(AudioAnalysisSceneType sceneType, String recordingText);
|
LocalLlmSummaryResult generateSummaryByLocalLLM(AudioAnalysisSceneType sceneType, String recordingText);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理完整的业务逻辑:调用大模型生成总结,解析JSON,保存数据
|
* 处理完整的业务逻辑:调用大模型生成总结,解析JSON,保存数据
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class AiQaCustomerAskServiceImpl implements IAiQaCustomerAskService {
|
|||||||
IAiQaItemService aiQaItemService,
|
IAiQaItemService aiQaItemService,
|
||||||
@Value("${ai.qa.local.chat-url:http://192.168.1.44:8000/v1/chat/completions}") String chatCompletionsUrl,
|
@Value("${ai.qa.local.chat-url:http://192.168.1.44:8000/v1/chat/completions}") String chatCompletionsUrl,
|
||||||
@Value("${ai.qa.local.default-model:Qwen2.5-7B-Instruct}") String configDefaultModel,
|
@Value("${ai.qa.local.default-model:Qwen2.5-7B-Instruct}") String configDefaultModel,
|
||||||
@Value("${ai.qa.local.max-tokens:512}") int configMaxTokens) {
|
@Value("${ai.qa.local.max-tokens:2048}") int configMaxTokens) {
|
||||||
this.restTemplate = restTemplate;
|
this.restTemplate = restTemplate;
|
||||||
this.objectMapper = objectMapper;
|
this.objectMapper = objectMapper;
|
||||||
this.aiQaMainService = aiQaMainService;
|
this.aiQaMainService = aiQaMainService;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.rj.service.impl;
|
|||||||
import com.alibaba.dashscope.aigc.generation.Generation;
|
import com.alibaba.dashscope.aigc.generation.Generation;
|
||||||
import com.alibaba.dashscope.aigc.generation.GenerationParam;
|
import com.alibaba.dashscope.aigc.generation.GenerationParam;
|
||||||
import com.alibaba.dashscope.aigc.generation.GenerationResult;
|
import com.alibaba.dashscope.aigc.generation.GenerationResult;
|
||||||
|
import com.alibaba.dashscope.aigc.generation.GenerationUsage;
|
||||||
import com.alibaba.dashscope.common.Message;
|
import com.alibaba.dashscope.common.Message;
|
||||||
import com.alibaba.dashscope.common.Role;
|
import com.alibaba.dashscope.common.Role;
|
||||||
import com.alibaba.dashscope.exception.InputRequiredException;
|
import com.alibaba.dashscope.exception.InputRequiredException;
|
||||||
@@ -12,6 +13,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.rj.common.AudioAnalysisSceneType;
|
import com.rj.common.AudioAnalysisSceneType;
|
||||||
|
import com.rj.common.LocalLlmSummaryResult;
|
||||||
import com.rj.entity.AudioManagement;
|
import com.rj.entity.AudioManagement;
|
||||||
import com.rj.entity.AudioTextAnalysisFurniture;
|
import com.rj.entity.AudioTextAnalysisFurniture;
|
||||||
import com.rj.entity.AudioTextAnalysisSop;
|
import com.rj.entity.AudioTextAnalysisSop;
|
||||||
@@ -24,6 +26,7 @@ import com.rj.service.ITodoItemService;
|
|||||||
import dev.langchain4j.model.chat.response.ChatResponse;
|
import dev.langchain4j.model.chat.response.ChatResponse;
|
||||||
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
|
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
|
||||||
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
|
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
|
||||||
|
import dev.langchain4j.model.output.TokenUsage;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@@ -50,6 +53,9 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmService {
|
public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmService {
|
||||||
|
|
||||||
|
/** LangChain4j 流式调用结束后的文本与(可选)服务端 usage */
|
||||||
|
private record LocalChatOutcome(String text, TokenUsage tokenUsage) {}
|
||||||
|
|
||||||
private static final Map<String, String> SYSTEM_PROMPT_CACHE = new ConcurrentHashMap<>();
|
private static final Map<String, String> SYSTEM_PROMPT_CACHE = new ConcurrentHashMap<>();
|
||||||
private static final Map<String, String> USER_PROMPT_CACHE = new ConcurrentHashMap<>();
|
private static final Map<String, String> USER_PROMPT_CACHE = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -75,7 +81,7 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
private String localDefaultModel;
|
private String localDefaultModel;
|
||||||
|
|
||||||
/** 单次补全上限(OpenAI max_tokens);与「模型总上下文 context-length」不是同一概念 */
|
/** 单次补全上限(OpenAI max_tokens);与「模型总上下文 context-length」不是同一概念 */
|
||||||
@Value("${ai.qa.local.max-tokens:512}")
|
@Value("${ai.qa.local.max-tokens:2048}")
|
||||||
private int localMaxTokens;
|
private int localMaxTokens;
|
||||||
|
|
||||||
/** 本地模型上下文长度(与推理侧 max context 一致,用于避免 input+max_tokens 超过上限;默认 16384) */
|
/** 本地模型上下文长度(与推理侧 max context 一致,用于避免 input+max_tokens 超过上限;默认 16384) */
|
||||||
@@ -117,7 +123,7 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generateSummaryByLLM(AudioAnalysisSceneType sceneType, String recordingText) {
|
public GenerationResult generateSummaryByLLM(AudioAnalysisSceneType sceneType, String recordingText) {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
log.info("开始调用大模型生成总结,场景: {}", sceneType);
|
log.info("开始调用大模型生成总结,场景: {}", sceneType);
|
||||||
|
|
||||||
@@ -145,8 +151,9 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
try {
|
try {
|
||||||
GenerationResult call = gen.call(param);
|
GenerationResult call = gen.call(param);
|
||||||
String rawContent = call.getOutput().getChoices().get(0).getMessage().getContent();
|
String rawContent = call.getOutput().getChoices().get(0).getMessage().getContent();
|
||||||
log.info("大模型生成总结完成,场景: {}, 结果长度: {}", sceneType, rawContent != null ? rawContent.length() : 0);
|
log.info("大模型生成总结完成,场景: {}, 输入长度:{},结果长度: {}", sceneType, recordingText.length(),rawContent != null ? rawContent.length() : 0);
|
||||||
return rawContent;
|
|
||||||
|
return call;
|
||||||
} catch (NoApiKeyException e) {
|
} catch (NoApiKeyException e) {
|
||||||
log.error("API密钥未配置", e);
|
log.error("API密钥未配置", e);
|
||||||
throw new RuntimeException("API密钥未配置: " + e.getMessage(), e);
|
throw new RuntimeException("API密钥未配置: " + e.getMessage(), e);
|
||||||
@@ -170,7 +177,7 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generateSummaryByLocalLLM(AudioAnalysisSceneType sceneType, String recordingText) {
|
public LocalLlmSummaryResult generateSummaryByLocalLLM(AudioAnalysisSceneType sceneType, String recordingText) {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
log.info("开始调用本地大模型生成总结,场景: {}", sceneType);
|
log.info("开始调用本地大模型生成总结,场景: {}", sceneType);
|
||||||
|
|
||||||
@@ -181,14 +188,25 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
int effectiveMaxTokens = computeEffectiveLocalMaxTokens(systemPrompt, userPrompt);
|
int effectiveMaxTokens = computeEffectiveLocalMaxTokens(systemPrompt, userPrompt);
|
||||||
String rawContent = callLocalOpenAiChatCompletionsByLangChain4j(
|
LocalChatOutcome outcome = callLocalOpenAiChatCompletionsByLangChain4j(
|
||||||
systemPrompt,
|
systemPrompt,
|
||||||
userPrompt,
|
userPrompt,
|
||||||
localDefaultModel,
|
localDefaultModel,
|
||||||
effectiveMaxTokens);
|
effectiveMaxTokens);
|
||||||
|
String rawContent = outcome.text();
|
||||||
|
TokenUsage usage = outcome.tokenUsage();
|
||||||
|
Integer total = usage != null ? usage.totalTokenCount() : null;
|
||||||
|
Integer input = usage != null ? usage.inputTokenCount() : null;
|
||||||
|
Integer output = usage != null ? usage.outputTokenCount() : null;
|
||||||
|
log.info(
|
||||||
|
"本地大模型生成总结完成,token花费,总token: {}, 输入token: {}, 输出token: {}, 输出token详情: {}",
|
||||||
|
total,
|
||||||
|
input,
|
||||||
|
output,
|
||||||
|
usage != null ? usage.toString() : "无");
|
||||||
log.info("本地大模型生成总结完成,场景: {}, 结果长度: {}",
|
log.info("本地大模型生成总结完成,场景: {}, 结果长度: {}",
|
||||||
sceneType, rawContent != null ? rawContent.length() : 0);
|
sceneType, rawContent != null ? rawContent.length() : 0);
|
||||||
return rawContent;
|
return new LocalLlmSummaryResult(rawContent, total, input, output);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("调用本地大模型生成总结失败, 场景: {}", sceneType, e);
|
log.error("调用本地大模型生成总结失败, 场景: {}", sceneType, e);
|
||||||
throw new RuntimeException("调用本地大模型失败: " + e.getMessage(), e);
|
throw new RuntimeException("调用本地大模型失败: " + e.getMessage(), e);
|
||||||
@@ -208,9 +226,9 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
/**
|
/**
|
||||||
* 与 {@link AiQaCustomerAskServiceImpl} 中非流式问答路径一致:LangChain4j + OpenAI 兼容接口,流式聚合为完整文本。
|
* 与 {@link AiQaCustomerAskServiceImpl} 中非流式问答路径一致:LangChain4j + OpenAI 兼容接口,流式聚合为完整文本。
|
||||||
*/
|
*/
|
||||||
private String callLocalOpenAiChatCompletionsByLangChain4j(
|
private LocalChatOutcome callLocalOpenAiChatCompletionsByLangChain4j(
|
||||||
String systemPrompt, String userContent, String model, int maxTokens) {
|
String systemPrompt, String userContent, String model, int maxTokens) {
|
||||||
log.info("音频分析本地 LLM:model={}, chatCompletionsUrl={}", model, chatCompletionsUrl);
|
log.info("音频分析本地 LLM:model={}, chatCompletionsUrl={}, maxTokens={}", model, chatCompletionsUrl,maxTokens);
|
||||||
String openAiBaseUrl = normalizeOpenAiBaseUrl(chatCompletionsUrl);
|
String openAiBaseUrl = normalizeOpenAiBaseUrl(chatCompletionsUrl);
|
||||||
OpenAiStreamingChatModel chatModel = OpenAiStreamingChatModel.builder()
|
OpenAiStreamingChatModel chatModel = OpenAiStreamingChatModel.builder()
|
||||||
.baseUrl(openAiBaseUrl)
|
.baseUrl(openAiBaseUrl)
|
||||||
@@ -223,6 +241,7 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
StringBuilder answerBuffer = new StringBuilder();
|
StringBuilder answerBuffer = new StringBuilder();
|
||||||
CountDownLatch done = new CountDownLatch(1);
|
CountDownLatch done = new CountDownLatch(1);
|
||||||
AtomicReference<Throwable> errorRef = new AtomicReference<>();
|
AtomicReference<Throwable> errorRef = new AtomicReference<>();
|
||||||
|
AtomicReference<TokenUsage> usageRef = new AtomicReference<>();
|
||||||
|
|
||||||
chatModel.chat(prompt, new StreamingChatResponseHandler() {
|
chatModel.chat(prompt, new StreamingChatResponseHandler() {
|
||||||
@Override
|
@Override
|
||||||
@@ -234,6 +253,9 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCompleteResponse(ChatResponse completeResponse) {
|
public void onCompleteResponse(ChatResponse completeResponse) {
|
||||||
|
if (completeResponse != null) {
|
||||||
|
usageRef.set(completeResponse.tokenUsage());
|
||||||
|
}
|
||||||
done.countDown();
|
done.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +284,7 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
if (answer.isEmpty()) {
|
if (answer.isEmpty()) {
|
||||||
throw new IllegalStateException("本地大模型流式调用返回空响应");
|
throw new IllegalStateException("本地大模型流式调用返回空响应");
|
||||||
}
|
}
|
||||||
return answer;
|
return new LocalChatOutcome(answer, usageRef.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String normalizeOpenAiBaseUrl(String rawUrl) {
|
private String normalizeOpenAiBaseUrl(String rawUrl) {
|
||||||
@@ -429,8 +451,11 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
String customerName,
|
String customerName,
|
||||||
String customerPhone) {
|
String customerPhone) {
|
||||||
try {
|
try {
|
||||||
|
GenerationResult generationResult = generateSummaryByLLM(sceneType, recordingText);
|
||||||
|
log.info("大模型生成总结完成,token花费,总token: {}, 输入token: {}, 输出token: {}, 输出token详情: {}",
|
||||||
|
generationResult.getUsage().getTotalTokens(),generationResult.getUsage().getInputTokens(),generationResult.getUsage().getOutputTokens(),generationResult.getUsage().getOutputTokensDetails());
|
||||||
// 1. 调用大模型生成总结
|
// 1. 调用大模型生成总结
|
||||||
String rawContent = generateSummaryByLLM(sceneType, recordingText);
|
String rawContent = generationResult.getOutput().getChoices().get(0).getMessage().getContent();
|
||||||
if (rawContent == null || rawContent.trim().isEmpty()) {
|
if (rawContent == null || rawContent.trim().isEmpty()) {
|
||||||
log.warn("大模型返回内容为空");
|
log.warn("大模型返回内容为空");
|
||||||
return null;
|
return null;
|
||||||
@@ -443,10 +468,11 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
// 3. 解析JSON并填充对象
|
// 3. 解析JSON并填充对象
|
||||||
applyStructuredResult(furniture, rawContent, parentId, ownerName, ownerPhone, customerName, customerPhone);
|
applyStructuredResult(furniture, rawContent, parentId, ownerName, ownerPhone, customerName, customerPhone);
|
||||||
|
|
||||||
// 4. 更新AudioManagement的summary字段
|
// 4. 更新AudioManagement的summary与 token 用量
|
||||||
AudioManagement audioManagement = new AudioManagement();
|
AudioManagement audioManagement = new AudioManagement();
|
||||||
audioManagement.setId(parentId);
|
audioManagement.setId(parentId);
|
||||||
audioManagement.setSummary(furniture.getSummarySentence());
|
audioManagement.setSummary(rawContent);
|
||||||
|
applyDashScopeUsageToAudioManagement(audioManagement, generationResult);
|
||||||
audioManagementService.updateById(audioManagement);
|
audioManagementService.updateById(audioManagement);
|
||||||
|
|
||||||
// 5. 保存或更新AudioTextAnalysisFurniture记录
|
// 5. 保存或更新AudioTextAnalysisFurniture记录
|
||||||
@@ -491,21 +517,47 @@ public class AudioTextAnalysisLlmServiceImpl implements IAudioTextAnalysisLlmSer
|
|||||||
String ownerPhone,
|
String ownerPhone,
|
||||||
String customerName,
|
String customerName,
|
||||||
String customerPhone) {
|
String customerPhone) {
|
||||||
// 1. 调用大模型生成总结
|
LocalLlmSummaryResult llmResult = generateSummaryByLocalLLM(sceneType, recordingText);
|
||||||
String rawContent = generateSummaryByLocalLLM(sceneType, recordingText);
|
String rawContent = llmResult.rawContent();
|
||||||
if (rawContent == null || rawContent.trim().isEmpty()) {
|
if (rawContent == null || rawContent.trim().isEmpty()) {
|
||||||
log.warn("大模型返回内容为空");
|
log.warn("大模型返回内容为空");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
AudioTextAnalysisFurniture furniture = new AudioTextAnalysisFurniture();
|
AudioTextAnalysisFurniture furniture = new AudioTextAnalysisFurniture();
|
||||||
// 4. 更新AudioManagement的summary字段
|
|
||||||
AudioManagement audioManagement = new AudioManagement();
|
AudioManagement audioManagement = new AudioManagement();
|
||||||
audioManagement.setId(parentId);
|
audioManagement.setId(parentId);
|
||||||
audioManagement.setSummary(rawContent);
|
audioManagement.setSummary(rawContent);
|
||||||
|
applyLocalLlmTokenCountsToAudioManagement(audioManagement, llmResult);
|
||||||
audioManagementService.updateById(audioManagement);
|
audioManagementService.updateById(audioManagement);
|
||||||
|
|
||||||
return furniture;
|
return furniture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyDashScopeUsageToAudioManagement(AudioManagement target, GenerationResult result) {
|
||||||
|
if (result == null || result.getUsage() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GenerationUsage usage = result.getUsage();
|
||||||
|
target.setTotalTokens(usage.getTotalTokens());
|
||||||
|
target.setInputTokens(usage.getInputTokens());
|
||||||
|
target.setOutputTokens(usage.getOutputTokens());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyLocalLlmTokenCountsToAudioManagement(AudioManagement target, LocalLlmSummaryResult result) {
|
||||||
|
if (result == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result.totalTokens() != null) {
|
||||||
|
target.setTotalTokens(result.totalTokens());
|
||||||
|
}
|
||||||
|
if (result.inputTokens() != null) {
|
||||||
|
target.setInputTokens(result.inputTokens());
|
||||||
|
}
|
||||||
|
if (result.outputTokens() != null) {
|
||||||
|
target.setOutputTokens(result.outputTokens());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析大模型返回的JSON结果并填充到AudioTextAnalysisFurniture对象
|
* 解析大模型返回的JSON结果并填充到AudioTextAnalysisFurniture对象
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
字段要求:
|
字段要求:
|
||||||
1. style_type:主题类型,仅可填「会议纪要」「课堂纪要」「面试纪要」。
|
1. style_type:主题类型,仅可填「会议纪要」「课堂纪要」「面试纪要」。
|
||||||
2. members:团队成员,描述 团队成员组成 ,比如: 经理,员工, 面试者,面试管,老师 , 重点反应每类人员的数量,姓名, 优点,贡献大小 等。
|
2. members:团队成员,描述 团队成员组成 ,比如: 经理,员工, 面试者,面试管,老师 , 重点反应每类人员的数量,姓名, 优点,贡献大小 等。
|
||||||
4. summary:一句话总结,应该简洁明了总结关键信息, 重点列举5到15个重点信息, 等关键信息, summary应该是树形结构,总共分3层 ,比如 summary是第一层 ,第二层 类似: summary1,summary2,summary3,summary[N] ,第三层 类似:summary1_1,summary1_2,summary1_3,summary1_[N]。
|
4. summary:一句话总结,生成的描述不少于200汉字,应该简洁明了总结关键信息, 重点列举5到15个重点信息, 等关键信息, summary应该是树形结构,总共分3层 ,比如 summary是第一层 ,第二层 类似: summary1,summary2,summary3,summary[N] ,第三层 类似:summary1_1,summary1_2,summary1_3,summary1_[N]。
|
||||||
5.summary1: 对summary 提供支持,summary1是对summary的详细解释的第一个理由, summary1是对summary深入分析的一部分 。
|
5.summary1: 对summary 提供支持,summary1是对summary的详细解释的第一个理由, summary1是对summary深入分析的一部分 。
|
||||||
6.summary1_1: 对summary1提供支持,summary1_1是对summary1的详细解释的第一个理由, summary1_1是对summary1深入分析的一部分 。
|
6.summary1_1: 对summary1提供支持,summary1_1是对summary1的详细解释的第一个理由, summary1_1是对summary1深入分析的一部分 。
|
||||||
7.summary1_[N]: 对summary1提供支持,summary1_[N]是对summary1的详细解释的第一个理由, summary1_[N]是对summary1深入分析的一部分 ,[N] 这里的N不能超过数字 10。
|
7.summary1_[N]: 对summary1提供支持,summary1_[N]是对summary1的详细解释的第一个理由, summary1_[N]是对summary1深入分析的一部分 ,[N] 这里的N不能超过数字 10。
|
||||||
|
|||||||
Reference in New Issue
Block a user