mcpField
D
discover-event-surfaces

discover-event-surfaces

github.com/amplitudeデータ・データベース4646.1k 回インストール5 日前に更新
リポジトリ

discover-event-surfaces について

分析計測ワークフローで、change_brief からプロダクトマネージャー向けの候補イベントを作成するスキルです。コード上のユーザーフローと成果を根拠に、命名規則の適用、重複排除、優先順位付けを行います。

主な機能

  1. 01change_brief と画面変更の解析
  2. 02コード内のユーザーフローと成果の追跡
  3. 03分析カテゴリ別の候補イベント生成
  4. 04既存イベントとの重複排除
  5. 05名前、優先度、計測箇所の提案

活用シーン

  1. 01新機能の候補イベント一覧を作成
  2. 02複数ステップのフローの始点と終点を特定
  3. 03提案イベントと既存イベントの意味上の重複を確認

インストール

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

$npx skills add https://github.com/amplitude/mcp-marketplace --skill discover-event-surfaces

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

詳細

discover-event-surfaces

分析計測ワークフローのステップ 2 です。change_brief YAML を読み、分析イベントの候補を漏れなく列挙します。わかりやすい名前を付け、カテゴリ別に整理し、PM のレビューに備えます。

機能をリリースするエンジニアとして、また、その機能の成功を重視する立場として考えてください。実装の詳細をそのまま反映したイベントではなく、プロダクトやビジネスに関する疑問に答えるイベントを生成します。幅広さと品質を重視してください。後続のスキルでリストを絞り込みます。

分析の基本方針と命名規則を理解するため、../taxonomy/SKILL.md にある taxonomy スキルを読みます。


1. change_brief を解析する

  • classification.analytics_scope — none の場合は停止し、計測対象がないことをユーザーに伝えます。
  • summary — 変更の概要を 1 行で示します。
  • user_facing_changes — 主な手がかりです。各項目は、ユーザーが新たに実行できること、または以前とは異なる形で見られることを表します。
  • surfaces.components — 変更された UI コンポーネントです。インタラクションが発生する場所を示します。
  • file_summary_map — surfaces 内のファイル、またはユーザー向けロジックに関係するファイルの概要を読みます。テスト、設定、ツール関連のファイルは除外します。

2. コードベースを調べ、ユーザーフローを把握する

イベントを生成する前に、ユーザーがこの機能をどのように利用するか、具体的に把握します。change_brief にはファイルパスと概要が記載されています。次に実際のコードを読み、ユーザーの一連の操作を追跡します。

読む対象
  • surfaces.components に記載されたすべてのファイルを最後まで読みます。
  • file_summary_map にあるファイルのうち、ユーザー向けロジックに関係するものを読みます(テスト、設定、ツール関連のファイルは除外します)。
  • インポートや参照を 1 階層先までたどります。コンポーネントがフックや API 関数を呼び出す場合、または別のルートに遷移する場合は、その呼び出し先のファイルも読みます。これにより、差分には含まれないものの、同じフローの一部であるステップを見つけられます。
確認する内容

ユーザーが機能にたどり着いてから目的を達成するまでの経路を追います。

  • 入口 — ユーザーはどのように機能にたどり着きますか?ルート定義、ナビゲーション呼び出し、メニュー項目、リンク、フィーチャーフラグによる制御を確認します。
  • インタラクションの流れ — ユーザーは順を追って何をしますか?フォームへの入力、選択、確認、アップロードなどを確認します。ハンドラーの設定(onClick、onSubmit、onChange)と、変更される状態を調べます。
  • 非同期処理の境界 — API 呼び出し、ミューテーション、サーバーアクションを確認します。「試行」が「成功」または「失敗」に変わる箇所です。
  • 終了状態 — 成功の確認、エラー処理、リダイレクト、完了画面を確認します。
  • 分岐経路 — ユーザーを異なる結果に導く条件分岐を確認します(例:無料版と有料版、初回利用と再訪)。
