mcpField
D
discover-event-surfaces

discover-event-surfaces

github.com/amplitude数据与数据库4646.1k 次安装5 天前更新
代码仓库

关于 discover-event-surfaces

这是分析埋点工作流中的技能,用于根据 change_brief 为产品经理整理候选分析事件。它强调围绕用户结果构建事件,并结合代码流程、命名规范和已有事件去重。

主要功能

  1. 01解析 change_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——对变更的一句话描述。
  • user_facing_changes——主要信号。每个条目都代表用户现在可以执行或查看的不同操作。
  • surfaces.components——修改过的 UI 组件;用户交互发生的位置。
  • file_summary_map——读取 surfaces 中所列文件或涉及面向用户逻辑的文件摘要。跳过测试/配置/工具文件。

2. 扫描代码库并梳理用户流程

生成任何事件前,先具体了解用户如何使用该功能。change_brief 会提供文件路径和摘要——现在请阅读实际代码,追踪完整流程。

要阅读的内容
  • 阅读 surfaces.components 中列出的每个文件,通读全文。
  • 阅读 file_summary_map 中涉及面向用户逻辑的文件(跳过测试、配置和工具文件)。
  • 向外追踪一层导入和引用:如果某个组件调用了 hook、API 函数,或会导航到其他路由,也要阅读对应目标文件。这样才能发现差异未涉及、但属于同一流程的步骤。
要查找的内容

追踪用户从进入功能到完成操作的路径:

  • 入口点——用户如何进入?检查路由定义、导航调用、菜单项、链接和功能标记门控。
  • 交互顺序——用户逐步执行哪些操作?例如填写表单、进行选择、确认和上传。查看处理函数的绑定(onClick、onSubmit、onChange)及其修改的状态。
  • 异步边界——API 调用、变更操作、服务端操作。这些环节决定了“已尝试”最终是“成功”还是“失败”。
  • 终止状态——成功确认、错误处理、重定向和完成页面。
  • 分支路径——将用户引向不同结果的条件判断(例如,免费与付费、首次使用与再次使用)。
提出漏斗假设

根据发现的内容,整理出一个或多个漏斗——按顺序排列从入口到结果的用户步骤。每个漏斗都应包含:

  • 描述性名称(例如,“属性提取流程”“入门向导”)
  • 按顺序排列的步骤,并注明每一步发生的文件和函数/处理函数
  • 明确指出哪一步是起点,哪一步是终点

并非每项变更都有漏斗。单一操作功能(例如开关、一键导出)不需要漏斗——只需说明不存在多步骤流程。但如果确实存在流程,在此梳理流程,才能在之后有把握地将漏斗起点/终点标记为关键事件。

假设必须以你实际阅读过的代码为依据。不要臆造没有证据支持的步骤。

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 会想了解哪些结果?”

从四个类别生成候选事件(按优先级排序):

类别记录的内容何时纳入
business_outcome收入、留存、增长相关操作(购买、订阅变更、转化关口)变更涉及变现或留存界面
user_journey有意义的状态转换(工作流完成、功能激活、引导流程结束)变更新增或调整了用户旅程中的步骤
feature_success“成功了”的时刻——已确认的结果,而非按钮点击(文档已创建、报告已生成)任何新增或发生实质性变更的功能
friction_failure用户失败、受阻或放弃的地方(错误、空状态、中途退出)复杂的多步骤交互或容易出错的流程
与现有事件去重

生成候选事件后,将每个候选事件与第 3 步中建立的现有事件索引进行检查。对于每个候选事件:

  • 完全匹配 — eventType 已原样存在。移除该候选事件。
  • 语义匹配 — 名称不同,但记录的是相同的用户操作或结果(例如,你提出了 Plan Upgraded,但已有 Subscription Upgraded 记录了相同的操作)。移除该候选事件。
  • 部分重叠 — 现有事件涵盖的操作范围更广,包含了你的候选事件(例如,已有 Checkout Completed,而你的候选事件 Payment Submitted 在同一时刻触发)。移除该候选事件,除非它能记录有意义的不同信息。

如果因某个候选事件已存在而将其移除,请在输出中的 already_tracked 列表里注明,以便用户了解哪些事件已有覆盖。

