target fix
This commit is contained in:
@@ -85,9 +85,12 @@ public class AiTargetologistService {
|
||||
return """
|
||||
SYSTEM ROLE & ARCHITECTURE MANDATE
|
||||
You are "Antigravity", an enterprise-grade AI Targeting Orchestrator and Media Buying Architect. Your sole function is to process sanitized marketing strategies and ready-made media assets, compiling them into a highly structured, production-ready payload for Ads Platform APIs (Meta Graph API, Google Ads API, TikTok Marketing API).
|
||||
|
||||
|
||||
You DO NOT generate basic raw creatives from scratch if ready-made texts exist. You DO NOT alter the core strategy. You map inputs to rigid targeting parameters, establish A/B testing matrices, calculate budget pacing, and define algorithmic optimization rules.
|
||||
|
||||
|
||||
CRITICAL BUDGET RULE:
|
||||
The input context contains "campaign_daily_budget_usd_approx" and "campaign_total_budget_usd_approx". You MUST use EXACTLY these values for all budget fields in the output JSON (daily_budget_usd, campaign_daily_budget_usd). Distribute total budget proportionally across adsets but NEVER exceed the total. Do NOT invent or inflate budget numbers.
|
||||
|
||||
OUTPUT CONTRACT:
|
||||
Your output must be EXCLUSIVELY a valid JSON object. DO NOT wrap it in markdown block quotes. DO NOT include any natural language explanation, introductory text, or concluding remarks. Just raw valid JSON.
|
||||
The JSON keys must be strictly snake_case conforming to the supplied schema structure.
|
||||
@@ -101,10 +104,21 @@ public class AiTargetologistService {
|
||||
List<SocialMediaCredentials> credentials) throws JsonProcessingException {
|
||||
|
||||
// 1. Business Metrics Context
|
||||
double totalKzt = campaign.getBudget() != null && campaign.getBudget().getTotalBudget() != null
|
||||
? campaign.getBudget().getTotalBudget() : 0.0;
|
||||
double dailyKzt = campaign.getBudget() != null && campaign.getBudget().getDailyBudget() != null
|
||||
? campaign.getBudget().getDailyBudget() : (totalKzt / 30.0);
|
||||
// KZT to USD approximate rate for AI context (1 USD ~ 470 KZT)
|
||||
double totalUsd = Math.round(totalKzt / 470.0 * 100.0) / 100.0;
|
||||
double dailyUsd = Math.round(dailyKzt / 470.0 * 100.0) / 100.0;
|
||||
|
||||
Map<String, Object> businessMetrics = new HashMap<>();
|
||||
businessMetrics.put("target_objective", campaign.getObjective() != null ? campaign.getObjective().name() : "TRAFFIC");
|
||||
businessMetrics.put("campaign_daily_budget_kzt", campaign.getBudget() != null ? campaign.getBudget().getDailyBudget() : 0);
|
||||
businessMetrics.put("campaign_total_budget_kzt", campaign.getBudget() != null ? campaign.getBudget().getTotalBudget() : 0);
|
||||
businessMetrics.put("campaign_daily_budget_kzt", dailyKzt);
|
||||
businessMetrics.put("campaign_total_budget_kzt", totalKzt);
|
||||
businessMetrics.put("campaign_daily_budget_usd_approx", dailyUsd);
|
||||
businessMetrics.put("campaign_total_budget_usd_approx", totalUsd);
|
||||
businessMetrics.put("budget_currency_note", "IMPORTANT: All budget fields in output JSON (daily_budget_usd, campaign_daily_budget_usd) MUST use the USD amounts provided above. Do NOT invent new budget amounts.");
|
||||
businessMetrics.put("target_platforms", campaign.getPlatforms());
|
||||
|
||||
// 2. Extracted Media Assets (Texts with hashtags)
|
||||
|
||||
@@ -66,6 +66,9 @@ public class TargetingCampaignService {
|
||||
if (req.getTotalBudgetKzt() == null || req.getTotalBudgetKzt() <= 0) {
|
||||
throw new ValidationException("totalBudgetKzt", req.getTotalBudgetKzt(), "Бюджет должен быть больше 0");
|
||||
}
|
||||
if (req.getTotalBudgetKzt() > 500_000_000) {
|
||||
throw new ValidationException("totalBudgetKzt", req.getTotalBudgetKzt(), "Бюджет не может превышать 500,000,000 KZT");
|
||||
}
|
||||
|
||||
TargetingRecommendationDto recommendation =
|
||||
aiTargetingSystemService.generateLinkedRecommendation(strategy, analysis);
|
||||
@@ -77,6 +80,11 @@ public class TargetingCampaignService {
|
||||
LocalDateTime startDate = req.getStartDate() != null ? req.getStartDate() : LocalDateTime.now();
|
||||
LocalDateTime endDate = req.getEndDate() != null ? req.getEndDate() : startDate.plusDays(durationDays);
|
||||
|
||||
// Если дневной бюджет не передан — вычисляем автоматически
|
||||
if (req.getDailyBudgetKzt() == null || req.getDailyBudgetKzt() <= 0) {
|
||||
req.setDailyBudgetKzt(Math.round(req.getTotalBudgetKzt() / durationDays * 100.0) / 100.0);
|
||||
}
|
||||
|
||||
TargetingAudienceProfile audienceProfile =
|
||||
buildAudienceProfile(recommendation, req.getAudienceOverride());
|
||||
|
||||
@@ -87,6 +95,32 @@ public class TargetingCampaignService {
|
||||
audienceProfile.setEstimatedReachMax(RangeParser.extractMax(reach));
|
||||
}
|
||||
|
||||
// Перезаписываем бюджетные поля AI-рекомендации реальными значениями пользователя,
|
||||
// чтобы AI не показывал фантастические миллиарды
|
||||
if (recommendation != null) {
|
||||
kz.konturai.parser.dto.targeting.TargetingBudgetDto realBudget =
|
||||
kz.konturai.parser.dto.targeting.TargetingBudgetDto.builder()
|
||||
.dailyBudget(String.format("%.0f KZT", req.getDailyBudgetKzt()))
|
||||
.monthlyBudget(String.format("%.0f KZT", req.getTotalBudgetKzt()))
|
||||
.bidStrategy(recommendation.getBudgetRecommendation() != null
|
||||
? recommendation.getBudgetRecommendation().getBidStrategy()
|
||||
: "LOWEST_COST_WITHOUT_CAP")
|
||||
.rationale(recommendation.getBudgetRecommendation() != null
|
||||
? recommendation.getBudgetRecommendation().getRationale()
|
||||
: null)
|
||||
.estimatedCpc(recommendation.getBudgetRecommendation() != null
|
||||
? recommendation.getBudgetRecommendation().getEstimatedCpc()
|
||||
: null)
|
||||
.estimatedCpl(recommendation.getBudgetRecommendation() != null
|
||||
? recommendation.getBudgetRecommendation().getEstimatedCpl()
|
||||
: null)
|
||||
.estimatedDailyReach(recommendation.getBudgetRecommendation() != null
|
||||
? recommendation.getBudgetRecommendation().getEstimatedDailyReach()
|
||||
: null)
|
||||
.build();
|
||||
recommendation.setBudgetRecommendation(realBudget);
|
||||
}
|
||||
|
||||
TargetingAIAnalysisResult aiAnalysisResult =
|
||||
buildAiAnalysisResult(strategy, analysis, recommendation);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user