ファネルの仮説を立てる

確認した内容をまとめ、入口から目的達成までのユーザーのステップを順序付けた 1 つ以上のファネルを作成します。各ファネルには次の内容を含めます。

  • 説明的な名前(例:「プロパティ抽出フロー」、「オンボーディングウィザード」)
  • 各ステップの順序と、その処理が行われるファイルおよび関数/ハンドラー
  • 開始ステップと終了ステップ

すべての変更にファネルがあるわけではありません。トグルやワンクリックのエクスポートなど、単一アクションの機能ではファネルは不要です。その場合は、複数ステップのフローがないことだけを記載します。一方、フローがある場合は、ここでマッピングすることで、後からファネルの開始/終了を重要なイベントとして確実に割り当てられます。

仮説は、実際に読んだコードに基づいて立てます。根拠のないステップを作り出してはいけません。

3. 命名規則を特定し、既存イベントを取得する

discover-analytics-patterns を呼び出し、その出力である event_naming_convention と property_naming_convention を使用します。命名を解決する手順と優先順位は、このスキルが管理します。ここで再定義してはいけません。

候補を生成する前に、プロジェクトの既存イベント分類を取得します。これにより、重複を避け、現在使われている命名規則に合わせられます。

プロジェクトを特定する

change_brief に Amplitude の projectId が含まれている場合は、それを直接使います。含まれていない場合は、get_amplitude_context を呼び出してプロジェクト名を特定するか、対象プロジェクトをユーザーに尋ねます。次の呼び出しには projectId が必要です。

既存イベントの取得

接続済みのカタログを調べ、解決済みのprojectIdを使用して、現在の分類体系に対応するイベントリーダーを利用します。公開されているスキーマに従ってください。呼び出し元の属性情報に対応している場合は、このスキルをYAMLフロントマターのnameで識別します。カーソルは不要です。パターンの検出には最初のページで十分です。スキーマでフィールド選択に対応している場合は、イベント名、カテゴリ、説明のフィールドをリクエストし、返されたフィールド名を使用してください。

命名の参照情報と既存イベントのインデックスを作成する
  1. 既存イベントのインデックス — すべてのeventTypeの値をセットにまとめます。ステップ4で候補と照合し、すでに追跡されているイベントを提案しないようにします。イベントが重複するのは、意味が既存のeventTypeと一致する場合です。文字列が完全に一致するかどうかだけでは判断しません。たとえば、Subscription Upgradedが存在する場合、同じ操作を表すPlan Upgradedは提案しないでください。

4. イベント候補を生成する

ファネルの仮説を出発点にします。ステップ2でファネルを特定した場合は、まずファネルの開始と終了に対応するイベントを生成します。これらをアンカーとして、その後、中間ステップやファネル以外の箇所の候補を補います。

各user_facing_changeについて、次のように考えます。「ユーザーがこれを行ったとき、PMはどのような結果を知りたいでしょうか?」

次の4つのカテゴリから、優先度の高い順に生成します。

カテゴリ記録する内容含めるタイミング
business_outcome収益、リテンション、成長につながる操作(購入、サブスクリプションの変更、コンバージョンのゲート)変更がマネタイズやリテンションに関わる箇所に影響する場合
user_journey意味のある状態遷移(ワークフローの完了、機能の有効化、オンボーディングの完了)変更によってユーザージャーニーのステップが追加または変更される場合
feature_success「正常に機能した」瞬間。ボタンのクリックではなく、結果が確認できた時点(ドキュメントの作成、レポートの生成)新しい機能、または実質的に変更された機能がある場合
friction_failureユーザーが失敗したり、行き詰まったり、諦めたりする箇所(エラー、空の状態、離脱)複雑な複数ステップの操作や、エラーが発生しやすいフローの場合
既存イベントと照合して重複を除外する

