PostHog Paths 指标排查实战指南:用路径图定位导航行为变化(Paths Playbook 深度解析)
【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog
导读:本指南围绕 PostHog 产品分析模块中的 Paths(路径)洞察展开,聚焦"从 X 到 Y 的路径变了""出现了新的主导路径"这类形状型(shape)指标异常排查。读完你将掌握:如何用
posthog:query-paths做等长区间对比、如何用趋势查询拆解端点流量、如何分段验证路径差异、以及如何结合录制与错误追踪交叉验证结论——整套方法论来自 products/product_analytics/skills/investigate-metric/references/paths-playbook.md,并由仓库源码与 Schema 定义提供底层佐证。
为什么 Paths 是"形状指标"而不是"数值指标"
当用户报告"从 X 到 Y 的路径变了""出现了不同的主导路径"时,先要意识到这与其他指标的差异。Paths 洞察描述的是用户在事件之间的导航流转形态,变化通常体现为边(edge)的流量迁移,而不是某个标量数字的单一移动。这一点决定了排查手段:
- 不能只盯一个聚合值,要观察边(source → target)的进出量变化;
- 需要成对的时间区间对比才能定义"变了";
- 结论往往要靠分段(segment)、录制(recordings)与错误日志交叉验证,而不是无限跑查询。
在仓库实现中,Paths 查询的产物正是"边"的集合。paths_query_runner.py 的to_query()方法以last_path_key AS source_event, path_key AS target_event, COUNT(*) AS event_count的形式聚合出每条边及其事件量,并按event_count DESC排序返回——这就是"dominant path(主导路径)"概念的数据来源。
一、确定"变了":等长区间双跑对比
为什么不能直接加 compareFilter
PathsQuery不支持compareFilter(对比过滤器)。这一点在文档中明确指出,也与 Schema 定义一致:查看 posthog/schema.py 中的PathsQuery模型,它包含dateRange、pathsFilter、properties、samplingFactor、filterTestAccounts等字段,但没有compareFilter字段。同样地,TrendsQuery/StickinessQuery支持compareFilter: {"compare": true},而 Paths 需要自己跑两次查询。
双跑示例(JSON 查询体)
第一次查询,取最近 7 天,路径起点为/home、终点为/checkout,只统计$pageview类型事件,最多返回 50 条边:
posthog:query-paths { "kind": "PathsQuery", "dateRange": { "date_from": "-7d" }, "pathsFilter": { "includeEventTypes": ["$pageview"], "startPoint": "/home", "endPoint": "/checkout", "edgeLimit": 50 } }第二次查询,取等长的前一个 7 天窗口:
posthog:query-paths { "kind": "PathsQuery", "dateRange": { "date_from": "-14d", "date_to": "-7d" }, "pathsFilter": { "includeEventTypes": ["$pageview"], "startPoint": "/home", "endPoint": "/checkout", "edgeLimit": 50 } }对比两组结果的边集合,找出哪条边获得了流量、哪条边丢失了流量(gain / lost volume)。窗口等长是关键前提——不等长的窗口无法直接比较边权重。
参数语义(结合源码核实)
| 参数 | 类型 | 默认值 | 语义 |
|---|---|---|---|
kind | string | "PathsQuery"(必填) | 查询类型标识 |
dateRange.date_from/date_to | string | 无 | 支持相对写法(-7d)与绝对日期 |
includeEventTypes | array | 空(含所有事件) | 参与路径的事件类型,见下方PathType枚举 |
startPoint | string | 无 | 只保留从该节点开始的路径 |
endPoint | string | 无 | 只保留在该节点结束的路径 |
edgeLimit | int | 50 | 返回的最大边数 |
以上默认值可在 PathsFilter 定义 中直接核实:edgeLimit: int | None = 50、stepLimit: int | None = 5。而PathType枚举在 posthog/schema_enums.py 中定义:
class PathType(StrEnum): FIELD_PAGEVIEW = "$pageview" FIELD_SCREEN = "$screen" CUSTOM_EVENT = "custom_event" HOGQL = "hogql"在 paths_query_runner.py 的_get_event_query()中可以看到这四个类型的底层翻译:
$pageview→event = '$pageview',路径节点取自$current_url(URL);$screen→event = '$screen',路径节点取自$screen_name;custom_event→NOT startsWith(events.event, '$'),即排除所有以$开头的自动捕获事件;hogql→ 使用pathsHogQLExpression自定义表达式。
两个补充细节(源码佐证):
- URL 尾部斜杠会被剥离。
construct_event_hogql()中对$pageview应用了replaceRegexpAll(ifNull(properties.$current_url, ''), '(.)/$', '\\1'),同时_strip_trailing_slash()会对startPoint/endPoint做同样的归一化,保证查询值与存储值匹配(见 paths_query_runner.py)。因此传入/checkout/与/checkout效果一致。 - 边权重过滤。
minEdgeWeight/maxEdgeWeight会在外层查询的HAVING子句中生效(get_edge_weight_exprs()),用于剔除低流量噪声边或高流量主干边;edgeLimit则作为最终LIMIT(见 paths_query_runner.py)。
底层执行链路(便于深入阅读)
PathsQueryRunner的核心流水线是:
paths_events_query():筛选事件并按事件类型归一化出path_item;paths_per_person_query():按person_id用groupArray聚合路径,再按会话阈值(默认 30 分钟,SESSION_TIME_THRESHOLD_DEFAULT_SECONDS)切分会话、压缩连续重复节点(compact_path),并定位startPoint/endPoint;to_query():将每个人的路径拆成相邻边source_event → target_event,COUNT(*)计数、avg(conversion_time)计算平均转换时长,最后按event_count降序返回。
其中"同人会话切分"由get_session_threshold_clause()实现:arraySplit(x -> if(x.3 < 1800, 0, 1), paths_tuple),即同一用户两次事件间隔超过 30 分钟即视为新会话(paths_query_runner.py)。理解这一点对解读结果很重要:路径是会话内的导航序列,跨会话跳转不会被连成一条边。
二、先检查端点自身流量:"A → B 下降"可能只是 A 或 B 下降
"从 A 到 B 的路径掉了"最常见的假象是:端点本身(A 或 B)的流量掉了,路径图只是被动地反映这一点。此时再深的路径分析都是多余的。
做法:对每个端点事件单独运行posthog:query-trends:
posthog:query-trends { "kind": "TrendsQuery", "dateRange": { "date_from": "-14d" }, "interval": "day", "series": [ { "kind": "EventsNode", "event": "$pageview", "properties": [{ "key": "$current_url", "operator": "exact", "value": "/home" }] }, { "kind": "EventsNode", "event": "$pageview", "properties": [{ "key": "$current_url", "operator": "exact", "value": "/checkout" }] } ] }判断逻辑:
- 如果 A 或 B 自身的趋势发生了移动 → 进入该事件对应的趋势 playbook(trend-playbook.md)排查,而不是继续在路径上纠缠;
- 如果两端都稳定,而路径边的流量在变 → 问题确实出在中间导航环节,路径分析才真正有价值。
这与漏斗 playbook 的思路一脉相承:FunnelsQuery的步骤 2 也要求"先区分是入口(entries)掉了还是完成(completions)掉了",参见 funnel-playbook.md。
三、确认工具选型:问的是转化率就别用路径
路径洞察回答的是形状(shape)问题:用户在页面/事件之间怎么走、在哪分叉、主流路线是否漂移。它不是转化率工具。
- 如果用户的实际问题是"转化率下降了""某一步流失增加了" → 正确做法是构建漏斗(Funnel),并转入 funnel-playbook.md。漏斗 playbook 还反过来利用路径:它的步骤 5 建议用
posthog:query-paths且endPoint指向失败步骤,观察"没能走到该端点的用户去了哪里"——这正是两个洞察的互补用法。 - 如果问题是"用户从 X 到 Y 的路线怎么变了""主流路径变成了什么" → 才是 Paths 的用武之地。
在指标分类上,这属于 investigate-metric 技能 的 Step 1——先读query.kind判断指标类型:PathsQuery路由到 paths playbook,FunnelsQuery路由到 funnel playbook,TrendsQuery路由到 trend playbook。判断错工具,整个排查方向就错了。
四、分段验证:路径形状是否因用户群体而异
为什么不支持 breakdownFilter
AssistantPathsQuery(Agent 使用的路径查询变体)不支持breakdownFilter。查看 schema.py 中的 AssistantPathsQuery,其字段包含aggregation_group_type_index、dateRange、filterTestAccounts、pathsFilter、properties等,同样没有breakdownFilter。PathsQuery/PathsFilter也没有 breakdown 能力——路径洞察本身是"一条主流路径",而不是"多维度分桶后的多条路径"。
用顶层 properties 过滤 + 分段重跑
正确的分段做法是:通过查询顶层的properties字段过滤,然后对每个分段重新跑一次路径查询:
posthog:query-paths { "kind": "PathsQuery", "dateRange": { "date_from": "-7d" }, "properties": [ { "key": "$geoip_country_code", "operator": "exact", "value": "US", "type": "person" } ], "pathsFilter": { "includeEventTypes": ["$pageview"], "startPoint": "/home", "endPoint": "/checkout", "edgeLimit": 50 } }properties在 Schema 中被定义为list[AnyPropertyFilterDiscriminated] | PropertyGroupFilter | None(schema.py),支持事件属性、Person 属性、分组属性等过滤维度,并在 paths_query_runner.py 中通过property_to_expr()翻译成 SQL 的WHERE条件(注意:这是顶层过滤,作用在整个查询上,等价于对每个 segment 重跑)。
何时该做分段:当路径形状在不同浏览器 / 国家 / 套餐(plan)之间出现剧烈差异时,这本身就是"变化是分段特定(segment-specific)"的有力证据——例如某个国家因为落地页改版走了完全不同的路线,而整体主流路径没变。
文档还提示了另一条更轻的路径:先跑一次全量查询,如果发现主流边变了,再针对可疑分段(如某个$browser或app_version)重跑验证,而不是一开始就对每个维度穷举。
分段维度的优先序参考
shared-patterns.md 给出了候选维度的大致信号强度排序,可直接套用:
$feature/<flag_key>—— 功能开关发布后信号最强;$browser、$os、$device_type、$geoip_country_code—— 平台 / 地区问题;app_version、$lib_version—— SDK 回归;is_identified、$is_first_session、plan / tier —— 用户状态问题;- 自定义事件属性 —— 通常最有诊断性。
五、录制 + 错误追踪:让证据闭环
录制:比继续跑查询更快
当发现新的主导边出现(例如用户开始大量从/home→/pricing→/signup),Pull 这段路径上用户的会话录制(session recordings),往往比继续跑查询更快暴露 UI 变化:
- 用
posthog:query-session-recordings-list拉取符合受影响分段的录制列表; - 用
posthog:session-recording-get获取单条录制详情。
这与 shared-patterns.md 中"Session recordings"一节的建议一致:对于 UI 形态导致的下降,看三到四条录制通常比跑更多查询快。例如某次改版后按钮位置变了、某个步骤加了新表单,用户的行为路径会立即在录制中显现。
错误追踪:交叉验证"分叉点"
在用户开始分叉(diverge)的页面上,用posthog:query-error-tracking-issues-list检查是否存在错误。但要警惕:错误只是候选,不是结论。按 shared-patterns 中的三条确认标准验证:
- 时序(Timing):错误量是否与指标变动对齐;
- 机制合理(Plausible mechanism):错误是否真的影响该指标表面(例如提交接口的 500 可以导致用户放弃该步骤,而控制台 warning 通常不能);
- 用户重叠(User overlap):报错的用户是否与走新路径/流失的用户重叠。
任一条不满足,都应把错误标记为巧合并继续排查。
找到根因后的收尾动作
按 investigate-metric SKILL.md 的 Step 5,调查结论应写入标准格式(Anomaly / Likely cause / Confidence / Evidence / Possible causes ruled out / Affected segment / Data gaps / Suggested follow-ups),并主动提供:
posthog:insight-create—— 保存关键图表;posthog:annotation-create—— 在根因时间点打标注,供后续对比引用。
六、常见坑与速查
| 场景 | 正确做法 |
|---|---|
| "A→B 路径掉了" | 先查 A、B 端点自身趋势(第 2 节),再进路径排查 |
| "转化率下降了" | 路径是错的工具,改用漏斗 playbook(第 3 节) |
| "某个分段的路径形状不同" | 用顶层properties过滤后逐段重跑(第 4 节) |
| "新的主导边出现了" | 拉录制看 UI、查错误追踪交叉验证(第 5 节) |
| 需要比较两个周期 | 等长窗口双跑,对比边 gain/lost(第 1 节) |
| URL 带尾部斜杠匹配不上 | 无需处理,服务端自动归一化(见_strip_trailing_slash) |
相关文档导航
- 主技能与整体流程:investigate-metric/SKILL.md(含 Step 1 指标分类 → Step 5 结论格式)
- 本 playbook 原文:paths-playbook.md
- 配套 playbook:funnel-playbook.md、trend-playbook.md
- 通用配方:shared-patterns.md(分段维度、录制、错误/日志交叉验证)
- 源码实现:paths_query_runner.py(查询流水线)、schema.py(
PathsQuery/PathsFilter/AssistantPathsQuery定义)、schema_enums.py(PathType枚举) - 测试用例:test_paths_query_runner.py(可对照学习各参数的实际行为)
【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考