首页
/ Sentry 前端埋点数据查询实战:基于 Amplitude MCP 的事件发现与查询工作流

Sentry 前端埋点数据查询实战:基于 Amplitude MCP 的事件发现与查询工作流

2026-09-05 10:30:23作者:蔡丛锟

本文以 Sentry 仓库中 Agent 技能文档 references/amplitude-mcp.md 为核心,完整讲解如何通过 Amplitude MCP(Model Context Protocol)回答"有多少人使用某功能"这类产品数据问题:从一次性连接配置、Amplitude 项目发现,到 searchget_propertiesquery_dataset 的完整调用链,并结合 static/app/utils/analytics/ 下的事件定义源码,说明事件名(eventName)是如何从代码一路流入 Amplitude 的,以及 MCP 未连接时如何用代码库兜底。

读完本文,你将掌握:

  • Amplitude MCP 的连接方式与 claude.ai Amplitude 工具的发现流程;
  • 一套可复用的"找事件 → 查属性 → 跑查询 → 报结果"四步工作流,含完整参数示例;
  • Sentry 前端埋点事件从 trackAnalytics 到 Amplitude 的完整链路(事件键 → 事件名映射 → 双通道上报),以及为什么 Reload-only 事件在 Amplitude 里搜不到;
  • 常见数据问题(页面浏览量、点击量、漏斗、留存)到 Amplitude 查询参数的映射表。

一、前置知识:Sentry 的埋点事件如何进入 Amplitude

在讲 MCP 查询之前,先理解查询目标——Amplitude 中的事件名——在 Sentry 代码里长什么样。这一点决定了为什么 search 要按 eventName 搜索,以及为什么有些事件搜不到。

Sentry 前端所有埋点都经由统一入口 trackAnalytics 发出。它由工厂函数 makeAnalyticsFunction 基于"事件键 → Amplitude 显示名"的映射表生成,定义在 analytics.tsx

// static/app/utils/analytics.tsx
interface EventParameters extends CommandPaletteEventParameters, /* …几十个领域事件类型 */ {}

const allEventMap: Record<string, string | null> = {
  ...commandPaletteEventMap,
  ...feedbackEventMap,
  ...issueEventMap,
  ...seerAnalyticsEventsMap,
  /* … */
};

export const trackAnalytics = makeAnalyticsFunction<EventParameters>(allEventMap);

makeAnalyticsFunction.tsx 的核心逻辑是:调用 trackAnalytics('issue_details.seer_opened', params) 时,先查 eventKeyToNameMap[eventKey] 得到 eventName,再与 eventKey 一起打包传给 rawTrackAnalyticsEvent。每个业务域在 static/app/utils/analytics/ 下维护一份 {domain}AnalyticsEvents.tsx 文件,同时定义事件参数类型(*EventParameters)和名称映射表(*EventMap)。例如 Seer / Autofix 域:

// static/app/utils/analytics/seerAnalyticsEvents.tsx
'issue_details.seer_opened': 'Issue Details: Seer Opened',   // 在 workflowAnalyticsEvents.tsx 中定义
'seer.explorer.session_created': 'Seer Explorer: Session Created',

注意:issue_details.* 这批事件实际定义在 workflowAnalyticsEvents.tsx,映射值为 'issue_details.seer_opened': 'Issue Details: Seer Opened'——这正是本文后面所有 MCP 查询示例使用的事件名。

三通道事件管线

事件发出后走的是 GetSentry 的 override 实现 rawTrackAnalyticsEvent.tsx,它决定了事件最终到达哪些分析后端:

目的地 触发条件 使用字段 查询方式
Reload(内部后端) 只要传了 eventKey 就上报 eventKey Redash
Amplitude eventName 非空 organization_id 可解析 eventName Amplitude UI 或 MCP
Pendo 与 Amplitude 相同 eventName Pendo

源码中有两处关键门槛值得注意(rawTrackAnalyticsEvent.tsx):

if (eventKey) {
  const reloadData = { user_id: ..., org_id: organization_id, allow_no_schema: true, ...data };
  trackReloadEvent(eventKey, reloadData);          // 总是上报 Reload
}
if (eventName && organization_id !== undefined) {
  trackAmplitudeEvent(eventName, organization_id, dataWithUrl, {time});
  trackPendoEvent(eventName, data);
}
  • 事件名映射为 null 的事件不会进 Amplitude。这类事件是"Reload-only"的内部高频指标,因此在 Amplitude 的 search 里搜不到它们——这是后文"MCP 无结果时回退 grep"这条兜底规则的根本原因之一。
  • 缺少 organization 上下文的事件也发不到 Amplitudeorganization_id === undefined 时直接跳过)。所以调用 trackAnalytics 时传入 organization 是事件进入 Amplitude 的前提。