候補を生成したら、ステップ3で作成した既存イベントのインデックスと各候補を照合します。候補ごとに、次のように判断します。

  • 完全一致 — eventTypeがそのまま既存のイベントに含まれています。候補を削除します。
  • 意味的な一致 — 名前は異なりますが、同じユーザー操作や結果を追跡しています(たとえば、Plan Upgradedを提案したものの、同じ操作について既にSubscription Upgradedが存在する場合)。候補を削除します。
  • 部分的な重複 — 既存のイベントが、候補の内容を含むより広範な操作をカバーしています(たとえば、Checkout Completedが既に存在し、候補のPayment Submittedが同じタイミングで発火する場合)。候補が意味のある異なる情報を捉える場合を除き、削除します。

すでに存在するために候補を削除した場合は、ユーザーが追跡済みの内容を確認できるよう、出力のalready_trackedリストに記載します。

5. 品質フィルター

各候補は、次の3つすべてを満たす必要があります。

  1. 意思決定に役立つ — PMが、ほかに5つのイベントを参照して背景を把握しなくても、これだけでプロダクトの意思決定を行えます。
  2. 成果に焦点を当てている — ユーザーが何かを「試みた」のではなく、何かが「起きた」ことを捉えます。Property Extracted > Extract Button Clicked。確認済みの成果を優先します。サーバー側で確認できない場合は、フォーム送信でも問題ありません。
  3. 再設計後も有効である — UI要素ではなく、ビジネスやプロダクトの概念に基づいて命名します。モーダルの名前を変えただけでイベント名が古くなるなら、結び付きが強すぎます。

除外するもの: 成果につながらない生のクリックやホバー、内部の技術的なアクション(APIコールバック、状態更新)、UIのバージョンに依存する名前(modal_v2_submit)、細かすぎるサブステップ単位の粒度。

6. イベント名を付ける

discover-analytics-patterns が返す命名規則を使用します。 新しいイベント名は、既存の計測イベントに違和感なくなじむようにします。 大文字・小文字の使い方、語順、区切り文字、接頭辞のパターン、具体性のレベルを既存のものに合わせます。

後で根拠や計測のヒントとしてプロパティ名を提案する必要がある場合は、 discover-analytics-patterns が返す property_naming_convention を使用します。

いずれの場合も、コード名(PropertyItem、ActionStore)ではなく、プロダクト領域の対象(Property、User、Document)を使用します。

良い例(タイトルケースの規則)悪い例
Property Extractedextract_property_clicked
Extract Type Configuredtype_dropdown_changed
Property Creation Failed500_error_new_property

7. ファイルと計測箇所を特定する

各候補について、file_summary_map と surfaces.components を使用して、次の項目を特定します。

  • file — 計測処理を追加するソースファイルです。ユーザーがアクションを開始する場所ではなく、成果が確認される場所に最も近いファイルを優先します。通常は surfaces.components にあるコンポーネントファイル、または非同期処理が完了するフックです。
  • instrumentation — 発火するタイミング(どの条件、コールバック、状態遷移の後か)と、どのように組み込むか(どの関数やハンドラーに追加するか)を1~2文で説明します。エンジニアが該当箇所を見つけられるよう、ファイルの概要に記載された実際の関数名を参照します。

8. 理解を深めてから優先順位を付ける

各候補について、スコアを付ける前に、まず次の2つのフィールドを検討します。これらを具体的に考えることで、イベントの価値を明確にできます。

  • analysis_recipe — アナリストがこのイベントを使って作成する具体的なグラフ、ファネル、またはクエリを記述します。可視化の種類、セグメント化のディメンション、組み合わせるほかのイベントを明記します。例:「週次ファネル:Panel Opened → Extract Type Selected → Property Extracted。extractType でセグメント化します。完了率が50%を下回った場合にアラートを出します。」
  • stakeholder_narrative — このイベントのデータを使って、PMが四半期レビューや取締役会資料にそのまま載せられる一文を作成します。すでに指標が存在すると想定し、そのデータが示すストーリーを書きます。例:「抽出を試みたユーザーの68%が初回で完了しており、前四半期の45%から上昇しました。」 説得力のあるスライドの一文を思い描けないなら、そのイベントは計測する価値がない可能性があります。

