Kaynağa Gözat

更改评分提示语
增加超出最大输出token提示

liyanbo 3 hafta önce
ebeveyn
işleme
9cf78f4650

+ 27 - 2
byzs-web/src/main/java/cn/iocoder/byzs/module/web/service/ai/WebQSAiServiceImpl.java

@@ -59,6 +59,7 @@ import java.util.ArrayList;
 import java.util.Base64;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.byzs.framework.common.pojo.CommonResult.error;
@@ -71,7 +72,7 @@ import static cn.iocoder.byzs.module.ai.enums.ErrorCodeConstants.CHAT_CONVERSATI
 @Service
 @Validated
 @Slf4j
-public class WebQSAiServiceImpl {
+public class  WebQSAiServiceImpl {
 
     // DeepSeek API URL 固定
     private static final String DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions";
@@ -150,6 +151,9 @@ public class WebQSAiServiceImpl {
 
         StringBuilder answer = new StringBuilder();
         AtomicBoolean serviceClosed = new AtomicBoolean(false);
+        AtomicBoolean tokenLimitWarningSent = new AtomicBoolean(false);
+        AtomicInteger outputTokens = new AtomicInteger();
+        AtomicInteger reasoningTokens = new AtomicInteger();
 
         return Flux.<CommonResult<AiChatMessageSendRespVO>>create(sink -> {
                     try {
@@ -183,6 +187,10 @@ public class WebQSAiServiceImpl {
                                         String data = line.substring(6).trim();
 
                                         if ("[DONE]".equals(data)) {
+                                            log.info("[QS评分-Token用量][conversationId({}) model({}) " +
+                                                            "outputTokens({}) reasoningTokens({})]",
+                                                    conversation.getId(), model.getModel(), outputTokens.get(),
+                                                    reasoningTokens.get());
                                             TenantUtils.executeIgnore(() ->
                                                     chatMessageMapper.updateById(
                                                             new AiChatMessageDO().setId(assistantMessage.getId())
@@ -193,6 +201,12 @@ public class WebQSAiServiceImpl {
 
                                         try {
                                             JsonNode chunk = objectMapper.readTree(data);
+                                            JsonNode usage = chunk.path("usage");
+                                            if (!usage.isMissingNode() && !usage.isNull()) {
+                                                outputTokens.set(usage.path("completion_tokens").asInt(0));
+                                                reasoningTokens.set(usage.path("completion_tokens_details")
+                                                        .path("reasoning_tokens").asInt(0));
+                                            }
                                             JsonNode choices = chunk.path("choices");
                                             if (choices.isEmpty()) {
                                                 return;
@@ -227,6 +241,17 @@ public class WebQSAiServiceImpl {
                                                 }
                                             }
 
+                                            JsonNode finishReasonNode = choices.path(0).path("finish_reason");
+                                            if (!finishReasonNode.isMissingNode() && !finishReasonNode.isNull()
+                                                    && "length".equals(finishReasonNode.asText())
+                                                    && tokenLimitWarningSent.compareAndSet(false, true)) {
+                                                String tokenLimitMessage = "\n\n本次评分内容较长,模型输出已达到最大 Token " +
+                                                        "限制,当前结果可能不完整。请减少单次评分人数、缩短材料或重新发起评分。";
+                                                answer.append(tokenLimitMessage);
+                                                sink.next(success(createTextResponse(userMessage, assistantMessage,
+                                                        tokenLimitMessage)));
+                                            }
+
                                         } catch (Exception e) {
                                             log.warn("解析 DeepSeek 响应失败: {}, line: {}", e.getMessage(), line);
                                         }
@@ -396,7 +421,7 @@ public class WebQSAiServiceImpl {
         // 组合最终内容
         StringBuilder fullContent = new StringBuilder();
         if (extractedText.length() > 0) {
-            fullContent.append("【附件内容】\n").append(extractedText);
+            fullContent.append("【录音文字稿:附件内容开始】\n").append(extractedText).append("【附件内容结束】\n");
         }
         if (StrUtil.isNotBlank(userContent)) {
             if (fullContent.length() > 0) {