mcpField
A
aa-conversion-funnel-analysis

aa-conversion-funnel-analysis

github.com/adobeデータ・データベース316343 回インストール今日更新
リポジトリ

aa-conversion-funnel-analysis について

aa-conversion-funnel-analysisは、Adobe Analyticsの訪問単位セグメントとレポートで複数段階のファネルを分析するスキルです。各段階の転換率と離脱を推定し、最大の離脱箇所を属性別に調べますが、厳密な順次離脱分析ではありません。

主な機能

  1. 01最大8段階のファネル定義
  2. 02訪問単位のステップセグメントの検索・作成
  3. 03転換率と離脱率の算出
  4. 04最大の離脱段階の特定
  5. 05オーディエンス属性別の結果分析
  6. 06HTMLレポートの生成

活用シーン

  1. 01チェックアウト過程の離脱箇所の特定
  2. 02デバイスタイプ別の段階進行の比較
  3. 03ファネル各段階の訪問単位転換の確認

MCP 対応

Adobe Analytics MCPツールを使い、レポートスイート、ディメンション、指標、セグメントを検索してレポートを実行します。このスキル自体はMCPサーバーを提供しません。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/adobe/skills --skill aa-conversion-funnel-analysis

インストール後、Claude Code で/aa-conversion-funnel-analysisを入力して読み込まれたか確認します。

同梱ファイルevals/evals.json

詳細

コンバージョンファネル分析(Adobe Analytics)

複数ステップのコンバージョンファネルを分析し、訪問者がどこで離脱するか、どのステップで最も多く離脱するか、訪問者のコンバージョンまたは離脱を促す要因を特定します。AA の訪問レベルのセグメントベースのレポートを使用して、ファネルの各ステップをシミュレートします。

AA のコンテナモデル: AA のファネルでは、CJA のイベント/セッション/ユーザーではなく、ヒット、訪問、訪問者のコンテナを使用します。ファネルの各ステップは、訪問レベルのセグメント(1 回の訪問中にそのステップを完了した訪問者)として定義します。

レポート方法: AA には、MCP 経由で利用できるネイティブの逐次フォールアウト API がありません。このスキルでは、ファネルの各ステップについて訪問レベルのセグメントを作成または検索し、各ステップのセグメントで指標を実行して通過率を計算することで、フォールアウトを近似します。


使用する AA MCP ツール

  • findReportSuites — レポートスイートを選択します
  • setSessionDefaults — セッションコンテキストを設定します(reportSuiteId + globalCompanyId)
  • findDimensions — ステップの定義に使用するページ/イベントディメンションを確認します
  • findMetrics — カウント指標として訪問数または注文数を検索します
  • searchDimensionItems — ページ名またはイベント値を検証します
  • findSegments — 利用可能であれば、既存のステップセグメントを検索します
  • upsertSegment — 見つからない場合は、訪問レベルのステップセグメントを作成します
  • runReport — 各ステップセグメントの訪問数をレポートします

フェーズ 0 — セットアップ

  1. findReportSuites/setSessionDefaults でレポートスイートを確認します。
  2. ファネル全体の対象範囲(訪問レベルまたは訪問者レベル)についてユーザーに尋ねます。
    • 訪問レベルのファネル: すべてのステップが 1 回の訪問中に発生します (チェックアウトファネルで一般的です)
    • 訪問者レベルのファネル: ステップが複数回の訪問にまたがることがあります (ライフサイクルファネルで一般的です)
findReportSuites(globalCompanyId: "<gcid>", page: 0, limit: 10)
setSessionDefaults(globalCompanyId: "<gcid>", reportSuiteId: "<rsid>")

フェーズ 1 — ファネルのステップを定義する

ファネルの各ステップを平易な言葉で説明してもらうよう、ユーザーに尋ねます。 3~8 個のステップを指定するよう促します。例:

  1. 商品ページを閲覧
  2. カートに追加
  3. チェックアウトを開始
  4. 支払い情報を入力
  5. 注文を確定(購入)

各ステップについて、次のように尋ねます。

  • 「このステップはページビュー(ページ名または URL)、カスタムイベント、またはその組み合わせで定義しますか?」
  • 「このステップはヒットレベル(単一のページ/イベント)と訪問レベル(該当のアクションが発生した訪問)どちらにしますか?」

フェーズ 2 — コンポーネントを確認する

2.1 ページ名を検証する

ページベースのステップの場合:

