Renecto commited on
Commit
d4aa6f6
·
verified ·
1 Parent(s): 8b4e99f

upload: mock_responses.py

Browse files
Files changed (1) hide show
  1. mock_responses.py +132 -0
mock_responses.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Level-aware mock templates.
3
+ Replace level1_propose / level2_propose / level3_propose with real logic.
4
+ """
5
+
6
+ from __future__ import annotations
7
+ from bridge_models import BestNow, NextLevelPreview, NeededInfo
8
+ from session_store import AccumulatedContext
9
+
10
+
11
+ def get_mock_best_now(level: str, ctx: AccumulatedContext) -> BestNow:
12
+ campaign = ctx.campaign_name or "このキャンペーン"
13
+ industry = ctx.industry or "この業界"
14
+
15
+ if level == "level1":
16
+ return BestNow(
17
+ summary=(
18
+ f"【{industry}】の業界ベンチマークを起点に、{campaign} の初期改善仮説を提案します。"
19
+ " 一般的にEC・サービス系では認知→検討→CVの3段階で離脱が発生します。"
20
+ " まずは訴求軸の見直し(ベネフィット訴求 vs 機能訴求)から着手することを推奨します。"
21
+ ),
22
+ actions=[
23
+ "ターゲット顧客の主要ペインを3つリストアップする",
24
+ "現在の広告訴求軸を「機能」「ベネフィット」「感情」で分類する",
25
+ "業界ベンチマークCVR(目安: 1〜3%)と現状ギャップを確認する",
26
+ ],
27
+ confidence="low",
28
+ reasoning_basis=["campaign_name", "industry"],
29
+ )
30
+
31
+ if level == "level2":
32
+ cvr_text = f"CVR {ctx.cvr}%" if ctx.cvr is not None else "CVR不明"
33
+ ctr_text = f"CTR {ctx.ctr}%" if ctx.ctr is not None else ""
34
+ metrics_summary = "、".join(filter(None, [cvr_text, ctr_text]))
35
+ return BestNow(
36
+ summary=(
37
+ f"{campaign} の定量データ({metrics_summary})をもとにファネル診断を行いました。"
38
+ " CVRが業界平均(約2%)を下回る場合、LP到達後の離脱が主要ボトルネックである可能性が高いです。"
39
+ " クリック後の初期体験(FV・CTA)の改善を優先します。"
40
+ ),
41
+ actions=[
42
+ "LPファーストビューのキャッチコピーをベネフィット訴求に変更する",
43
+ "CTAボタンの文言・色・配置をA/Bテストする",
44
+ "LPの読了率をヒートマップで確認し、離脱ポイントを特定する",
45
+ ],
46
+ confidence="mid",
47
+ reasoning_basis=["cvr", "ctr", "campaign_name", "industry"],
48
+ )
49
+
50
+ # level3
51
+ return BestNow(
52
+ summary=(
53
+ f"{campaign} のクリエイティブ画像を含めた総合的な改善提案です。"
54
+ " 画像の視覚的訴求力(色彩・人物有無・テキスト量)と定量KPIを組み合わせて診断します。"
55
+ " ファーストビューの画像とCTAの整合性が鍵です。"
56
+ ),
57
+ actions=[
58
+ "クリエイティブ画像のメインビジュアルに人物(使用シーン)を追加する",
59
+ "画像内テキストを最小化し、LPコピーとの役割分担を明確にする",
60
+ "高CVR画像の共通要素(色・構図・訴求軸)をパターン化してA/Bテストに活用する",
61
+ ],
62
+ confidence="high",
63
+ reasoning_basis=["image_base64", "cvr", "ctr", "campaign_name", "industry"],
64
+ )
65
+
66
+
67
+ def get_mock_next_level_preview(current_level: str) -> NextLevelPreview:
68
+ if current_level == "level1":
69
+ return NextLevelPreview(
70
+ current_level="level1",
71
+ next_level="level2",
72
+ needed_info=[
73
+ NeededInfo(key="cvr", label="直近14日のCVR", example="2.1%"),
74
+ NeededInfo(key="ctr", label="CTR(クリック率)", example="0.8%"),
75
+ NeededInfo(key="cpa", label="CPA(獲得単価)", example="3500円"),
76
+ ],
77
+ what_will_be_possible=[
78
+ "ファネル診断(どの段階で離脱しているか特定)",
79
+ "優先度付きの改善アクション(高インパクト順)",
80
+ "KPI改善の定量目標設定",
81
+ ],
82
+ expected_impact="CVRやCTRの数値があると、業界平均との差分から改善余地を定量化でき、提案の精度が大幅に向上します。",
83
+ )
84
+
85
+ if current_level == "level2":
86
+ return NextLevelPreview(
87
+ current_level="level2",
88
+ next_level="level3",
89
+ needed_info=[
90
+ NeededInfo(key="image_base64", label="広告クリエイティブ画像", example="バナー画像またはLP上部スクリーンショット"),
91
+ ],
92
+ what_will_be_possible=[
93
+ "クリエイティブ要素(ビジュアル・テキスト量・色彩)の具体的改善提案",
94
+ "画像とKPIの相関分析(どのビジュアル要素がCVRに影響するか)",
95
+ "高CVR画像パターンの抽出",
96
+ ],
97
+ expected_impact="画像があると、数値だけでは見えない「なぜ離脱するか」の視覚的原因を特定でき、具体的なクリエイティブ改善指示が出せます。",
98
+ )
99
+
100
+ # level3 -- already at max
101
+ return NextLevelPreview(
102
+ current_level="level3",
103
+ next_level=None,
104
+ needed_info=[],
105
+ what_will_be_possible=[],
106
+ expected_impact="利用可能な全情報が揃っています。現在の提案は最高精度です。",
107
+ )
108
+
109
+
110
+ def get_follow_up_question(current_level: str) -> str | None:
111
+ if current_level == "level1":
112
+ return "CVRやCTRなどの数値データはありますか?あれば入力いただくと提案精度が上がります。"
113
+ if current_level == "level2":
114
+ return "広告クリエイティブ画像(バナーやLPスクリーンショット)をアップロードできますか?"
115
+ return None
116
+
117
+
118
+ # --- Real implementation stubs (user replaces these) ---
119
+
120
+ def level1_propose(ctx: AccumulatedContext, history: list) -> BestNow:
121
+ """Level 1 real implementation. Replace this with your logic."""
122
+ return get_mock_best_now("level1", ctx)
123
+
124
+
125
+ def level2_propose(ctx: AccumulatedContext, history: list) -> BestNow:
126
+ """Level 2 real implementation. Replace this with your logic."""
127
+ return get_mock_best_now("level2", ctx)
128
+
129
+
130
+ def level3_propose(ctx: AccumulatedContext, history: list) -> BestNow:
131
+ """Level 3 real implementation. Replace this with your logic."""
132
+ return get_mock_best_now("level3", ctx)