level_bridge_chat / mock_responses.py
Renecto's picture
upload: mock_responses.py
d4aa6f6 verified
"""
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)