From 7983a4b352c3888f6c7248b79591ffafeda8d870 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 28 Dec 2025 00:28:03 +0500 Subject: [PATCH] . --- .../service/MarketingAnalysisService.java | 64 +++++++++++++++---- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java b/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java index b14db3c..91355f3 100644 --- a/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java +++ b/src/main/java/kz/konturai/parser/service/MarketingAnalysisService.java @@ -759,6 +759,15 @@ public class MarketingAnalysisService { logger.error("Error in audience analysis: {}", e.getMessage(), e); } + // Пауза 15 секунд между вызовами для предотвращения 429 ошибок + try { + logger.info("Waiting 15 seconds before next analysis block to prevent rate limits"); + Thread.sleep(15000); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted during delay between analysis blocks"); + } + try { logger.info("Starting competitor analysis generation"); Map competitorAnalysis = getCompetitorAnalysis(request); @@ -772,6 +781,15 @@ public class MarketingAnalysisService { logger.error("Error in competitor analysis: {}", e.getMessage(), e); } + // Пауза 15 секунд между вызовами для предотвращения 429 ошибок + try { + logger.info("Waiting 15 seconds before next analysis block to prevent rate limits"); + Thread.sleep(15000); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted during delay between analysis blocks"); + } + try { logger.info("Starting seasonality and market analysis generation"); Map seasonalityAndMarket = getSeasonalityAndMarket(request); @@ -785,6 +803,15 @@ public class MarketingAnalysisService { logger.error("Error in seasonality analysis: {}", e.getMessage(), e); } + // Пауза 15 секунд между вызовами для предотвращения 429 ошибок + try { + logger.info("Waiting 15 seconds before next analysis block to prevent rate limits"); + Thread.sleep(15000); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted during delay between analysis blocks"); + } + try { logger.info("Starting strategy and funnel analysis generation"); Map strategyAndFunnel = getStrategyAndFunnel(request); @@ -954,8 +981,10 @@ public class MarketingAnalysisService { String prompt = promptBuilder.toString(); logger.debug("getAudienceAnalysis: Generating audience analysis with detailed prompt (length: {} chars)", prompt.length()); - logger.info("getAudienceAnalysis: Calling OpenAI API for audience analysis"); - String jsonResponse = openAIAnalyticsService.generateWithInstruction(context, prompt, "ru"); + logger.info( + "getAudienceAnalysis: Calling OpenAI API for audience analysis using miniModelName (gpt-4o-mini)"); + String jsonResponse = openAIAnalyticsService.generateWithInstructionWithModel(context, prompt, "ru", + miniModelName); logger.debug("getAudienceAnalysis: OpenAI response received. Length: {} chars", jsonResponse != null ? jsonResponse.length() : 0); @@ -1154,8 +1183,10 @@ public class MarketingAnalysisService { logger.debug( "getCompetitorAnalysis: Generating competitor analysis with detailed prompt (length: {} chars)", prompt.length()); - logger.info("getCompetitorAnalysis: Calling OpenAI API for competitor analysis"); - String jsonResponse = openAIAnalyticsService.generateWithInstruction(context, prompt, "ru"); + logger.info( + "getCompetitorAnalysis: Calling OpenAI API for competitor analysis using miniModelName (gpt-4o-mini)"); + String jsonResponse = openAIAnalyticsService.generateWithInstructionWithModel(context, prompt, "ru", + miniModelName); logger.debug("getCompetitorAnalysis: OpenAI response received. Length: {} chars", jsonResponse != null ? jsonResponse.length() : 0); @@ -1333,9 +1364,10 @@ public class MarketingAnalysisService { try { attempt++; logger.info( - "getSeasonalityAndMarket: Calling OpenAI API for seasonality and market analysis (attempt {}/{})", + "getSeasonalityAndMarket: Calling OpenAI API for seasonality and market analysis (attempt {}/{}) using miniModelName (gpt-4o-mini)", attempt, MAX_RETRY_ATTEMPTS); - String jsonResponse = openAIAnalyticsService.generateWithInstruction(context, prompt, "ru"); + String jsonResponse = openAIAnalyticsService.generateWithInstructionWithModel(context, prompt, "ru", + miniModelName); logger.debug("getSeasonalityAndMarket: OpenAI response received. Length: {} chars", jsonResponse != null ? jsonResponse.length() : 0); @@ -1506,9 +1538,10 @@ public class MarketingAnalysisService { try { attempt++; logger.info( - "getStrategyAndFunnel: Calling OpenAI API for strategy and funnel analysis (attempt {}/{})", + "getStrategyAndFunnel: Calling OpenAI API for strategy and funnel analysis (attempt {}/{}) using miniModelName (gpt-4o-mini)", attempt, MAX_RETRY_ATTEMPTS); - String jsonResponse = openAIAnalyticsService.generateWithInstruction(context, prompt, "ru"); + String jsonResponse = openAIAnalyticsService.generateWithInstructionWithModel(context, prompt, "ru", + miniModelName); logger.debug("getStrategyAndFunnel: OpenAI response received. Length: {} chars", jsonResponse != null ? jsonResponse.length() : 0); @@ -1713,11 +1746,16 @@ public class MarketingAnalysisService { // Exponential backoff for 429 errors or empty responses if (i < maxAttempts) { long delayMs; - if (is429Error || (last == null && i < maxAttempts)) { - // Exponential backoff: 2s, 4s, 8s - delayMs = (long) Math.pow(2, i) * 1000; - logger.info("Waiting {}ms before retry (attempt {}/{}) for section '{}' due to {}", - delayMs, i, maxAttempts, sectionId, is429Error ? "429 rate limit" : "empty response"); + if (is429Error) { + // Увеличенные задержки для 429 ошибок: 10s, 20s (приоритет стабильности) + delayMs = i * 10000; // 10 секунд для первой попытки, 20 секунд для второй + logger.info("Waiting {}ms before retry (attempt {}/{}) for section '{}' due to 429 rate limit", + delayMs, i, maxAttempts, sectionId); + } else if (last == null && i < maxAttempts) { + // Для пустых ответов используем стандартную экспоненциальную задержку + delayMs = (long) Math.pow(2, i) * 1000; // 2s, 4s, 8s + logger.info("Waiting {}ms before retry (attempt {}/{}) for section '{}' due to empty response", + delayMs, i, maxAttempts, sectionId); } else { // Small delay for other errors delayMs = 250L;