Spaces:
Sleeping
Sleeping
Update ui.py
Browse files
ui.py
CHANGED
|
@@ -22,15 +22,30 @@ 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
|
|
|
|
| 26 |
|
| 27 |
# 初期化
|
| 28 |
init_db()
|
| 29 |
_seasonality_cache: Dict[str, SeasonalityModel] = {}
|
| 30 |
|
|
|
|
| 31 |
GEN_SYSTEM = """
|
| 32 |
あなたは日本語広告コピーのプロフェッショナルコピーライターです。
|
| 33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
"""
|
| 35 |
|
| 36 |
GEN_USER_TEMPLATE = """
|
|
@@ -40,10 +55,10 @@ GEN_USER_TEMPLATE = """
|
|
| 40 |
トーン: {tone}
|
| 41 |
制約: {constraints}
|
| 42 |
生成本数: {k}
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
-
|
| 46 |
-
-
|
| 47 |
"""
|
| 48 |
|
| 49 |
def _seasonal(campaign_id: str) -> SeasonalityModel:
|
|
@@ -73,16 +88,20 @@ async def ui_generate(campaign_id: str, brand: str, product: str, target: str, t
|
|
| 73 |
k=k_variants,
|
| 74 |
)
|
| 75 |
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
raise gr.Error("LLM出力のJSONパースに失敗しました。プロンプトを短くするか、再実行してください。")
|
| 86 |
|
| 87 |
rows = []
|
| 88 |
for it in items[:k_variants]:
|
|
|
|
| 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 |
あなたは日本語広告コピーのプロフェッショナルコピーライターです。
|
| 35 |
+
出力は**次のJSONオブジェクトのみ**で厳密に返してください。余計な文章・説明・前置きは禁止です。
|
| 36 |
+
|
| 37 |
+
形式:
|
| 38 |
+
{
|
| 39 |
+
"variants": [
|
| 40 |
+
{"headline": "全角15-25字程度", "body": "全角40-90字程度"},
|
| 41 |
+
...
|
| 42 |
+
]
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
ルール:
|
| 46 |
+
- 医薬効能の断定、100%、永久、即効、根拠のない数値などの誇大表現は禁止
|
| 47 |
+
- CTAは自然に
|
| 48 |
+
- 日本語で、句読点や記号は自然に
|
| 49 |
"""
|
| 50 |
|
| 51 |
GEN_USER_TEMPLATE = """
|
|
|
|
| 55 |
トーン: {tone}
|
| 56 |
制約: {constraints}
|
| 57 |
生成本数: {k}
|
| 58 |
+
|
| 59 |
+
要件:
|
| 60 |
+
- "variants" 配列の要素数は **ちょうど {k}** 件にしてください
|
| 61 |
+
- 各要素は {"headline": "...", "body": "..."} のみ
|
| 62 |
"""
|
| 63 |
|
| 64 |
def _seasonal(campaign_id: str) -> SeasonalityModel:
|
|
|
|
| 88 |
k=k_variants,
|
| 89 |
)
|
| 90 |
|
| 91 |
+
# ← JSONモードを使用
|
| 92 |
+
data = await openai_chat_json(
|
| 93 |
+
[
|
| 94 |
+
{"role": "system", "content": GEN_SYSTEM},
|
| 95 |
+
{"role": "user", "content": user},
|
| 96 |
+
],
|
| 97 |
+
temperature=0.3,
|
| 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]:
|