再看 trackAmplitudeEvent.tsx 的最终落点:它先检查 ConfigStore.get('enableAnalytics') 开关,然后 Amplitude.setUserId 设置用户、Amplitude.setGroup('organization_id', ...) 在组织切换时更新分组,最后 Amplitude.track(event_type, data, eventOptions) 发出事件。也就是说,Amplitude 里的用户维度是 Sentry 用户 ID,组织维度是 organization_id group——查询"独立用户数"(uniques + countGroup: "User")时统计的就是这个 userId

一个真实的埋点调用示例,来自 Issue 详情页侧边栏的"Open Autofix"按钮 autofixSection.tsx

<Button
  size="md"
  icon={<IconSeer />}
  variant="primary"
  onClick={openSeerDrawer}
  analyticsEventKey="issue_details.seer_opened"
  analyticsEventName="Issue Details: Seer Opened"
  analyticsParams={{
    group_id: group.id,
    autofix_exists: true,
    has_root_cause: hasRootCause,
    has_pr: hasPullRequests,
    mode: 'explorer',
    referrer,
  }}
/>

按钮通过声明式 props(analyticsEventKey / analyticsEventName / analyticsParams)触发同一个 issue_details.seer_opened 事件。这条链路——声明式 props → trackAnalytics → override → Amplitude.track——就是本文后续 MCP 查询的对象。

二、一次性配置:连接 Amplitude MCP

如果 Amplitude MCP 尚未连接(调用 mcp__claude_ai_Amplitude__* 工具会不可用),按以下三步完成连接:

  1. 在 Claude Code 中运行 /mcp
  2. 在列表中选择 "claude.ai Amplitude"
  3. 通过 Sentry SSO 完成认证。

连接成功后,mcp__claude_ai_Amplitude__* 系列工具(get_contextsearchget_propertiesquery_datasetquery_chart 等)即可在会话中调用。

三、发现 Amplitude 项目:get_context

所有 Amplitude 工具调用都需要 projectId。发现方式:

  1. 调用 get_context,找到 Sentry 组织及其下属项目列表;
  2. 找到 sentry.io 这个产品对应的项目,取其 appId
  3. 把这个 appId 作为后续所有 Amplitude 工具调用(get_propertiesquery_dataset 等)中的 projectId 使用。

这一步只做一次,同一会话内可复用。

四、发现工作流:四步回答"有多少人做了 X"

当用户问出"多少人做了 X?""有人在用 Y 吗?"这类问题时,按以下四步执行。

步骤 1:找到事件(Find the Event)

search 按关键词搜索事件。queries 支持多个关键词并行搜索,entityTypes 限定为 EVENTsearch_goal 用自然语言说明搜索意图:

mcp__claude_ai_Amplitude__search({
  queries: ["seer", "autofix"],
  entityTypes: ["EVENT"],
  limitPerQuery: 20,
  search_goal: "Find events related to the seer feature on issue details"
})

返回结果就是 Amplitude 里的事件名(eventName),即各事件映射表里的值,例如 "Issue Details: Seer Opened"

如果 search 没有返回任何结果,回退到 grep 代码库(对应第一节讲的两类"Amplitude 盲区":null 映射的 Reload-only 事件、以及尚未接入 Amplitude 的事件):

grep -rn "seer\|autofix" static/app/utils/analytics/ --include="*.tsx"

Sentry 的领域事件文件都集中在 static/app/utils/analytics/ 目录下,按功能域命名(seerAnalyticsEvents.tsxworkflowAnalyticsEvents.tsxfeedbackAnalyticsEvents.tsx 等),grep 该目录即可覆盖绝大多数前端事件定义。

步骤 2:获取事件属性(可选)

当用户需要按某个属性过滤或分组(比如按平台、按入口来源)时,先取该事件的属性列表:

mcp__claude_ai_Amplitude__get_properties({
  propertyType: "event",
  projectId: "<projectId>",
  eventType: "Issue Details: Seer Opened"
})

返回该事件已上报的所有属性名。属性名应与代码中 analyticsParams 的键对应——以上述 Autofix 按钮为例,返回结果里应能看到 group_idhas_root_causehas_prmodereferrer 等键。

步骤 3:查询数据(Query the Data)

对临时性(ad-hoc)分析需求,使用 query_dataset 构造事件分段查询。以"最近 30 天有多少独立用户打开过 Seer"为例:

mcp__claude_ai_Amplitude__query_dataset({
  projectId: "<projectId>",
  definition: {
    type: "eventsSegmentation",
    app: "<projectId>",
    name: "Seer Opens Last 30 Days",
    params: {
      range: "Last 30 Days",
      events: [{
        event_type: "Issue Details: Seer Opened",
        filters: [],
        group_by: []
      }],
      metric: "uniques",
      countGroup: "User",
      groupBy: [],
      interval: 1,
      segments: [{ conditions: [] }]
    }
  }
})

参数要点:

