ps1811 commited on
Commit
46a086b
·
1 Parent(s): 2976301

Prompts updated. llm finetuned model used

Browse files
app/ads1/ads_analyst.py CHANGED
@@ -3,6 +3,7 @@ import json
3
  import pandas as pd
4
 
5
  from app.recs.generate import TARGET_CPL, generate_explanation, is_bad_llm_output
 
6
 
7
  # -------------------------
8
  # 1. DATA BUILDERS
@@ -133,11 +134,7 @@ def build_ads_analyst_context(dfs: dict, campaign_name: str | None = None) -> di
133
  def build_ads_analyst_prompt(context: dict) -> str:
134
  payload = json.dumps(context, indent=2, default=str)
135
  name = context.get("campaign_name", "this campaign")
136
- return (
137
- f"Write 3 to 5 bullet points of actionable Google Ads insights for {name}.\n"
138
- "Use simple language. One insight per bullet. Start each line with '- '. No intro sentence.\n\n"
139
- f"Data (JSON):\n{payload}"
140
- )
141
 
142
 
143
  def rule_based_insights(context: dict) -> str:
 
3
  import pandas as pd
4
 
5
  from app.recs.generate import TARGET_CPL, generate_explanation, is_bad_llm_output
6
+ from app.ads1.prompt_templates import ads_analyst_prompt
7
 
8
  # -------------------------
9
  # 1. DATA BUILDERS
 
134
  def build_ads_analyst_prompt(context: dict) -> str:
135
  payload = json.dumps(context, indent=2, default=str)
136
  name = context.get("campaign_name", "this campaign")
137
+ return ads_analyst_prompt(name, payload)
 
 
 
 
138
 
139
 
140
  def rule_based_insights(context: dict) -> str:
app/ads1/budget_optimizer.py CHANGED
@@ -1,6 +1,4 @@
1
- import json
2
  import pandas as pd
3
- from app.recs.generate import generate_explanation, is_bad_llm_output
4
 
5
  def build_budget_features(df: pd.DataFrame) -> pd.DataFrame:
6
  df = df.copy()
@@ -75,18 +73,6 @@ def build_budget_optimizer_context(dfs: dict, campaign_name: str | None = None):
75
  "budget_actions": action_rows.round(2).to_dict("records")
76
  }
77
 
78
- def build_budget_optimizer_prompt(context: dict) -> str:
79
- payload = json.dumps(context, indent=2, default=str)
80
- name = context.get("campaign_name", "this account")
81
-
82
- return (
83
- f"Write 3 to 5 bullet points of actionable budget optimization insights for {name}.\n"
84
- "Use the budget_actions list only. Each bullet must mention the campaign or keyword name, the budget action, and the evidence.\n"
85
- "Use simple language. One self-contained budget action per bullet. Start each line with '- '. No intro sentence. Do not quote JSON values by themselves.\n\n"
86
- f"Data (JSON):\n{payload}"
87
- )
88
-
89
-
90
  def rule_based_budget_actions(context: dict) -> str:
91
  rows = context.get("budget_actions", [])
92
  if not rows:
@@ -124,18 +110,5 @@ def run_budget_optimizer(dfs: dict, campaign_name: str | None = None) -> str:
124
  return "⚠️ No campaign data available."
125
 
126
  context = build_budget_optimizer_context(dfs, campaign_name)
127
-
128
  print("🧠 [budget_optimizer] context built", flush=True)
129
-
130
- prompt = build_budget_optimizer_prompt(context)
131
-
132
- print("✍️ [budget_optimizer] prompt built", flush=True)
133
-
134
- result = generate_explanation(prompt)
135
-
136
- if is_bad_llm_output(result) or not result.strip().startswith("-") or result.count('"') >= 4:
137
- print("⚠️ [budget_optimizer] fallback triggered", flush=True)
138
- return rule_based_budget_actions(context)
139
-
140
- print("📤 [budget_optimizer] result received", flush=True)
141
- return result
 
 
1
  import pandas as pd
 
2
 
3
  def build_budget_features(df: pd.DataFrame) -> pd.DataFrame:
4
  df = df.copy()
 
73
  "budget_actions": action_rows.round(2).to_dict("records")
74
  }
75
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  def rule_based_budget_actions(context: dict) -> str:
77
  rows = context.get("budget_actions", [])
78
  if not rows:
 
110
  return "⚠️ No campaign data available."
111
 
112
  context = build_budget_optimizer_context(dfs, campaign_name)
 
