Spaces:
Sleeping
Sleeping
| """ | |
| Level-aware mock templates. | |
| Replace level1_propose / level2_propose / level3_propose with real logic. | |
| """ | |
| from __future__ import annotations | |
| from bridge_models import BestNow, NextLevelPreview, NeededInfo | |
| from session_store import AccumulatedContext | |
| def get_mock_best_now(level: str, ctx: AccumulatedContext) -> BestNow: | |
| campaign = ctx.campaign_name or "このキャンペーン" | |
| industry = ctx.industry or "この業界" | |
| if level == "level1": | |
| return BestNow( | |
| summary=( | |
| f"【{industry}】の業界ベンチマークを起点に、{campaign} の初期改善仮説を提案します。" | |
| " 一般的にEC・サービス系では認知→検討→CVの3段階で離脱が発生します。" | |
| " まずは訴求軸の見直し(ベネフィット訴求 vs 機能訴求)から着手することを推奨します。" | |
| ), | |
| actions=[ | |
| "ターゲット顧客の主要ペインを3つリストアップする", | |
| "現在の広告訴求軸を「機能」「ベネフィット」「感情」で分類する", | |
| "業界ベンチマークCVR(目安: 1〜3%)と現状ギャップを確認する", | |
| ], | |
| confidence="low", | |
| reasoning_basis=["campaign_name", "industry"], | |
| ) | |
| if level == "level2": | |
| cvr_text = f"CVR {ctx.cvr}%" if ctx.cvr is not None else "CVR不明" | |
| ctr_text = f"CTR {ctx.ctr}%" if ctx.ctr is not None else "" | |
| metrics_summary = "、".join(filter(None, [cvr_text, ctr_text])) | |
| return BestNow( | |
| summary=( | |
| f"{campaign} の定量データ({metrics_summary})をもとにファネル診断を行いました。" | |
| " CVRが業界平均(約2%)を下回る場合、LP到達後の離脱が主要ボトルネックである可能性が高いです。" | |
| " クリック後の初期体験(FV・CTA)の改善を優先します。" | |
| ), | |
| actions=[ | |
| "LPファーストビューのキャッチコピーをベネフィット訴求に変更する", | |
| "CTAボタンの文言・色・配置をA/Bテストする", | |
| "LPの読了率をヒートマップで確認し、離脱ポイントを特定する", | |
| ], | |
| confidence="mid", | |
| reasoning_basis=["cvr", "ctr", "campaign_name", "industry"], | |
| ) | |
| # level3 | |
| return BestNow( | |
| summary=( | |
| f"{campaign} のクリエイティブ画像を含めた総合的な改善提案です。" | |
| " 画像の視覚的訴求力(色彩・人物有無・テキスト量)と定量KPIを組み合わせて診断します。" | |
| " ファーストビューの画像とCTAの整合性が鍵です。" | |
| ), | |
| actions=[ | |
| "クリエイティブ画像のメインビジュアルに人物(使用シーン)を追加する", | |
| "画像内テキストを最小化し、LPコピーとの役割分担を明確にする", | |
| "高CVR画像の共通要素(色・構図・訴求軸)をパターン化してA/Bテストに活用する", | |
| ], | |
| confidence="high", | |
| reasoning_basis=["image_base64", "cvr", "ctr", "campaign_name", "industry"], | |
| ) | |
| def get_mock_next_level_preview(current_level: str) -> NextLevelPreview: | |
| if current_level == "level1": | |
| return NextLevelPreview( | |
| current_level="level1", | |
| next_level="level2", | |
| needed_info=[ | |
| NeededInfo(key="cvr", label="直近14日のCVR", example="2.1%"), | |
| NeededInfo(key="ctr", label="CTR(クリック率)", example="0.8%"), | |
| NeededInfo(key="cpa", label="CPA(獲得単価)", example="3500円"), | |
| ], | |
| what_will_be_possible=[ | |
| "ファネル診断(どの段階で離脱しているか特定)", | |
| "優先度付きの改善アクション(高インパクト順)", | |
| "KPI改善の定量目標設定", | |
| ], | |
| expected_impact="CVRやCTRの数値があると、業界平均との差分から改善余地を定量化でき、提案の精度が大幅に向上します。", | |
| ) | |
| if current_level == "level2": | |
| return NextLevelPreview( | |
| current_level="level2", | |
| next_level="level3", | |
| needed_info=[ | |
| NeededInfo(key="image_base64", label="広告クリエイティブ画像", example="バナー画像またはLP上部スクリーンショット"), | |
| ], | |
| what_will_be_possible=[ | |
| "クリエイティブ要素(ビジュアル・テキスト量・色彩)の具体的改善提案", | |
| "画像とKPIの相関分析(どのビジュアル要素がCVRに影響するか)", | |
| "高CVR画像パターンの抽出", | |
| ], | |
| expected_impact="画像があると、数値だけでは見えない「なぜ離脱するか」の視覚的原因を特定でき、具体的なクリエイティブ改善指示が出せます。", | |
| ) | |
| # level3 -- already at max | |
| return NextLevelPreview( | |
| current_level="level3", | |
| next_level=None, | |
| needed_info=[], | |
| what_will_be_possible=[], | |
| expected_impact="利用可能な全情報が揃っています。現在の提案は最高精度です。", | |
| ) | |
| def get_follow_up_question(current_level: str) -> str | None: | |
| if current_level == "level1": | |
| return "CVRやCTRなどの数値データはありますか?あれば入力いただくと提案精度が上がります。" | |
| if current_level == "level2": | |
| return "広告クリエイティブ画像(バナーやLPスクリーンショット)をアップロードできますか?" | |
| return None | |
| # --- Real implementation stubs (user replaces these) --- | |
| def level1_propose(ctx: AccumulatedContext, history: list) -> BestNow: | |
| """Level 1 real implementation. Replace this with your logic.""" | |
| return get_mock_best_now("level1", ctx) | |
| def level2_propose(ctx: AccumulatedContext, history: list) -> BestNow: | |
| """Level 2 real implementation. Replace this with your logic.""" | |
| return get_mock_best_now("level2", ctx) | |
| def level3_propose(ctx: AccumulatedContext, history: list) -> BestNow: | |
| """Level 3 real implementation. Replace this with your logic.""" | |
| return get_mock_best_now("level3", ctx) | |