LogicGoInfotechSpaces commited on
Commit
b3d55f3
·
1 Parent(s): 9ab0023

Add validation to prevent always 'keep' recommendations - override lazy OpenAI responses with intelligent analysis

Browse files
Files changed (1) hide show
  1. app/smart_recommendation.py +103 -10
app/smart_recommendation.py CHANGED
@@ -69,6 +69,25 @@ class SmartBudgetRecommender:
69
  recommended_budget = ai_result.get("recommended_budget")
70
  reason = ai_result.get("reason", f"AI recommendation for {category_name}")
71
  action = ai_result.get("action")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  print(f"✅ OpenAI recommendation for {category_name}: {recommended_budget} (action: {action})")
73
  else:
74
  # Fallback to rule-based recommendation if OpenAI fails
@@ -234,8 +253,16 @@ class SmartBudgetRecommender:
234
  ai_result = self._get_ai_recommendation(category_name, data, avg_expense)
235
  if ai_result and ai_result.get("recommended_budget"):
236
  recommended_budget = ai_result.get("recommended_budget")
237
- reason = ai_result.get("reason", f"AI recommendation for {category_name} based on your budget of Rs.{budget_amount:,.2f}")
238
  action = ai_result.get("action")
 
 
 
 
 
 
 
 
239
  print(f"✅ OpenAI recommendation for {category_name} (budget: {budget_amount}): {recommended_budget} (action: {action})")
240
  else:
241
  # Fallback to rule-based recommendation if OpenAI fails
@@ -404,7 +431,49 @@ class SmartBudgetRecommender:
404
  recommended_budget = ai_result.get("recommended_budget")
405
  reason = ai_result.get("reason", f"AI recommendation for {category_name}")
406
  action = ai_result.get("action")
407
- print(f"✅ OpenAI recommendation for {category_name}: {recommended_budget} (action: {action})")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
  else:
409
  # Fallback to rule-based recommendation if OpenAI fails
410
  recommended_budget = self._calculate_recommended_budget(avg_expense, data)
@@ -998,13 +1067,37 @@ class SmartBudgetRecommender:
998
  " - Accounts for category-specific factors\n"
999
  " - Includes appropriate buffer for variability and inflation\n"
1000
  " - Is justified by your analysis and knowledge\n\n"
1001
- "CRITICAL RULES:\n"
1002
- "- Do NOT always recommend 'keep' - use your intelligence to determine the best action\n"
1003
- "- If there's an upward trend, recommend INCREASE (don't ignore the trend)\n"
1004
- "- If there's high variation, recommend INCREASE to create buffer\n"
1005
- "- If spending is stable AND category is predictable, you can recommend KEEP with small buffer (5-10%)\n"
1006
- "- The recommended_budget should be SMART: Specific, Measurable, Achievable, Relevant, Time-bound\n"
1007
- "- Consider inflation: even stable spending should account for 2-5% annual inflation\n\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1008
  "Respond strictly as JSON with the following keys:\n"
1009
  '{ "recommended_budget": number, "action": "increase|decrease|keep", "reason": "string" }.\n\n'
1010
  "The 'reason' field is CRITICAL - it must:\n"
@@ -1032,7 +1125,7 @@ class SmartBudgetRecommender:
1032
  "messages": [
1033
  {"role": "user", "content": prompt}
1034
  ],
1035
- "temperature": 0.7, # Increased for more varied and creative recommendations
1036
  "response_format": {"type": "json_object"},
1037
  },
1038
  timeout=30,
 
69
  recommended_budget = ai_result.get("recommended_budget")
70
  reason = ai_result.get("reason", f"AI recommendation for {category_name}")
71
  action = ai_result.get("action")
