关于 ga-use
ga-use 面向营销人员,将自然语言分析需求转为 GA4 Data API 报告并解读结果。它用 Python 脚本处理确定性查询,并依据事件和字段信息映射分析请求。
主要功能
- 01自然语言提出 GA4 报告需求
- 02映射事件与参数
- 03执行 GA4 Data API 查询
- 04解读并整理结果
- 05检查分类表与事件活动
适用场景
- 01查看流量或事件指标
- 02分析转化漏斗与用户路径
- 03调查表现变化
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ogaeng/ ga4-skill --skill ga-use安装后在 Claude Code 中输入/ga-use确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
requirements.txtreferences/analysis-guide.mdanalysis-recipes.mdscripts/ga4_cohort.pyga4_common.pyga4_funnel.pyga4_metadata.pyga4_pivot.pyga4_query.pyga4_realtime.pyga4_reporting.py详细介绍
GA4 分析与查询技能(ga-use)
将营销人员的自然语言分析请求转换为 GA4 Data API 报告并作答。
确定性工作由 scripts/ 中的 Python 脚本完成;你负责将请求映射为查询,
并解读结果。
语言
使用用户的语言作答。如果用户用韩语提问,就用韩语作答; 如果用户用英语提问,就用英语作答。每个步骤都适用此规则,包括设置指导、 进度更新、结果和错误说明。
不得翻译:GA4 API 标识符(eventCount、sessionSource、runReport)、
文件和目录名称(.ga4/token.json)、shell 命令和 JSON 字段名称。
不得将脚本输出原样展示给用户。 脚本始终输出英文的
error/hint 字符串。当脚本返回 "ok": false 时,必须先将
hint 改写为用户所用的语言,再展示给用户。切勿直接粘贴英文,也不得展示原始 JSON。改写时,标识符、路径和命令必须保持原样——只翻译周围的说明文字。
示例——脚本返回: {"ok": false, "hint": "token.json is missing. Log in first with the ga-auth skill."} 对使用韩语的用户,应这样说: 登录信息(.ga4/token.json)不存在。我会先使用 ga-auth 技能登录。 不要这样说:"token.json is missing. Log in first with the ga-auth skill."
解释器规则
ga4_query.py、ga4_realtime.py、ga4_pivot.py、ga4_cohort.py、ga4_funnel.py、ga4_metadata.py:必须使用.ga4/venv/bin/python运行(需要 google-analytics-data){SKILLS_DIR}= 安装这些 GA 技能的目录,即当前技能目录的上级目录 (Claude Code 项目中的.claude/skills;其他 Agent 使用各自的位置)。 请替换为实际路径。请从项目根目录运行命令。
第 0 步:状态检查(始终首先执行)
检查 .ga4/,确定从哪里开始:
config.json(property_id)和token.json是否存在?如果不存在,指导用户先使用 ga-auth 技能进行连接。- 依赖库是否已就绪?如果
python3 {SKILLS_DIR}/ga-auth/scripts/ga4_status.py返回的deps_ready为false,此技能会自行运行配套的deps_fix命令(“我会安装此分析所需的依赖库”),并在继续之前重新检查——不要要求营销人员运行 pip。如果为null,则说明检查本身失败;不要假设依赖库缺失,直接继续。 taxonomy.md是否存在?- 如果存在,读取它,并将请求映射到事件/参数。
参数表中的 Query Name 列必须原样使用——
method (standard)表示查询method,不加前缀;(metric)表示它属于metrics;Not registered — cannot query表示不要查询,并告知用户需要先注册。仅凭名称猜测customEvent:会导致 400 错误。Reserved name — cannot be registered or queried与上述情况不同:不要要求注册该参数。 GA4 会拒绝保留名称和前缀(user_id、session_id,以及任何以google_/firebase_/ga_/_开头的名称),因此请求会被拒绝,而且无法通过 Data API 查询该值。应明确说明这一点,而不是让营销人员联系管理员。customEvent:x — prefer standard y表示使用y。 GA4 对该参数有标准字段,而自定义定义不会包含注册之前的数据——因此,自定义字段会悄然漏掉标准字段完整涵盖的较早时间段。只有当标准字段没有返回任何结果时,才回退使用customEvent:名称。 较旧的taxonomy.md文件可能仍保留含义相同的韩语标签(조회명= Query Name,미등록 — 조회 불가= Not registered)——使用 ga-taxonomy 重新解析工作表会将其更新为英文标签。 - 分类表描述的是预期行为,而非实际发生的情况。 基于映射的事件进行分析前,先检查它在所请求时间段内实际触发的次数(执行一次
eventName×eventCount查询即可)。实际情况是,31 个分类条目中有 14 个在过去 30 天内没有任何命中,有些即使在 90 天内也只有个位数——不了解这一点就构建漏斗,可能会令人信服地报告“3 项中完成 1 项 → 完成率 33%”这类毫无意义的数字。样本量较小时,报告原始计数而非百分比,并说明原因。 - 如果不存在,分析之前先调查事件概况:使用
limit50 或更高的值查询eventName×eventCount/activeUsers,查看此属性包含哪些事件,然后再映射请求。如果响应中的truncated: true,就提高 limit 并重新查询(缺失事件可能意味着缺少某项核心行为)。
- 如果存在,读取它,并将请求映射到事件/参数。
参数表中的 Query Name 列必须原样使用——
custom_definitions.json是否存在?(由 ga-taxonomy 创建)- 如果存在,读取它。用它将分类中的参数转换为实际查询名称(
customEvent:...)和单位——详情请参阅references/analysis-guide.md中的 “Custom Definitions” 部分。 - 如果不存在,可以在
ga4_metadata.py get-metadata的结果中查找以customEvent:、customUser:或customItem:开头的条目,并以相同方式使用。
- 如果存在,读取它。用它将分类中的参数转换为实际查询名称(
平台上下文
状态检查会报告 platforms——此属性收集数据的平台,使用 GA4 自身的拼写(web、iOS、Android 或 unknown)。这会影响哪些事件和维度可能存在,因此在判断某项内容缺失之前,请先查看该字段。
null表示从未查询过。不要假定平台。 猜测平台正是这个字段要防止的错误。重新运行.ga4/venv/bin/python {SKILLS_DIR}/ga-auth/scripts/ga4_admin.py get-property <PROPERTY_ID>并通过 ga-auth 技能的第 4 步中的第 4 和第 5 项保存结果:保存操作会从头重建config.json,因此必须在同一命令中再次传入币种、时区和保留期限,否则它们会变成null——这会导致 ga-use 无法获知其报告收入所用的币种(实时响应完全不包含元数据),也会丢失空漏斗检查所依据的保留期限。[]表示该属性没有数据流——它没有收集任何数据。unknown条目表示某个数据流无法分类,因此列表并非完整答案。存在unknown时,不要把缺少web解读为“仅限应用”:应说明该属性无法分类,而不是据此判断其仅限 Web 或仅限应用。- 如果
platforms_age_days大于 180,列表可能早于团队后来添加的平台。依赖该列表之前,请重新检查。 platforms表示已配置的数据流;platform维度表示实际到达的流量。已配置的数据流仍可能没有数据,因此不要把其中一种情况说成另一种。
分析流程
- 确认需要进行哪种分析(指标、时间段、细分维度、过滤条件)。
- 如果这是一个复合问题(对应配方中的问题类型——转化分析、路径/旅程、效果摘要(概览)、变化诊断、内容效果或行为重要性比较),请先阅读
references/analysis-recipes.md并规划查询(要组合什么、为什么组合、如何组合)。 对于目标数量可能较少的分析(转化、细分),先检查规模,并根据references/analysis-recipes.md中的样本量门槛设定分析深度。 - 将请求映射到实际事件/参数名称——使用步骤 0 收集的信息
(
taxonomy.md,如果没有则使用查询到的事件列表)。 - 如果不确定维度/指标,请查询元数据——使用
--search缩小范围:
一个属性公开约 400 个维度和约 120 个指标,因此未筛选的转储约有 12k 个 token;使用.ga4/venv/bin/python {SKILLS_DIR}/ga-use/scripts/ga4_metadata.py get-metadata --search item--search查询单个字段约有 150 个 token。--search可重复使用 (保留匹配任意搜索词的条目),并会匹配 API 名称或 UI 名称。--kind dimension|metric会移除另一个列表。筛选后的响应会包含一个filtered键,其中列出 未筛选结果的总数——如果存在该键,说明你看到的并非完整目录。 - 构建扩展 JSON 规范并执行查询(格式见
references/analysis-guide.md):echo '<request JSON>' | .ga4/venv/bin/python {SKILLS_DIR}/ga-use/scripts/ga4_query.py - 将结果整理为表格或摘要并作答。若结果为空或出现错误,请根据
references/analysis-recipes.md中的重试循环进行处理。 如果truncated为 true,你看到的只是顶部的一部分——不要将其描述为“总数”;应提高limit并重新查询,或注明这是“基于前 N 项”的结果。 如果漏斗结果包含steps_without_data,则该步骤在响应中没有对应的行 (GA4 会省略触达量为零的步骤,因此通常意味着零——但不要自行推断,请原样传递)。
工作原则(关键)
目标受众是非技术营销人员:
- 将工作拆分成小步骤,并在每一步用一句话说明“做什么/为什么”。
- 尽可能自行处理文件放置和命令执行。
- 将自然语言转换为 JSON 规范是 Claude 的工作——绝不要要求营销人员提供 JSON。
常见请求模式
-
Top-N:
order_bys(desc)+limit。例如,按计数统计事件数前 10 名。(透视表按轴分别设置,因此应使用pivots[].order_bys/pivots[].limit。) -
按
dimension排序采用的是 GA4 的字典序,而不是数值或日历顺序。hour/minute不会补零,因此此脚本会自动为这两个维度请求 NUMERIC 排序类型,无需额外操作。dayOfWeekName和appVersion也有同样的问题,且服务端无法修复(前者是文本,后者是多段字符串;NUMERIC 排序类型同样无效——两者均经实时测量确认),因此会通过note发出警告:对于dayOfWeekName,请按dayOfWeek(0=Sunday..6=Saturday)排序,并保留名称用于显示;对于appVersion,没有可替代的维度——请自行解析每个版本号中以点分隔的部分,将其作为整数对返回的行排序。其他任何看起来像数字的维度(包括自定义维度)也可能存在同样的问题——安全维度的完整列表请参见references/analysis-guide.md。 -
不要通过对各行求和来获取总计。 以
~Users结尾的指标和sessions都是去重值——对各维度的行求和会使结果高于真实总值(在实时资源中测量:将一个月的每日activeUsers相加,结果比真实总值高出 13%)。由于另一个原因,费率和平均值也不适合求和:它们从未去重,对各行进行加总或平均在算术上都不成立。如果响应包含non_additive_metrics/note,则此规则适用——注释会说明每项指标适用的具体原因,而不是把所有情况都归咎于去重。如果需要总计,使用相同的时间段再次查询,但不指定dimensions。像eventCount这样的计数型指标可以安全求和。 -
totalUsers和activeUsers不可互换。totalUsers统计记录过事件的所有用户;activeUsers则要求存在互动信号,因此两者通常不同(实时测量:同一时间段内分别为 99 和 124,相差 25%)。GA4 自带的*PerUser指标(sessionsPerUser等)除以的是activeUsers,而不是totalUsers——不要用totalUsers手动计算“人均”数据后声称结果更准确;请使用 GA4 已提供的指标,或者在必须手动计算时使用activeUsers。 -
dauPerMau/dauPerWau/wauPerMau不适用上述“无维度 = 安全总计”规则。 这些是逐日滚动比率;当时间段超过一天时,GA4 自带的无维度聚合值是每日数值之和,而不是整个时间段的比率——经实时测量确认,结果完全一致(6 天查询的无维度总值与手动求和的同日数值相同,精确到双精度)。如果响应中的注释提到这些指标,请改为请求单日指标,或按date拆分并分别读取每天的数据。 -
基于收入的表达式指标可能返回原始收入,而不是比率。 单独请求类似
totalRevenue/eventCount(平均订单价值)这样的表达式时,返回的是totalRevenue本身,除非metrics中也列出了totalRevenue(经实时测量确认——只有包含收入指标时,GA4 才会计算该表达式)。如果响应包含expression_revenue_operands,请添加该收入指标后重新查询;读起来像大额总值的“比率”就是这种情况。基于非收入指标的表达式(eventCount/sessions)不受影响。自动检查只会捕获以Revenue结尾的指标——其他金额指标(itemRefundAmount、advertiserAdCost)不会被标记,因此也请将它们与表达式一并请求。 -
报告收入时,务必注明货币。 响应中的
metadata.currency_code是资源的报告货币——绝不可假定它与所在国家或使用的语言相符。 一个时区为Asia/Seoul的实时资源使用 USD 报告数据;若将这些数据解读为韩元,结果会相差约 1300 倍,且响应中的其他信息都不会提示这一点。metadata.time_zone是资源的时区,“今天”会依据该时区确定。 -
metadata可能会说明这些数值不适合引用。sampling: true表示数值是基于部分数据得出的估算——请说明这一点,也不要把数值之间的小幅差异当作真实差距。subject_to_thresholding: true表示 GA4 为保护隐私而隐藏了部分行,因此总计只是下限。data_loss_from_other_row: true表示数值被合并到(other)中,细分数据缺失的部分规模未知。 -
经过抽样的表达式可能会扭曲其原始操作数。 如果抽样响应包含
expression_sampling_overlap,则同时以原始形式和表达式形式(例如totalRevenue/eventCount)请求的事件级收入指标(totalRevenue、purchaseRevenue)返回值会远低于真实总值(实测相差约 13 倍)。不要引用此响应中的原始数据列——请在不包含表达式的情况下重新查询,或缩小查询范围以避免触发抽样。(商品级的itemRevenue和计数型指标不会偏移,也不会被标记。) -
按日(或按月)统计的序列可能缺少行。 如果某行中的所有请求指标均为零,GA4 就会丢弃该行,因此按
date查询收入时,零销售额的日期会消失;yearMonth维度的粒度高一层,也会发生同样的情况(经实时测量:12 个月的订阅收入查询只返回了其中 4 个月)。如果响应包含missing_dates,这些行表示实际值为零,并非数据缺失——计算平均值时请将它们纳入(仅除以返回的行数会导致结果偏高),也不要让趋势线跨越这些日期直接连接。 -
(not set)不是一个类别。 如果响应包含unset_dimensions,表示 GA4 未收到这些行对应的值。切勿将其报告为排名第一的项目——在一个实时资源中,“按收入统计排名最高的优惠券”将(not set)排在首位,意思是“未使用优惠券”。如果某个维度列在fully_unset下,则所有行都没有值:事件已触发,但应用或网站从未附加该参数,因此应报告为追踪缺口,而不是展示细分结果。 在将fully_unset判定为追踪缺口之前,请先检查平台。 如果某个维度不适用于此属性的数据流,那么即使实现完全正确,它也会始终返回(not set)。只要 config.json 中记录了platforms,响应就会自行完成这项检查,涵盖 24 个维度:Web 数据流一侧包括 9 个成员的页面维度系列、browser/browserVersion,以及完整的 12 个成员的增强型衡量系列(出站点击、文件下载、视频、滚动);应用数据流一侧则包括appVersion。这些维度会分别列在unset_dimensions.platform_mismatched下,且note会说明“这是预期情况,不是追踪缺口”,而不会归咎于应用或网站。不过,以下三种情况下检查不会给出提示,因此仍需自行应用上述判断:完全没有记录
platforms;其中包含unknown(无法分类的数据流意味着列表并不完整,因此不会据此判断 Web/应用平台——请参阅上文关于platforms的说明);以及这 24 个维度之外完全未设置的维度(包括unifiedScreenName——它是跨平台维度,因此其中真实存在的缺口不会被标记;searchTerm和contentGroup系列也一样,因为这两个平台都需要手动埋点)。这里有三个系列,而非两个。
pagePath、pageTitle和landingPagePlusQueryString是 Web 数据流维度;appVersion属于应用数据流;而unified*系列——unifiedScreenName(其 UI 名称为“页面标题和屏幕名称”)、unifiedScreenClass、unifiedPagePathScreen——是跨平台维度:在 Web 数据流中承载页面标题/路径,在应用数据流中承载屏幕名称/类别。screenPageViews是同时统计两者的指标。不存在screenName维度:请求该维度会直接失败,返回400 ... Field screenName is not a valid dimension。- 仅应用:页面维度系列在每一行都为
(not set)——这属于维度系列不匹配,而非追踪缺口。请改用unified*系列。如果unifiedScreenName也完全未设置,说明应用没有发送屏幕名称参数,而unifiedScreenClass仍会包含自动收集的类别名称(在一个仅应用的线上属性中测得:unifiedScreenName完全为(not set),而unifiedScreenClass返回了实际屏幕)。在漏斗中,第一步是screen_view,而非page_view。 - 仅 Web:这里的
unified*系列有值——这些行是真实的页面标题和路径,切勿将其误认为应用产生的数据而丢弃,也不要绕开该系列。真正缺失的是应用范围的数据:appVersion和应用屏幕参数都没有可供其取值的数据流。 - 混合平台:应用部分的
pagePath为(not set),Web 部分的appVersion为(not set),而且两者都正确——都不应报告为缺口。若要查看跨平台数据,请使用unified*系列;若要分别查看两部分,请按platform维度细分(或筛选至单个平台),并说明数据涵盖的是哪个平台。
- 仅应用:页面维度系列在每一行都为
-
0 可能表示“从未跟踪”。 如果响应包含
uninstrumented_metrics,该指标的读数为 0,是因为此媒体资源从未记录过其背后的事件——而不是因为没有发生任何事情。应将其报告为跟踪缺口(“应用或网站从未发送过refund事件”),切勿将其报告为业务结果(“没有退款”)。后一种说法会用一个错误事实结束对话,营销人员还会据此采取行动。该键会列出所有可能填充此指标的事件——请引用这份列表,因为应用上的购买事件会记为in_app_purchase,而非purchase。如果存档的事件清单已经过时,说明会采用保留措辞(“可能表示未跟踪”)并要求刷新清单;请保留这种不确定性,不要报告数据无法支持的确定结论。 -
指标也可能因为此处不存在对应的流类型而读数为 0——这是第三种情况,与“从未跟踪”不同。
scrolledUsers(以及未来任何类似指标)依赖仅适用于 Web 的 GA4 增强型衡量事件,且没有对应的应用流事件,因此在仅有应用流的媒体资源中,它只能是 0——这不是添加事件就能修复的跟踪缺口,也不是业务上的 0。如果响应包含platform_mismatched_metrics,请明确说明这一点,不要套用前两种说法。 -
购买次数为 0 时仍有购买收入,说明这是订阅收入。 如果
purchaseRevenue/grossPurchaseRevenue不为 0,而所有请求的购买次数/购买者指标均为 0,响应会包含subscription_revenue。在应用商店订阅类应用中,GA4 会将app_store_subscription_*事件计入收入和transactions,但不会计入购买次数,因此这些 0 是设计如此,并非数据缺口。请将这笔收入报告为定期订阅收入,不要据此计算平均订单价值:这种情况下purchaseRevenue/ecommercePurchases会返回 0,看起来就像订单价格为 0。 -
漏斗为空可能是数据保留期限所致,而非转化次数为 0。 保留期限会限制漏斗和探索,但不会限制标准报告,因此对于超出保留期限的时段,
ga4_funnel.py会无报错地返回 0 行,而ga4_query.py对同一时段则能正常作答。在一个 14 个月的媒体资源上进行测量时,2025 年 1 月的漏斗没有返回任何数据,而runReport返回了 783 个add_to_cart和 136 个purchase。如果响应包含beyond_retention_days,请说明漏斗无法查询那么久之前的数据,并用查询核实事件——绝不要报告为转化次数为 0。适用于此情况时,steps_without_data说明本身已经使用了委婉表述(不再断言“通常意味着用户数为 0”),但仍应优先说明保留期限,而不是先提缺失步骤。没有beyond_retention_days并不代表一切正常——如果从未记录保留期限设置,该字段同样不会出现。此时空漏斗会附带一条说明,指出无法执行检查;请转述这一点,并用ga4_query.py核实,而不是报告为 0。使用 ga-auth 重新选择媒体资源即可记录该设置。 -
漏斗细分结果包含汇总行。 如果响应列出了
reserved_total_row_indexes,这些行不是类别。对于实际的细分维度(funnel_breakdown),RESERVED_TOTAL行已经等于其相邻行的总和,因此把所有行相加会使实际总数翻倍。对于时段对比(2 个或更多date_ranges,且包含dateRange表头),情况则相反:在多个对比时段内都活跃的用户会在总计中只计一次,但会在相邻的每个时段行中分别计数,因此各行总和可能超过总计——无论如何都不要预期两者相等;只需在展示排名或总量占比时排除汇总行。RESERVED_(other)行属于第三种情况——它表示折叠后的长尾数据,应计入总量,但无法进一步细分。 -
最近两天的数据仍在变化。 GA4 需要 24–48 小时完成处理,因此结束于
today或yesterday的时段数据还会变化。如果响应包含unsettled_ranges,绝不要将近期下滑报告为真实下降——应说明数据仍在处理中,或将时段结束日期设为2daysAgo。“昨天的收入下降了 30%”就是典型例子:营销人员可能会因为一个明天就会变高的数字而暂停营销活动。 -
时段对比:给
date_ranges传入两个时段,dateRange列就会显示各时段的对比。两个时段长度必须相同,且较新的时段应结束于yesterday,而非today——7daysAgo..today有 8 天,而14daysAgo..8daysAgo只有 7 天;并且今天尚未结束,因此两者之间的“上升/下降 X%”部分只是多了一天造成的。响应会包含date_range_lengths,并在时段长度不同时发出警告。如果还按date进行细分,GA4 会为每个时段返回每个日期,并将各时段之外的日期填为0——这些 0 表示“此时段不包含该日期”,因此绝不要对返回的所有行取平均值。 -
筛选器:
dimension_filter(复合与/或/非、部分匹配、列表)、metric_filter(数值条件)。
实时快照(最近 30 分钟)
对于“当前有谁正在使用应用或网站”或“刚刚发生了什么”(使用单独的端点)等实时问题,请使用 ga4_realtime.py:
echo '<request JSON>' | .ga4/venv/bin/python {SKILLS_DIR}/ga-use/scripts/ga4_realtime.py
minute_ranges可缩小时间范围(省略时为最近 30 分钟)。- 实时报告可用的维度/指标有限(country、deviceCategory、eventName、minutesAgo 等 / activeUsers、eventCount、keyEvents、screenPageViews)。大多数标准报告维度/指标都无法用于实时报告。
- 在这些指标中,
activeUsers不能与其他任何指标组合使用(与 eventCount、keyEvents、screenPageViews 配对时都会失败,而这些指标彼此之间可以自由组合)。脚本会在本地拒绝此类配对——请拆分为两个实时查询,并并列报告数值。 - 筛选/排序语法与
ga4_query.py相同(references/analysis-guide.md),但不存在date_ranges/offset——传入这些参数会被拦截并报错(查询过去时段请使用ga4_query.py)。
交叉表(透视报告)
对于两个或更多轴的交叉表分析,例如“按国家 × 设备”或“按渠道和设备交叉统计”,请使用 ga4_pivot.py:
echo '<request JSON>' | .ga4/venv/bin/python {SKILLS_DIR}/ga-use/scripts/ga4_pivot.py
pivots数组中的每一项代表一个轴(field_names、limit、order_bys、metric_aggregations)。轴维度也必须列在顶层的dimensions中。GA4 要求每个轴都设置limit——省略会返回 400 错误,而不是不设上限的结果——因此缺少limit时会自动设置默认值(单个轴:GA4 建议的 10000;多个轴:会相应调低,以使所有 limit 的乘积保持在 GA4 的 250000 上限内);也可以显式设置,以限制某个轴(例如,设置为5以获取前 5 项)。如果某个轴的值超过其 limit,pivot_axes[].truncated会说明这一点。- 请求
metric_aggregations(TOTAL、MINIMUM、MAXIMUM、COUNT)会在响应中添加aggregates行(总计等)——但仅当pivots至少有 2 项时才会添加。实际测试确认:只有一个透视轴时,GA4 会静默地不返回任何aggregates(也不会报错)。添加一个任意维度的第二个透视轴即可启用此功能。如果在单个透视轴上请求metric_aggregations,响应现在会包含一条note,说明总计已被静默丢弃以及如何修复——不要手动累加各行来计算总计。说明中会指出原因:轴被截断(常见情况——见pivot_axes[].truncated)意味着行本来就未涵盖所有值;而去重后的指标(用户数、会话数)即使轴未截断,计算结果也会偏高。说明会指出实际适用的原因,而不会一概归咎于去重。 - 响应中的
pivot_axes提供各轴独立的截断信息(returned_values、total_row_count、truncated,顺序与pivots相同)。如果有任何轴被截断,顶层的truncated也会变为 true,因此应将该轴描述为“基于前 N 项”,而不是“总计”。returned_values是该轴上的值数量,与顶层的row_count(交叉组合行数)不同。某个轴包含多个维度时,total_row_count表示组合数量——如何描述请参见references/analysis-guide.md。 - 筛选语法与
ga4_query.py相同,但排序和行数限制均按轴设置(pivots[].order_bys、pivots[].limit)。不能使用顶层的order_bys/limit——传入这些参数会被拦截并报错。
群组(留存)报告
对于“6 月第一周注册的用户中,有多少人每周都会回来”这类留存问题,请使用 ga4_cohort.py:
echo '<request JSON>' | .ga4/venv/bin/python {SKILLS_DIR}/ga-use/scripts/ga4_cohort.py
简写(单个群组)示例:
{
"granularity": "WEEKLY",
"date_range": {"start_date": "2026-06-01", "end_date": "2026-06-28"},
"offsets": {"start": 0, "end": 4},
"dimension": "firstSessionDate",
"accumulate": false
}
- 必须提供
granularity(DAILY/WEEKLY/MONTHLY)、date_range(群组获客时段)和offsets(要观察的经过时间窗口,{start,end})。偏移量从获客周(第 0 周)开始计算,因此不能为负数,而且start必须<= end— 反向窗口不会匹配任何周,GA4 会以零行且不报错的方式响应,这会被理解为“没有留存”;现在这两种情况都会在本地捕获。dimension(默认值为firstSessionDate)是可选的。accumulate必须保持为 false —true需要使用runPivotReport,而此脚本从不使用它,因此 GA4 总会拒绝该请求;现在会在本地捕获。要获得累计总数,请自行将各偏移量的cohortActiveUsers相加。 - 如需同时比较多个群组,请使用完整控制模式,直接指定
cohort_spec(cohorts、cohorts_range、cohort_report_settings)。 cohort/cohortNthDay/Week/Month维度和默认指标 (cohortActiveUsers)会自动注入。禁止使用顶层date_ranges— 群组应使用date_range/cohort_spec。- 过滤器和排序语法与
ga4_query.py相同(references/analysis-guide.md)。 - 日期只能使用绝对日期(
2026-06-01)。 GA4 不接受其他报告支持的相对日期 (28daysAgo、today)用于群组报告。 - 如果请求的偏移量对应的窗口尚未完全经过,响应中可能完全没有该行 — 这与回访用户数为零无法区分。出现这种情况时,响应的
note会说明(例如,周群组的第 3 周仍在进行中时的偏移量 3);不要将缺失的近期偏移量报告为“留存率为 0%”。
漏斗(转化/流失)报告
对于“从 page_view → add_to_cart → purchase 的逐步转化/流失”这类有序步骤分析,请使用 ga4_funnel.py:
echo '<request JSON>' | .ga4/venv/bin/python {SKILLS_DIR}/ga-use/scripts/ga4_funnel.py
简写示例:
{
"steps": [
{"name": "Page view", "event_name": "page_view"},
{"name": "Add to cart", "event_name": "add_to_cart"},
{"name": "Purchase", "event_name": "purchase"}
],
"date_ranges": [{"start_date": "28daysAgo", "end_date": "yesterday"}],
"funnel_breakdown": {"dimension": "deviceCategory", "limit": 5}
}
- 至少需要 2 个
steps,且每个步骤必须恰好定义以下其中一项:event_name/field(+value|in_list)/filter_expression(完整控制模式)。 funnel_breakdown(可选)按特定维度(设备、渠道等)细分各步骤的流失情况。细分结果可能全部为(not set)— 事件已触发,但应用或网站从未附加该参数。如果子报告包含unset_dimensions.fully_unset(或顶层note指明存在跟踪缺口),则该细分不包含任何信息:应将其报告为缺少埋点,而不是转化结果。(混入细分结果的汇总RESERVED_TOTAL行不计入此检查;它们列在reserved_total_row_indexes下。)funnel_visualization_type(默认值为STANDARD_FUNNEL;时间序列趋势请使用TRENDED_FUNNEL)决定funnel_visualization是否包含date轴 — 无论哪种情况,两个子报告都会填充 — 详情请参阅references/analysis-guide.md。趋势漏斗的每日趋势可能会缺少某些步骤的行,这与普通每日序列的“GA4 删除零值行”问题相同(见上文要点)— 在计算平均值或绘制趋势图之前,请检查funnel_visualization.missing_dates_by_step(或顶层note)。- 包含 2 个条目的
date_ranges会比较两个时间段,与ga4_query.py相同 — GA4 会附加一个dateRange维度,并将其视为funnel_breakdown(经实时验证),包括汇总行:请预期会出现RESERVED_TOTAL行,并应用上文相同的“汇总前排除”指导。也可以同时使用此项和funnel_breakdown(经实时验证)— 两个轴会生成交叉组合(步骤 × 你的细分维度 × dateRange),而且reserved_total_row_indexes会正确捕获在任一轴上属于 RESERVED_TOTAL 的行,无需特殊处理。
文件位置
config.json(property_id)和token.json由 ga-auth 技能创建和管理。taxonomy.md由 ga-taxonomy 技能创建。GA4_DIR环境变量可以更改.ga4的位置(默认值:<cwd>/.ga4)。