参数 作用
range 时间范围,如 "Last 30 Days"
events[].event_type 步骤 1 找到的 Amplitude 事件名(eventName
events[].filters 按事件属性过滤,属性名来自步骤 2 的 get_properties
metric 聚合指标:uniques(独立用户)或 totals(总量)
countGroup 计数维度,"User" 表示按用户去重
groupBy 需要按属性/时间分桶时填写
segments[].conditions 用户段条件,空数组表示不限

如果用户提供的是已存在的图表 ID 或 URL,则改用 query_chart 直接取数,无需重新拼装查询定义。

步骤 4:汇报结果(Report Results)

  • 明确说明使用了哪个事件名、查询了哪个时间范围;
  • 默认报告独立用户数(uniques)而非总事件量,除非用户明确要求总量;
  • 当数字缺乏上下文时,主动提议按属性(平台、组织等)做拆解。

五、常见查询模式速查表

文档将高频的自然语言问题映射为固定的指标与事件模式,可直接套用:

用户问题 指标 事件类型模式
"有多少人浏览 X 页面?" uniques "Page View: ..."
"X 按钮有多少次点击?" totals "Feature: Button Clicked"
"从 X 到 Y 的漏斗是什么?" 漏斗 使用 type: "funnels" 并传入有序事件
"人们会回到 X 吗?" 留存 使用 type: "retention"

对应到 query_datasetdefinition:前两种仍用 type: "eventsSegmentation",只改 metricuniques / totals)与事件名;后两种则把 type 换为 "funnels"events 按转化顺序排列)或 "retention"

六、搜索现成的 Dashboard 与 Chart

当用户要的不是原始数据,而是"给我看看 Seer 的仪表盘"时,用 search 指定 DASHBOARD / CHART 实体类型:

mcp__claude_ai_Amplitude__search({
  queries: ["seer dashboard", "autofix metrics"],
  limitPerQuery: 10,
  entityTypes: ["DASHBOARD", "CHART"]
})

找到后可以直接打开链接,或将其 ID 交给 query_chart 取数。

七、MCP 未连接时的代码库兜底

Amplitude MCP 是"锦上添花"的加速器;没有它时,仓库本身就是完整的事件字典。兜底流程:

  1. grep 事件文件找 Amplitude 名称:在各 {domain}AnalyticsEvents.tsx 的事件映射表(*EventMap)里找 eventName 值,例如 grep -rn "Seer Opened" static/app/utils/analytics/
  2. 向用户报告事件键(eventKey)与 Amplitude 名称(eventName)的对应关系,让用户可以在 Amplitude UI 中手动检索——事件键是 issue_details.seer_opened 这类 snake_case 键,Amplitude 名称是 Issue Details: Seer Opened 这类 Title Case 字符串,两者一一对应;
  3. 建议用户连接 Amplitude MCP 以便直接查询:运行 /mcp → 选择 "claude.ai Amplitude"。

八、实践要点与排错

结合源码,使用这套工作流时有几个容易踩坑的点:

  1. search 搜不到 ≠ 事件不存在。映射值为 null 的 Reload-only 事件(SKILL.md 中的事件管线说明 指出其"too expensive for Amplitude")不会出现在 Amplitude 搜索中,此时必须走 grep 兜底,并通过事件键去 Redash(Reload 侧)查询。
  2. projectIdapp 字段填同一个值query_dataset 示例中 projectId(顶层)与 definition.app 都填 get_context 得到的 sentry.io 项目 appId
  3. 计数口径先看 countGroup。"多少人"用 metric: "uniques" + countGroup: "User";"多少次"用 metric: "totals"trackAmplitudeEvent.tsxAmplitude.setUserId(user?.id ?? null) 说明 User 维度对应 Sentry 用户 ID,同一用户跨组织切换时 organization_id group 会随之更新。
  4. 事件是否真的会发到 Amplitude,取决于调用点传没传 organization。从源码结构看,rawTrackAnalyticsEventorganization_id === undefined 时跳过 Amplitude 通道(rawTrackAnalyticsEvent.tsx),因此查询结果偏少时,除了核对事件名,还应检查埋点调用点的组织上下文是否完整。
  5. 本地调试埋点:在浏览器 localStorage 设置 DEBUG_ANALYTICS = 1makeAnalyticsFunction.tsxrawTrackAnalyticsEvent.tsx 都会 console.log 出完整的事件参数,便于在跑 MCP 查询前确认 eventName 与属性值。

小结

这套工作流的价值在于把"产品数据问题"转化为一条确定的工具链:get_contextprojectIdsearch 找事件名(无果则 grep static/app/utils/analytics/)→ get_properties 看可过滤属性 → query_dataset / query_chart 取数 → 以"事件名 + 时间范围 + 独立用户数"的口径汇报。理解了 Sentry 埋点"事件键 → 名称映射 → Reload/Amplitude/Pendo 三通道"的底层管线后,Amplitude 查询结果的每个数字都能回溯到具体的一次 trackAnalytics 调用,查询与代码互为印证。

登录后查看全文
热门项目推荐
相关项目推荐