113
  print("🧠 [budget_optimizer] context built", flush=True)
114
+ return rule_based_budget_actions(context)
 
 
 
 
 
 
 
 
 
 
 
 
app/ads1/growth_finder.py CHANGED
@@ -1,6 +1,4 @@
1
- import json
2
  import pandas as pd
3
- from app.recs.generate import generate_explanation, is_bad_llm_output
4
 
5
  def build_growth_finder_features(df: pd.DataFrame) -> pd.DataFrame:
6
  df = df.copy()
@@ -60,19 +58,6 @@ def build_growth_finder_context(dfs: dict, campaign_name: str | None = None):
60
  "growth_candidates": df[keep_cols].round(2).to_dict("records")
61
  }
62
 
63
- def build_growth_finder_prompt(context: dict) -> str:
64
- payload = json.dumps(context, indent=2, default=str)
65
- name = context.get("campaign_name", "this account")
66
-
67
- return (
68
- f"Write 3 to 5 bullet points of actionable growth opportunities for {name}.\n"
69
- "Use the growth_candidates list only. Suggest ways to scale winners, expand related intent, or increase budget on efficient areas.\n"
70
- "Each bullet must mention the keyword, the growth action, and the evidence. Do not list weak keywords or diagnose poor performance.\n"
71
- "Use simple language. One self-contained growth opportunity per bullet. Start each line with '- '. No intro sentence. Do not quote JSON values by themselves.\n\n"
72
- f"Data (JSON):\n{payload}"
73
- )
74
-
75
-
76
  def rule_based_growth_actions(context: dict) -> str:
77
  rows = context.get("growth_candidates", [])
78
  if not rows:
@@ -102,20 +87,5 @@ def run_growth_finder(dfs: dict, campaign_name: str | None = None) -> str:
102
  return "⚠️ No keyword data available."
103
 
104
  context = build_growth_finder_context(dfs, campaign_name)
105
- if not context.get("growth_candidates"):
106
- return rule_based_growth_actions(context)
107
-
108
  print("🧠 [growth_finder] context built", flush=True)
109
-
110
- prompt = build_growth_finder_prompt(context)
111
-
112
- print("✍️ [growth_finder] prompt built", flush=True)
113
-
114
- result = generate_explanation(prompt)
115
-
116
- if is_bad_llm_output(result) or not result.strip().startswith("-") or result.count('"') >= 4:
117
- print("⚠️ [growth_finder] fallback triggered", flush=True)
118
- return rule_based_growth_actions(context)
119
-
120
- print("📤 [growth_finder] result received", flush=True)
121
- return result
 
 
1
  import pandas as pd
 
2
 
3
  def build_growth_finder_features(df: pd.DataFrame) -> pd.DataFrame:
4
  df = df.copy()
 
58
  "growth_candidates": df[keep_cols].round(2).to_dict("records")
59
  }
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  def rule_based_growth_actions(context: dict) -> str:
62
  rows = context.get("growth_candidates", [])
63
  if not rows:
 
87
  return "⚠️ No keyword data available."
88
 
89
  context = build_growth_finder_context(dfs, campaign_name)
 
 
 
90
  print("🧠 [growth_finder] context built", flush=True)
91
+ return rule_based_growth_actions(context)
 
 
 
 
 
 
 
 
 
 
 
 
app/ads1/keyword_inspector.py CHANGED
@@ -2,6 +2,7 @@ import json
2
  import pandas as pd
3
 
4
  from app.recs.generate import generate_explanation, is_bad_llm_output
 
5
 
6
 
7
  # -------------------------
@@ -27,12 +28,7 @@ def build_keyword_features(df: pd.DataFrame) -> pd.DataFrame:
27
  def build_keyword_prompt(context: dict) -> str:
28
  payload = json.dumps(context, indent=2, default=str)
29
 
30
- return (
31
- "Write 3 to 5 bullet points of actionable keyword performance insights.\n"
32
- "Classify individual keywords as winning, wasted spend, or scaling opportunities using CTR, cost, and conversions.\n"
33
- "Use simple language. One insight per bullet. Start each line with '- '. No intro sentence.\n\n"
34
- f"Data (JSON):\n{payload}"
35
- )
36
  # -------------------------
37
  # Main runner
38
  # -------------------------
 
2
  import pandas as pd
3
 
4
  from app.recs.generate import generate_explanation, is_bad_llm_output
5
+ from app.ads1.prompt_templates import keyword_inspector_prompt
6
 
7
 
8
  # -------------------------
 