72
+
73
+ # Validate OpenAI recommendation (same logic as in get_recommendation_for_category)
74
+ if recommended_budget == avg_expense and action == "keep":
75
+ std_dev = data.get("std_dev", 0.0)
76
+ monthly_values = data.get("monthly_values", [])
77
+ has_trend = len(monthly_values) > 1 and (monthly_values[-1] != monthly_values[0])
78
+
79
+ if has_trend or std_dev > avg_expense * 0.05:
80
+ # Override with intelligent recommendation
81
+ if has_trend and monthly_values[-1] > monthly_values[0]:
82
+ recommended_budget = avg_expense * 1.15
83
+ action = "increase"
84
+ elif std_dev > avg_expense * 0.05:
85
+ recommended_budget = avg_expense * 1.20
86
+ action = "increase"
87
+ else:
88
+ recommended_budget = avg_expense * 1.05
89
+ action = "increase"
90
+
91
  print(f"✅ OpenAI recommendation for {category_name}: {recommended_budget} (action: {action})")
92
  else:
93
  # Fallback to rule-based recommendation if OpenAI fails
 
253
  ai_result = self._get_ai_recommendation(category_name, data, avg_expense)
254
  if ai_result and ai_result.get("recommended_budget"):
255
  recommended_budget = ai_result.get("recommended_budget")
256
+ reason = ai_result.get("reason", f"AI recommendation for {category_name} based on your budget of {budget_amount:,.2f}")
257
  action = ai_result.get("action")
258
+
259
+ # Validate OpenAI recommendation
260
+ if recommended_budget == avg_expense and action == "keep":
261
+ # For budget_amount only, always add buffer
262
+ recommended_budget = avg_expense * 1.10
263
+ action = "increase"
264
+ reason = f"Based on your budget amount, I recommend increasing by 10% to {recommended_budget:,.0f} to account for variability and inflation."
265
+
266
  print(f"✅ OpenAI recommendation for {category_name} (budget: {budget_amount}): {recommended_budget} (action: {action})")
267
  else:
268
  # Fallback to rule-based recommendation if OpenAI fails
 
431
  recommended_budget = ai_result.get("recommended_budget")
432
  reason = ai_result.get("reason", f"AI recommendation for {category_name}")
433
  action = ai_result.get("action")
434
+
435
+ # VALIDATION: Check if OpenAI returned a lazy "keep" recommendation
436
+ # If recommended_budget equals avg_expense and action is "keep", validate if it's justified
437
+ monthly_values = data.get("monthly_values", [])
438
+ std_dev = data.get("std_dev", 0.0)
439
+
440
+ if recommended_budget == avg_expense and action == "keep":
441
+ # Check if this is justified
442
+ has_trend = False
443
+ if len(monthly_values) > 1:
444
+ # Check for upward trend
445
+ if monthly_values[-1] > monthly_values[0]:
446
+ has_trend = True
447
+ # Check for downward trend
448
+ elif monthly_values[-1] < monthly_values[0]:
449
+ has_trend = True
450
+
451
+ # If there's a trend or high variation, force a better recommendation
452
+ if has_trend or std_dev > avg_expense * 0.05:
453
+ print(f"⚠️ OpenAI returned 'keep' but data shows trend/variation - overriding with intelligent recommendation")
454
+ # Force increase with buffer
455
+ if has_trend and monthly_values[-1] > monthly_values[0]:
456
+ # Upward trend - increase by 15%
457
+ recommended_budget = avg_expense * 1.15
458
+ action = "increase"
459
+ reason = f"Your spending shows an upward trend. I recommend increasing your budget by 15% to {recommended_budget:,.0f} to accommodate this growth pattern and provide a buffer for continued increases."
460
+ elif has_trend and monthly_values[-1] < monthly_values[0]:
461
+ # Downward trend - decrease by 10%
462
+ recommended_budget = avg_expense * 0.90
463
+ action = "decrease"
464
+ reason = f"Your spending shows a downward trend. I recommend decreasing your budget by 10% to {recommended_budget:,.0f} to reflect this reduction pattern."
465
+ elif std_dev > avg_expense * 0.05:
466
+ # High variation - increase by 20%
467
+ recommended_budget = avg_expense * 1.20
468
+ action = "increase"
469
+ reason = f"Your spending shows high variability (std_dev: {std_dev:,.0f}). I recommend increasing your budget by 20% to {recommended_budget:,.0f} to create a safety buffer for unpredictable expenses."
470
+ else:
471
+ # Even for stable spending, add inflation buffer
472
+ recommended_budget = avg_expense * 1.05
473
+ action = "increase"
474
+ reason = f"While your spending is stable, I recommend adding a 5% buffer ({recommended_budget:,.0f}) to account for inflation and unexpected expenses."
475
+
476
+ print(f"✅ OpenAI recommendation for {category_name}: {recommended_budget:,.0f} (action: {action}, avg: {avg_expense:,.0f})")
477
  else:
478
  # Fallback to rule-based recommendation if OpenAI fails
479
  recommended_budget = self._calculate_recommended_budget(avg_expense, data)
 
1067
  " - Accounts for category-specific factors\n"
1068
  " - Includes appropriate buffer for variability and inflation\n"
1069
  " - Is justified by your analysis and knowledge\n\n"
1070
+ "CRITICAL RULES - READ CAREFULLY:\n"
1071
+ "⚠️ DO NOT ALWAYS RECOMMEND 'KEEP' - This is a common mistake. Analyze the data first!\n\n"
1072
+ "MANDATORY ANALYSIS STEPS:\n"
1073
+ "1. Look at the monthly_values array - is there a trend?\n"
1074
+ " - If values increase over time MUST recommend INCREASE\n"
1075
+ " - If values decrease over time MUST recommend DECREASE\n"
1076
+ " - Only if values are truly flat (all same) AND std_dev is very low → can recommend KEEP\n\n"
1077
+ "2. Check the std_dev (standard deviation):\n"
1078
+ " - If std_dev > 10% of average → MUST recommend INCREASE (high variability needs buffer)\n"
1079
+ " - If std_dev is moderate (5-10%) → Recommend INCREASE with 10-15% buffer\n"
1080
+ " - Only if std_dev < 3% AND no trend → can recommend KEEP with 5% buffer\n\n"
1081
+ "3. Consider inflation and best practices:\n"
1082
+ " - Even if spending is stable, inflation (2-5% annually) means you should INCREASE by at least 5-10%\n"
1083
+ " - Always add a buffer for unexpected expenses (5-15% depending on category)\n\n"
1084
+ "4. For single data point or new budgets:\n"
1085
+ " - MUST recommend INCREASE by 10-20% to account for variability\n"
1086
+ " - Never recommend KEEP for new/limited data\n\n"
1087
+ "DECISION TREE:\n"
1088
+ "- Upward trend? → INCREASE (10-25%)\n"
1089
+ "- Downward trend? → DECREASE (5-15%)\n"
1090
+ "- High variation (std_dev > 15%)? → INCREASE (20-30%)\n"
1091
+ "- Moderate variation (std_dev 5-15%)? → INCREASE (10-20%)\n"
1092
+ "- Stable with low variation (std_dev < 3%) AND no trend? → KEEP with 5-10% buffer\n"
1093
+ "- Single data point? → INCREASE (10-20%)\n\n"
1094
+ "⚠️ IMPORTANT: The recommended_budget MUST be different from average_expense in most cases.\n"
1095
+ "Only recommend the same amount if ALL of these are true:\n"
1096
+ "1. Spending is perfectly stable (all monthly values identical)\n"
1097
+ "2. Std_dev is very low (< 3% of average)\n"
1098
+ "3. No upward or downward trend\n"
1099
+ "4. Category is highly predictable\n"
1100
+ "Even then, add at least 5% buffer for inflation!\n\n"
1101
  "Respond strictly as JSON with the following keys:\n"
1102
  '{ "recommended_budget": number, "action": "increase|decrease|keep", "reason": "string" }.\n\n'
1103
  "The 'reason' field is CRITICAL - it must:\n"
 
1125
  "messages": [
1126
  {"role": "user", "content": prompt}
1127
  ],
1128
+ "temperature": 0.9, # Higher temperature for more varied and creative recommendations
1129
  "response_format": {"type": "json_object"},
1130
  },
1131
  timeout=30,