この背景を踏まえて、優先度を設定します。

優先度意味ガイダンス
3(重大)このイベントがなければリリースを止めるほどです。チームが最初の1週間に必ず尋ねる質問に答えます。機能の成功・失敗を直接測定するイベントに限って設定してください。ほとんどの変更で、重大なイベントは1〜2件だけです。
2(有用)分析に実質的な価値を加えますが、なくても機能をリリースできます。計測コストが低ければ追加する価値があります。セグメンテーションのディメンション、二次的なワークフロー、設定の選択肢など。
1(任意)あれば便利です。チームに余力があり、検証したい具体的な仮説がある場合にのみ計測してください。エッジケースでの失敗、探索的なエンゲージメントのシグナル、発見しやすさの指標など。

ファネルイベントには特に注意が必要です。 変更によって複数ステップのプロセス(チェックアウトのフロー、オンボーディングウィザード、データインポートのパイプラインなど)が導入または変更される場合、PMが最初に尋ねるのは「ユーザーはどこで離脱しているのか?」です。ファネルの開始から終了までの間が可視化されていないと、深刻なプロダクト上の問題を隠す盲点になり得ます。たとえば、5ステップ中2ステップ目でエンゲージメントが急落した場合、チームは推測するのではなく、把握する必要があります。

ファネルの開始イベントと終了イベントは、常に重大(優先度3)です。 この両端がなければ、あらゆるファネルで最も重要な指標であるコンバージョン率を測定できません。ファネルの長さや複雑さにかかわらず、この2つのイベントは必須です。

重大としてマークする中間ファネルイベントの数は、ファネルの長さと複雑さを考慮して決めてください。

  • 短いプロセス(2〜3ステップ、単一ページ): 開始イベントと終了イベントだけで十分です。単純なフローの細かなステップをすべて計測する必要はありません。
  • 中程度のプロセス(3〜5ステップ、複数ページにまたがる場合もある): 離脱の可能性が最も高いポイントに、中間イベントを1つ追加します。通常は、ユーザーが労力をかける箇所(フォームへの入力、重要な選択、ファイルのアップロードなど)です。
  • 長いプロセス(5ステップ以上、複数ページまたはウィザード形式): 自然なフェーズの区切りに、中間イベントを2〜3個追加します。すべてのフィールド操作を追跡するのではなく、「開始 → 設定 → 送信 → 確認」のように考えてください。

中間イベントは厳選してください。重大としてマークするファネルイベントが1つ増えるたびに、エンジニアが実装し、PMが監視しなければならない項目が増えます。中間ステップを追跡する価値があるか判断に迷う場合は、おそらく必要ありません。開始イベントと終了イベントがあれば問題の有無がわかりますし、離脱が多い箇所が見えてから、いつでも詳細な計測を追加できます。

少ないほうが効果的です。誰も見ない膨大なリストより、実際にダッシュボードで確認される、要点を絞った重大イベントのほうが優れています。迷ったら優先度を下げてください。イベントは後から追加するほうが、すでにダッシュボードにあるイベントを削除するより簡単です。

9. YAML 出力を生成する

YAML ブロックのみを出力してください。前後に文章を付けないでください。