28
  def build_keyword_prompt(context: dict) -> str:
29
  payload = json.dumps(context, indent=2, default=str)
30
 
31
+ return keyword_inspector_prompt(payload)
 
 
 
 
 
32
  # -------------------------
33
  # Main runner
34
  # -------------------------
app/ads1/prompt_templates.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def ads_analyst_prompt(name: str, payload: str) -> str:
2
+ return (
3
+ f"Write 3 to 5 bullet points of actionable Google Ads insights for {name}.\n"
4
+ "Use simple language. One insight per bullet. Start each line with '- '. No intro sentence.\n\n"
5
+ f"Data (JSON):\n{payload}"
6
+ )
7
+
8
+
9
+ def keyword_inspector_prompt(payload: str) -> str:
10
+ return (
11
+ "Write 3 to 5 bullet points of actionable keyword performance insights.\n"
12
+ "Classify individual keywords as winning, wasted spend, or scaling opportunities using CTR, cost, and conversions.\n"
13
+ "Use simple language. One insight per bullet. Start each line with '- '. No intro sentence.\n\n"
14
+ f"Data (JSON):\n{payload}"
15
+ )
16
+
17
+
18
+ def search_term_cleaner_prompt(name: str, payload: str) -> str:
19
+ return (
20
+ f"Write 3 to 5 bullet points of actionable search term cleanup insights for {name}.\n"
21
+ "Classify search terms as wasted spend, high intent, scale, or negative keyword candidates using total_cost, clicks, conversions, CPA, CVR, and CPC.\n"
22
+ "Use simple language. One search term action per bullet. Start each line with '- '. No intro sentence.\n\n"
23
+ f"Data (JSON):\n{payload}"
24
+ )
25
+
app/ads1/search_term_optimizer.py CHANGED
@@ -1,6 +1,7 @@
1
  import json
2
  import pandas as pd
3
  from app.recs.generate import generate_explanation, is_bad_llm_output
 
4
 
5
  # -------------------------
6
  # Feature engineering only
@@ -65,12 +66,7 @@ def build_search_optimizer_prompt(context: dict) -> str:
65
  payload = json.dumps(context, indent=2, default=str)
66
  name = context.get("campaign_name", "this campaign")
67
 
68
- return (
69
- f"Write 3 to 5 bullet points of actionable search term cleanup insights for {name}.\n"
70
- "Use the search_terms list only. total_cost is total spend for that search term; cpc is cost per click.\n"
71
- "Each bullet must mention the search term, the action, and the evidence. Use simple language. Start each line with '- '. No intro sentence.\n\n"
72
- f"Data (JSON):\n{payload}"
73
- )
74
 
75
 
76
  # -------------------------
 
1
  import json
2
  import pandas as pd
3
  from app.recs.generate import generate_explanation, is_bad_llm_output
4
+ from app.ads1.prompt_templates import search_term_cleaner_prompt
5
 
6
  # -------------------------
7
  # Feature engineering only
 
66
  payload = json.dumps(context, indent=2, default=str)
67
  name = context.get("campaign_name", "this campaign")
68
 
69
+ return search_term_cleaner_prompt(name, payload)
 
 
 
 
 
70
 
71
 
72
  # -------------------------
app/models/llm.py CHANGED
@@ -6,8 +6,11 @@ from typing import Any
6
 
7
  from huggingface_hub import hf_hub_download
8
 
9
- HF_REPO = os.getenv("LLAMA_HF_REPO", "openbmb/MiniCPM5-1B-GGUF")
10
- HF_FILENAME = os.getenv("LLAMA_HF_FILENAME", "MiniCPM5-1B-Q4_K_M.gguf")
 
 
 
11
 
12
  _model: Any = None
13
  _init_lock = threading.Lock()
 
6
 
7
  from huggingface_hub import hf_hub_download
8
 
9
+ # HF_REPO = os.getenv("LLAMA_HF_REPO", "openbmb/MiniCPM5-1B-GGUF")
10
+ # HF_FILENAME = os.getenv("LLAMA_HF_FILENAME", "MiniCPM5-1B-Q4_K_M.gguf")
11
+
12
+ LLAMA_HF_REPO = os.getenv("LLAMA_HF_REPO", "ps1811/advisor-minicpm-finetuned-gguf")
13
+ LLAMA_HF_FILENAME= os.getenv("LLAMA_HF_FILENAME", "advisor-minicpm-q4_k_m.gguf")
14
 
15
  _model: Any = None
16
  _init_lock = threading.Lock()