findDimensions(page: 1, limit: 500)   # returns all available dimensions; look for variables/page
searchDimensionItems(
  dimensionId: "variables/page",
  searchOr: "<step page keywords>",   # space-separated keywords OR'd together
  startDate: "<start>",
  endDate: "<end>",
  page: 1,
  limit: 20
)

一般的なページディメンション ID:variables/page、variables/entrypage、variables/exitpage。 複数の一致がある場合は、正しいページ名の値をユーザーに確認します。

注: searchDimensionItems でフィルタリングに使用するのは searchTerm ではなく、searchOr または searchAnd です。 行が返されない場合は、日付範囲を広げてみてください。レポートスイートによっては、過去のデータしかない場合があります。

2.2 イベント/指標を検証する

イベントベースのステップ(カートへの追加、チェックアウト、購入)の場合:

findMetrics(expansions: "componentType,categories", page: 0, limit: 200)
# Filter results locally by name: visits, orders, pageviews, etc.

フェーズ 3 — ステップセグメントを検索または作成する

ファネルの各ステップについて、既存のセグメントを検索します。

findSegments(searchTerm: "<step description>")

適切な訪問レベルのセグメントがある場合は、それをそのまま使用します。

ない場合は、各ステップについて新しい訪問レベルのセグメントを作成します。

upsertSegment(
  definition: {
    "name": "Visit: Checkout Started",
    "description": "Visits where the visitor reached the checkout page",
    "reportSuiteID": "<rsid>",
    "container": {
      "func": "segment",
      "context": "visits",
      "pred": {
        "func": "streq",
        "val": "/checkout",
        "str": "/checkout",
        "dimension": "variables/page"
      }
    },
    "tags": [{ "name": "funnel" }]
  }
)

レポートを実行する前に、すべてのステップセグメントを作成します。各セグメントの id を記録します。

重要: 明示的にユーザーの確認を得た場合にのみ、新しいセグメントを作成します。 作成するセグメントの一覧を提示し、「ファネルの各ステップを定義するために、N 個の訪問レベルセグメントを作成する必要があります。よろしいですか?」と尋ねます。


フェーズ 4 — ファネルのステップレポートを実行する

各ステップセグメントについて、分析期間の訪問数をレポートします。

runReport(
  dimensionId: "variables/page",    # required by AA runReport
  metricIds: "metrics/visits",      # note: plural field name "metricIds"
  segmentIds: "<step segment id>",  # note: plural field name "segmentIds"
  startDate: "<start>",
  endDate: "<end>",
  limit: 1
)
# summaryData.totals[0] is the total visits for this segment

ファネルのステップごとに 1 回の呼び出しが必要です。5 ステップのファネルなら、5 回呼び出します。

また、100%の基準値として、セグメントなしの総訪問数もレポートします。

runReport(
  dimensionId: "variables/page",
  metricIds: "metrics/visits",
  startDate: "<start>",
  endDate: "<end>",
  limit: 1
)
# Use summaryData.totals[0] as the baseline visit count

AA の runReport フィールド名: metricId ではなく metricIds、segmentId ではなく segmentIds を使用します。 dateRange オブジェクトではなく、startDate/endDate(ISO 8601)を使用します。 合計値は必ず rows ではなく summaryData.totals[0] から読み取ります。


フェーズ 5 — ファネル指標の算出

各ステップについて、次の指標を算出します。

指標計算式
ステップの訪問数runReport の生の件数
ステップのコンバージョン率ステップの訪問数 / 合計訪問数 × 100
ステップ間の率ステップ N の訪問数 / ステップ N-1 の訪問数 × 100
ステップ間の離脱数ステップ N-1 の訪問数 - ステップ N の訪問数
離脱率100 - ステップ間の率

最も大きな流出が発生しているステップ(離脱数が最も多いステップ)と、 コンバージョンが最も低いステップ(ステップ間の率が最も低いステップ)を特定します。


フェーズ 6 — 最も問題のあるステップを詳しく分析する

離脱数が最も多いステップについて、ディメンションの内訳を実行し、 ステップを進んだ訪問者と離脱した訪問者の違いを見つけます。

runReport(
  dimensionId: "variables/mobiledevicetype",
  metricIds: "metrics/visits",
  segmentIds: "<worst step segment>",
  startDate: "<start>",
  endDate: "<end>",
  limit: 10
)

runReport(
  dimensionId: "variables/mobiledevicetype",
  metricIds: "metrics/visits",
  segmentIds: "<next step segment>",
  startDate: "<start>",
  endDate: "<end>",
  limit: 10
)