5. 质量筛选

每个候选事件都必须满足以下三项要求:

  1. 有助于决策 — 仅凭此事件,PM 就能做出产品决策,无需借助其他五个事件了解背景。
  2. 关注结果 — 记录某件事已发生,而非用户尝试了某件事。Property Extracted > Extract Button Clicked。优先选择已确认的结果;如果没有服务器端确认,则可接受表单提交。
  3. 改版后仍然稳定 — 以业务/产品概念命名,而非以 UI 元素命名。如果重命名某个模态框就会导致事件名称过时,说明耦合过紧。

剔除: 没有结果的原始点击/悬停、内部技术操作(API 回调、状态更新)、包含 UI 版本的名称(modal_v2_submit)、子步骤级的粒度。

6. 为事件命名

使用 discover-analytics-patterns 返回的命名规范。 新事件应与其他埋点保持一致: 使用相同的大小写、词序、分隔符、前缀模式和具体程度。

如果之后需要在理由或埋点提示中建议属性名称,请使用 discover-analytics-patterns 返回的 property_naming_convention。

所有情况下,都应使用产品领域中的主体(Property、User、Document),而非代码名称(PropertyItem、ActionStore)。

好(标题式大小写规范)差
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. 深入理解,然后确定优先级

针对每个候选事件,先完成以下两个字段——它们能促使你在评分前具体思考事件的价值:

  • analysis_recipe — 描述分析师会用此事件构建的具体图表、漏斗或查询。请具体说明可视化类型、细分维度,以及要结合的其他事件。例如:“每周漏斗:Panel Opened → Extract Type Selected → Property Extracted,按 extractType 细分。如果完成率低于 50%,则发出提醒。”
  • stakeholder_narrative — 写一句 PM 可以放进季度回顾或董事会演示文稿的话,用到此事件的数据。假设该指标已经存在,写出它所呈现的故事。例如:“尝试提取的用户中,有 68% 首次尝试就完成了提取,高于上一季度的 45%。” 如果想不出一句有说服力的幻灯片文案,这个事件可能不值得埋点。

现在,结合这些背景,分配一个优先级:

优先级含义指引
3(关键)如果缺少此事件,你会阻止发布。它回答了团队在第一周一定会提出的问题。仅用于直接衡量功能成功或失败的事件。大多数变更只会产生 1-2 个关键事件。
2(有用)能带来实际分析价值,但即使没有它,功能也可以发布。如果埋点成本较低,值得添加。细分维度、次要工作流、配置选项。
1(可选)有更好,没有也无妨。只有团队有余力且有明确的待验证假设时才埋点。边缘情况故障、探索性参与信号、可发现性指标。

漏斗事件值得特别关注。 当变更引入或修改了一个多步骤流程(结账流程、新手引导向导、数据导入流程)时,PM 最先会问:“用户在哪一步流失?”如果漏斗起点和终点之间没有任何可见性,这个盲区就可能掩盖严重的产品问题——如果用户在 5 步中的第 2 步参与度骤降,团队需要了解情况,而不是靠猜测。

漏斗起点和终点事件始终是关键事件(优先级 3)。 没有这两个端点,就无法衡量转化率——这是任何漏斗最重要的指标。无论漏斗有多长或多复杂,这两个事件都不可或缺。

要决定将多少个漏斗中间事件标记为关键事件,请评估漏斗的长度和复杂程度:

  • 短流程(2-3 步,单个页面): 起点和终点事件就足够了。简单流程中,不要为每个微小步骤都埋点。
  • 中等流程(3-5 步,可能跨多个页面): 在最可能发生流失的位置添加一个中间事件——通常是用户投入精力的环节(填写表单、做出关键选择、上传文件)。
  • 长流程(5 步以上,多页面或向导式): 在自然的阶段分界处添加 2-3 个中间事件。考虑跟踪“已开始 → 已配置 → 已提交 → 已确认”,而不是跟踪每次字段交互。

谨慎选择中间事件。你标记为关键事件的每个漏斗事件,都是工程师必须实现、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(粒度过细)。

评论

支持 Markdown