Corin1998 commited on
Commit
13499b7
·
verified ·
1 Parent(s): 9a9d6a7

Update ui.py

Browse files
Files changed (1) hide show
  1. ui.py +12 -12
ui.py CHANGED
@@ -22,13 +22,16 @@ from app.storage import (
22
  from app.bandit import ThompsonBandit
23
  from app.forecast import SeasonalityModel
24
  from app.compliance import rule_based_check, llm_check_and_fix
25
- from app.openai_client import openai_chat_json # ← ここを変更
26
-
27
 
28
  # 初期化
29
  init_db()
30
  _seasonality_cache: Dict[str, SeasonalityModel] = {}
31
 
 
 
 
 
32
  # JSONモード前提の厳格プロンプト
33
  GEN_SYSTEM = """
34
  あなたは日本語広告コピーのプロフェッショナルコピーライターです。
@@ -88,7 +91,6 @@ async def ui_generate(campaign_id: str, brand: str, product: str, target: str, t
88
  k=k_variants,
89
  )
90
 
91
- # ← JSONモードを使用
92
  data = await openai_chat_json(
93
  [
94
  {"role": "system", "content": GEN_SYSTEM},
@@ -98,13 +100,9 @@ async def ui_generate(campaign_id: str, brand: str, product: str, target: str, t
98
  max_tokens=1200,
99
  )
100
 
101
- # 許容: {"variants":[...] } もしくはリストそのもの(保険)
102
  items = data.get("variants", data if isinstance(data, list) else [])
103
- if not isinstance(items, list) or not items:
104
- raise gr.Error("JSON応答の 'variants' が取得できませんでした。もう一度お試しください。")
105
-
106
  rows = []
107
- for it in items[:k_variants]:
108
  headline = (it.get("headline") or "").strip()
109
  body = (it.get("body") or "").strip()
110
  text = f"{headline}\n{body}".strip()
@@ -134,7 +132,8 @@ async def ui_generate(campaign_id: str, brand: str, product: str, target: str, t
134
  "text": text,
135
  })
136
 
137
- df = pd.DataFrame(rows, columns=["variant_id", "status", "rejection_reason", "text"]) if rows else pd.DataFrame()
 
138
  return df
139
 
140
  def ui_serve(campaign_id: str, hour: int, segment: str):
@@ -180,7 +179,8 @@ def ui_report(campaign_id: str):
180
  "cvr": round(cvr, 4),
181
  "expected_value": round(ev, 6),
182
  })
183
- df = pd.DataFrame(rows, columns=["variant_id","impressions","clicks","conversions","ctr","cvr","expected_value"]) if rows else pd.DataFrame()
 
184
  return df
185
 
186
  def ui_check(text: str):
@@ -211,7 +211,7 @@ with gr.Blocks(title="AdCopy MAB Optimizer", fill_height=True) as demo:
211
  tone = gr.Textbox(label="トーン", value="エビデンス重視で安心感")
212
  ng_words = gr.Textbox(label="NGワード(改行区切り)", value="治る\n奇跡")
213
  btn_gen = gr.Button("広告案を生成&審査&保存")
214
- table_gen = gr.Dataframe(headers=["variant_id","status","rejection_reason","text"], interactive=False)
215
  btn_gen.click(ui_generate, [campaign_id, brand, product, target, tone, k_variants, ng_words, value_per_conv], [table_gen])
216
 
217
  with gr.Tab("2) Serve & Feedback"):
@@ -234,7 +234,7 @@ with gr.Blocks(title="AdCopy MAB Optimizer", fill_height=True) as demo:
234
  with gr.Tab("3) Report"):
235
  campaign_id3 = gr.Textbox(label="campaign_id", value="cmp-demo")
236
  btn_rep = gr.Button("更新")
237
- table_rep = gr.Dataframe(headers=["variant_id","impressions","clicks","conversions","ctr","cvr","expected_value"], interactive=False)
238
  btn_rep.click(ui_report, [campaign_id3], [table_rep])
239
 
240
  with gr.Tab("4) Compliance Check"):
 
22
  from app.bandit import ThompsonBandit
23
  from app.forecast import SeasonalityModel
24
  from app.compliance import rule_based_check, llm_check_and_fix
25
+ from app.openai_client import openai_chat_json
 
26
 
27
  # 初期化
28
  init_db()
29
  _seasonality_cache: Dict[str, SeasonalityModel] = {}
30
 
31
+ # 固定カラム(常にこの形で返す)
32
+ GENERATE_COLUMNS = ["variant_id", "status", "rejection_reason", "text"]
33
+ REPORT_COLUMNS = ["variant_id","impressions","clicks","conversions","ctr","cvr","expected_value"]
34
+
35
  # JSONモード前提の厳格プロンプト
36
  GEN_SYSTEM = """
37
  あなたは日本語広告コピーのプロフェッショナルコピーライターです。
 
91
  k=k_variants,
92
  )
93
 
 
94
  data = await openai_chat_json(
95
  [
96
  {"role": "system", "content": GEN_SYSTEM},
 
100
  max_tokens=1200,
101
  )
102
 
 
103
  items = data.get("variants", data if isinstance(data, list) else [])
 
 
 
104
  rows = []
105
+ for it in (items[:k_variants] if isinstance(items, list) else []):
106
  headline = (it.get("headline") or "").strip()
107
  body = (it.get("body") or "").strip()
108
  text = f"{headline}\n{body}".strip()
 
132
  "text": text,
133
  })
134
 
135
+ # 常に固定カラムで返す(空でもカラムを持つDataFrame
136
+ df = pd.DataFrame(rows, columns=GENERATE_COLUMNS)
137
  return df
138
 
139
  def ui_serve(campaign_id: str, hour: int, segment: str):
 
179
  "cvr": round(cvr, 4),
180
  "expected_value": round(ev, 6),
181
  })
182
+ # 常に固定カラムで返す(空でもカラムを持つDataFrame
183
+ df = pd.DataFrame(rows, columns=REPORT_COLUMNS)
184
  return df
185
 
186
  def ui_check(text: str):
 
211
  tone = gr.Textbox(label="トーン", value="エビデンス重視で安心感")
212
  ng_words = gr.Textbox(label="NGワード(改行区切り)", value="治る\n奇跡")
213
  btn_gen = gr.Button("広告案を生成&審査&保存")
214
+ table_gen = gr.Dataframe(headers=GENERATE_COLUMNS, interactive=False)
215
  btn_gen.click(ui_generate, [campaign_id, brand, product, target, tone, k_variants, ng_words, value_per_conv], [table_gen])
216
 
217
  with gr.Tab("2) Serve & Feedback"):
 
234
  with gr.Tab("3) Report"):
235
  campaign_id3 = gr.Textbox(label="campaign_id", value="cmp-demo")
236
  btn_rep = gr.Button("更新")
237
+ table_rep = gr.Dataframe(headers=REPORT_COLUMNS, interactive=False)
238
  btn_rep.click(ui_report, [campaign_id3], [table_rep])
239
 
240
  with gr.Tab("4) Compliance Check"):