最も問題のあるステップを完了した訪問者と、次のステップに進んだ訪問者のデバイスタイプの構成を比較します。ほかのディメンションについても、1~2 個繰り返します (例:トラフィックソース、新規訪問者とリピーター)。


フェーズ 7 — HTML レポートの生成

ファネルレポートをインラインで作成し、 /tmp/aa_funnel_analysis_report_<YYYY-MM-DD_HHMMSS>.html に書き込みます。

HTML テンプレート
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Funnel Health &mdash; {ORG_NAME} &mdash; {FUNNEL_NAME}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;900&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
  * { box-sizing: border-box; margin: 0; padding: 0; }
  :root {
    --bg: #f5f4f1;
    --surface: #ffffff;
    --ink: #1a1a1a;
    --ink-muted: #6b6b6b;
    --border: #e5e2dc;
    --header-bg: #0e0e10;
    --header-warm: #3a1010;
    --accent-red: #c8312f;
    --accent-red-bright: #ff6b68;
    --accent-red-soft: #fdecea;
    --accent-green: #1f7a4d;
    --accent-yellow: #d4a017;
  }
  body { font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
         background: var(--bg); color: var(--ink); line-height: 1.5;
         -webkit-font-smoothing: antialiased; }

  /* === Header === */
  header { background: linear-gradient(120deg, var(--header-bg) 0%, #1a0d0d 55%, var(--header-warm) 100%);
           color: #fff; padding: 56px 56px 44px; position: relative; overflow: hidden; }
  header::after { content: ""; position: absolute; right: -140px; top: -140px;
                  width: 460px; height: 460px;
                  background: radial-gradient(circle, rgba(200,49,47,.35) 0%, transparent 70%);
                  pointer-events: none; }
  .header-inner { max-width: 1080px; margin: 0 auto; position: relative; z-index: 1; }
  .eyebrow { display: inline-flex; align-items: center; gap: 8px;
             padding: 6px 14px; border: 1px solid rgba(255,107,104,.55);
             border-radius: 999px; color: var(--accent-red-bright);
             font-size: 11px; font-weight: 600; letter-spacing: 1.2px;
             text-transform: uppercase; margin-bottom: 24px;
             background: rgba(200,49,47,.10); }
  .eyebrow::before { content: ""; width: 6px; height: 6px;
                     background: var(--accent-red-bright); border-radius: 50%; }
  header h1 { font-family: "Playfair Display", Georgia, serif;
              font-size: 56px; font-weight: 700; letter-spacing: -1.5px;
              line-height: 1.05; margin-bottom: 14px; color: #fff; }
  header .lede { font-size: 16px; max-width: 600px;
                 color: rgba(255,255,255,.80); margin-bottom: 24px;
                 line-height: 1.55; }
  header .meta { display: flex; flex-wrap: wrap; gap: 22px;
                 font-size: 13px; color: rgba(255,255,255,.60); }
  header .meta span { display: inline-flex; align-items: center; gap: 6px; }
  header .meta .icon { opacity: .8; }

  /* === Tabs === */
  nav { background: var(--surface); border-bottom: 1px solid var(--border);
        padding: 0 56px; display: flex; gap: 28px;
        position: sticky; top: 0; z-index: 50; }
  nav a { display: block; padding: 16px 0; font-size: 14px;
          color: var(--ink); text-decoration: none;
          border-bottom: 2px solid transparent;
          transition: border-color .15s ease; }
  nav a:hover { border-bottom-color: var(--accent-red); }

  /* === Container === */
  .container { max-width: 1080px; margin: 0 auto; padding: 36px 56px 60px; }

  /* === Section label === */
  .section-label { font-size: 11px; font-weight: 700;
                   text-transform: uppercase; letter-spacing: 1.4px;
                   color: var(--ink-muted); margin-bottom: 14px;
                   padding-bottom: 10px; border-bottom: 1px solid var(--border); }

  /* === Funnel visualization (horizontal stepped bars) ===
     Bar color is set per step by tier:
       .tier-strong = green  (rate >= 70% pass-through)
       .tier-mid    = yellow (40-69%)
       .tier-weak   = red    (< 40%)
     The biggest-leakage step also gets .step-bar.worst (red, regardless of tier). */
  .funnel-wrap { background: var(--surface); border-radius: 8px;
                 padding: 28px 32px; margin-bottom: 28px;
                 box-shadow: 0 1px 3px rgba(0,0,0,.04); }
  .funnel-step { display: flex; align-items: center; margin-bottom: 10px; }
  .step-label { width: 220px; font-size: 14px; font-weight: 600;
                text-align: right; padding-right: 16px; white-space: nowrap;
                overflow: hidden; text-overflow: ellipsis; color: var(--ink); }
  .step-bar-wrap { flex: 1; position: relative; height: 44px;
                   background: #f4f1eb; border-radius: 4px; }
  .step-bar { height: 44px; border-radius: 4px;
              display: flex; align-items: center; padding: 0 14px;
              color: #fff; font-size: 13px; font-weight: 700;
              transition: width 0.4s ease;
              background: var(--accent-green); }
  .step-bar.tier-strong { background: var(--accent-green); }
  .step-bar.tier-mid    { background: var(--accent-yellow); color: #3a2a05; }
  .step-bar.tier-weak   { background: var(--accent-red); }
  .step-bar.worst       { background: var(--accent-red); color: #fff; }
  .step-meta { width: 200px; padding-left: 16px; font-size: 12px;
               color: var(--ink-muted); }
  .step-meta .rate { font-family: "Playfair Display", Georgia, serif;
                     font-size: 18px; font-weight: 700;
                     color: var(--ink); line-height: 1; }
  .step-meta .drop { color: var(--accent-red); font-weight: 600;
                     display: block; margin-top: 4px; }

  /* === Collapsible sections === */
  .section { background: var(--surface); border-radius: 8px;
             box-shadow: 0 1px 3px rgba(0,0,0,.04);
             margin-bottom: 22px; overflow: hidden; }
  .section-header { padding: 18px 28px; border-bottom: 1px solid var(--border);
                    display: flex; justify-content: space-between;
                    align-items: center; cursor: pointer; user-select: none; }
  .section-header h2 { font-family: "Playfair Display", Georgia, serif;
                       font-size: 18px; font-weight: 700; }
  .toggle { font-size: 16px; color: var(--accent-red); }

  /* === Tables === */
  table { width: 100%; border-collapse: collapse; font-size: 13px; }
  thead th { background: #faf8f4; padding: 12px 22px;
             text-align: left; font-weight: 600;
             text-transform: uppercase; letter-spacing: .6px;
             font-size: 11px; color: var(--ink-muted);
             border-bottom: 1px solid var(--border); }
  tbody td { padding: 12px 22px; border-bottom: 1px solid #f4f1eb; }
  tbody tr:last-child td { border-bottom: none; }

  /* === Badges === */
  .badge { display: inline-block; padding: 3px 9px; border-radius: 4px;
           font-size: 11px; font-weight: 600; }
  .badge.green  { background: #ebf5ef; color: var(--accent-green); }
  .badge.yellow { background: #fef6e3; color: #b67a08; }
  .badge.red    { background: var(--accent-red-soft); color: var(--accent-red); }

  /* === Insight callout === */
  .insight { background: var(--accent-red-soft);
             border-left: 4px solid var(--accent-red);
             border-radius: 6px; padding: 16px 22px;
             margin: 16px 28px; font-size: 14px; line-height: 1.6;
             color: #4a2222; }

  .back-top { position: fixed; bottom: 24px; right: 24px; background: var(--accent-red);
              color: #fff; width: 44px; height: 44px; border-radius: 50%; border: none;
              font-size: 20px; cursor: pointer;
              box-shadow: 0 4px 12px rgba(200,49,47,.35); }
  footer { text-align: center; padding: 32px 24px;
           font-size: 12px; color: var(--ink-muted); }

  /* === Print === */
  @media print {
    nav { display: none; position: static; }
    header { padding: 36px 32px 28px; }
    header h1 { font-size: 42px; }
    .section-header { cursor: default; }
    .back-top { display: none; }
    .funnel-wrap, .section {
      box-shadow: none; border: 1px solid var(--border); break-inside: avoid;
    }
  }
</style>
</head>
<body>
<header>
  <div class="header-inner">
    <div class="eyebrow">Funnel Health Report</div>
    <h1>{ORG_NAME} Funnel Health</h1>
    <p class="lede">Step-by-step pass-through for the {FUNNEL_NAME} funnel during {DATE_RANGE}.</p>
    <div class="meta">
      <span><span class="icon">&#128197;</span> {DATE_RANGE}</span>
      <span><span class="icon">&#128202;</span> {REPORT_SUITE}</span>
      <span><span class="icon">&#128340;</span> Prepared {GENERATED_DATE}</span>
    </div>
  </div>
</header>
<nav>
  <a href="#funnel">Funnel</a>
  <a href="#steps">Step Detail</a>
  <a href="#leakage">Leakage Analysis</a>
  <a href="#recommendations">Recommendations</a>
</nav>
<div class="container">
  
  <div class="section-label">Funnel Pass-Through</div>
  <div id="funnel" class="funnel-wrap">
    
  </div>

  
  <div id="steps" class="section">
    <div class="section-header" onclick="toggle('steps-body')">
      <h2>Step Detail</h2>
      <span class="toggle" id="steps-body-icon">&#9662;</span>
    </div>
    <div id="steps-body">
      <table>
        <thead><tr>
          <th>Step</th><th>Visits</th><th>% of Total</th>
          <th>Step Rate</th><th>Drop-off</th>
        </tr></thead>
        <tbody></tbody>
      </table>
    </div>
  </div>

  
  <div id="leakage" class="section">
    <div class="section-header" onclick="toggle('leak-body')">
      <h2>Leakage Analysis (Worst Step: {WORST_STEP_NAME})</h2>
      <span class="toggle" id="leak-body-icon">&#9662;</span>
    </div>
    <div id="leak-body">
      <div class="insight">{LEAKAGE_INSIGHT_TEXT}</div>
      <table>
        <thead><tr>
          <th>Dimension</th><th>Entered Step</th><th>Completed Step</th>
          <th>Step Rate</th><th>vs. Average</th>
        </tr></thead>
        <tbody></tbody>
      </table>
    </div>
  </div>

  
  <div id="recommendations" class="section">
    <div class="section-header" onclick="toggle('rec-body')">
      <h2>Recommendations</h2>
      <span class="toggle" id="rec-body-icon">&#9662;</span>
    </div>
    <div id="rec-body">
      
    </div>
  </div>
</div>
<button class="back-top" onclick="window.scrollTo({top:0,behavior:'smooth'})">
  &#8679;
</button>
<footer>Funnel Health &mdash; {ORG_NAME} &mdash; Generated {GENERATED_DATE}</footer>
<script>
function toggle(id) {
  var el = document.getElementById(id);
  var ic = document.getElementById(id + '-icon');
  if (el.style.display === 'none') { el.style.display = ''; ic.textContent = '\u25be'; }
  else { el.style.display = 'none'; ic.textContent = '\u25b8'; }
}
</script>
</body>
</html>

セクションタイトル — フェーズ番号なし:HTML レポートのセクション見出しに、フェーズ番号を含めないでください。セクション名のみを使用します(例:「フェーズ 2 — ファネル概要」ではなく「ファネル概要」、「フェーズ 3 — 離脱分析」ではなく「離脱分析」)。

/tmp/aa_funnel_analysis_report_<YYYY-MM-DD_HHMMSS>.html に書き込み、開きます。

open /tmp/aa_funnel_analysis_report_<YYYY-MM-DD_HHMMSS>.html

注意事項

  • 作成するセグメントの一覧(ステップ 3)を必ず提示し、upsertSegment を呼び出す前にユーザーの確認を得てください。
  • ユーザーがファネルの各ステップに名前付きセグメントをすでに持っている場合は、新しいセグメントを作成するよりも、既存のものを優先して使用してください。まず findSegments を確認します。
  • 実用的な API 呼び出し予算に収まるよう、ファネルは最大 8 ステップに制限してください。
  • 訪問セグメントを使用したファネルのコンバージョン率は概算です。各ステップに到達した訪問数を数えるものであり、厳密な逐次的離脱を示すものではありません。この制限をユーザーに伝えてください。

対話例

「チェックアウトファネルを分析してください。訪問者がどこで離脱するのかを確認したいです。」

  1. レポートスイートと期間(過去 30 日間)を確認します。
  2. 5 つのステップを定義します:商品閲覧 → カートに追加 → チェックアウト → 支払い → 購入。
  3. searchDimensionItems でページ名を検証します。
  4. 既存のステップセグメントを確認するか、ユーザーの承認を得て新しいセグメントを作成します。
  5. 6 件のレポート(5 ステップ分と合計)を実行します。
  6. 算出します:100% → 42%(カートに追加)→ 28%(チェックアウト)→ 19%(支払い)→ 11%(購入)。全体のコンバージョン率:11%。
  7. 最も問題のあるステップ:カートへの追加からチェックアウト(離脱率 33%)。
  8. 詳しく分析します:モバイルユーザーのチェックアウト率は 18% にとどまり、デスクトップでは 31% です。
  9. HTML レポートを生成して開きます。
  10. 主な洞察:「モバイルはファネルにおける最大の弱点です。モバイルのチェックアウト体験を簡素化することを検討してください。」

コメント