event_candidates:
  source_summary: "<from change_brief.summary>"
  analytics_scope: "<from change_brief.classification.analytics_scope>"
  event_naming_convention: "<from MCP if clear, otherwise codebase instrumentation, otherwise taxonomy skill>"
  property_naming_convention: "<from MCP if clear, otherwise codebase instrumentation, otherwise taxonomy skill>"

  already_tracked:                         # omit if no duplicates found
    - existing_event: "Subscription Upgraded"
      candidate_dropped: "Plan Upgraded"
      reason: "Same action — existing event already tracks plan/subscription upgrades."

  funnels:                                 # omit if no multi-step flows found
    - name: "Descriptive funnel name"
      steps:
        - step: "Step description"
          file: "src/components/Foo.tsx"
          function: "handleOpen"
          role: start                      # start | intermediate | end
        - step: "Next step"
          file: "src/components/Bar.tsx"
          function: "onSubmit"
          role: intermediate
        - step: "Final step"
          file: "src/hooks/useSave.ts"
          function: "onSuccess"
          role: end

  candidates:
    - name: "Event Name Here"
      category: feature_success          # business_outcome | user_journey | feature_success | friction_failure
      rationale: "What PM question this answers."
      analysis_recipe: "Weekly trend of completions; funnel from Panel Opened → Extract Type Selected → Event Name, segmented by extract type."
      stakeholder_narrative: "Feature X adoption reached 40% of active users within two weeks of launch, exceeding our 25% target."
      priority: 3                        # 3 = critical, 2 = useful, 1 = optional
      funnel: "Funnel name"             # which funnel this belongs to, if any
      funnel_role: start                 # start | intermediate | end — omit if not part of a funnel
      surface: "ComponentName"           # from surfaces.components
      file: "src/components/Foo/Bar.tsx"
      instrumentation: "Fire after the async save resolves, inside onSuccess of useExtract(). Pass result status."

    - name: "Another Event"
      category: user_journey
      rationale: "..."
      analysis_recipe: "..."
      stakeholder_narrative: "..."
      priority: 2
      surface: "..."
      file: "..."
      instrumentation: "..."

順序:上位のカテゴリから並べ、各カテゴリ内では影響の大きいものを先にします。


例

入力の抜粋:

user_facing_changes:
  - "Users can now select Extract Type (Text or Attribute) in the PropertyItem panel"
surfaces:
  components:
    - name: PropertyItem
      change: modified

適切な候補:

- name: "Property Extracted"
  category: feature_success
  rationale: "Core adoption signal — tells PMs whether the extract workflow completes."
  analysis_recipe: "Weekly funnel: Panel Opened → Extract Type Selected → Property Extracted, segmented by extractType. Alert if completion rate drops below 50%."
  stakeholder_narrative: "72% of users who open a property panel complete an extraction, up from 0% before this release — validating the new extract workflow."
  priority: 3
  surface: "PropertyItem"
  file: "src/components/PropertiesPanel/PropertyItem.tsx"
  instrumentation: "Fire after extract resolves successfully in onSuccess handler. Include extractType (TEXT or ATTRIBUTE)."

- name: "Extract Type Selected"
  category: feature_success
  rationale: "Shows which mode users prefer — informs investment in Attribute mode."
  analysis_recipe: "Pie chart of Text vs Attribute selections over 30 days. Combine with Property Extracted to get per-mode completion rate."
  stakeholder_narrative: "85% of extractions use Text mode vs 15% Attribute — we should double down on Text UX before expanding Attribute capabilities."
  priority: 2
  surface: "PropertyItem"
  file: "src/components/PropertiesPanel/PropertyItem.tsx"
  instrumentation: "Fire in onChange of Extract Type select, passing new value."

- name: "Property Extraction Failed"
  category: friction_failure
  rationale: "Surfaces where the extract workflow breaks for reliability prioritization."
  analysis_recipe: "Error rate chart: Property Extraction Failed / (Property Extracted + Property Extraction Failed), grouped by error reason. Alert on spikes."
  stakeholder_narrative: "Extraction failure rate dropped from 12% to 3% after the v2 error-handling patch — users are hitting fewer dead ends."
  priority: 2
  surface: "PropertyItem"
  file: "src/components/PropertiesPanel/PropertyItem.tsx"
  instrumentation: "Fire in catch/onError of extract call. Include error reason if available."

含めないでください: Extract Type Dropdown Opened(クリックで、結果がない)、PropertyItem State Updated(内部処理)、Attribute Input Focused(細かすぎる)。

コメント