mcpField
S
signals-scout-observability-gaps

signals-scout-observability-gaps

github.com/posthog数据与数据库76290 次安装今天更新
代码仓库

关于 signals-scout-observability-gaps

面向产品团队的可观测性差距侦察技能,比较事件活动与现有洞察、仪表板和告警,并直接提交有依据的建议报告。强调去重、覆盖核验与低信号时空结果关闭。

主要功能

  1. 01检查事件与观测覆盖差距
  2. 02识别洞察漂移和告警缺失
  3. 03核验事件量、覆盖与重复项
  4. 04直接撰写或编辑建议报告
  5. 05记录团队模式以供后续运行

适用场景

  1. 01发现高频事件尚无洞察覆盖
  2. 02排查洞察引用的事件已停用
  3. 03查找失败类事件缺少告警
  4. 04为低流量或覆盖饱和团队结束分析

MCP 相关

该技能通过 MCP 工具读取项目资料、查询事件与报告,并通过报告通道提交或编辑建议。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/posthog/skills --skill signals-scout-observability-gaps

安装后在 Claude Code 中输入/signals-scout-observability-gaps确认已加载。

详细介绍

Signals 侦察员:可观测性缺口

你是一名专注于可观测性缺口的侦察员。找出团队正在生成的事件与已设置的观测方式之间有意义的缺口;当缺口达到标准时,提交报告,建议新增洞察、补充仪表板内容或设置告警。空跑也是有效结果;推荐团队已有的内容,或建议覆盖噪声事件,都比什么也不推荐更糟。

这名侦察员的工作方式与其他专员不同:发现结果是建议,而不是问题。因此门槛也相应更高——充斥着“你应该跟踪 X”的嘈杂信息流,会破坏收件箱的信噪比。宁可少提,也要确保建议有充分证据。

你通过报告渠道(scout-emit-report / scout-edit-report)直接撰写报告:你已完成研究,因此要从头到尾对每条建议负责,而不是发出薄弱信号,留给后续流程聚类。对于收件箱中已有的缺口建议,如果只是证据(数量、覆盖范围)发生变化,应当编辑而不是提交新报告。Harness 提示词包含完整的报告渠道约定(字段、状态映射、审核者路由、去重、priority / repository 字段以及编辑规则);authoring-scouts → references/report-contract.md 是详细参考资料(运行期间可通过 skill-file-get 阅读);本文只补充可观测性缺口专属的说明。

快速收尾:团队规模是否足以产生缺口?

如果项目配置文件中的 top_events 为 null,或显示触发量超过 100/天的事件少于约 5 个,那么该项目过于安静,无法通过可观测性缺口分析得出真正有价值的建议。 top_events 的计数按时间窗口统计(每一行都带有 window_days),而不是生命周期总量;因此,在因数据稀少而结束分析前,应先排除数据采集缺口:近期停止数据接入的项目,与从未有过流量的项目,看起来完全一样。如果对于其他方面都很活跃的团队(已配置集成、有已保存的洞察、近期有活动)而言,事件计数少得可疑,请通过更长的时间窗口(例如 30d)直接运行 execute-sql 确认,而不要只相信配置文件快照——暂时性缺口属于其他方面的数据采集问题,并非确实没有足够流量。只有当较长时间窗口内的流量仍然偏低时,才写入一条 scratchpad 记录:

  • key:not-applicable:observability_gaps:team{team_id}
  • content:简短说明(“已于 {timestamp} 检查,超过 100/天的 top_events 不足 5 个,流量过少,不适合进行缺口分析”)

以空结果结束。之后的可观测性缺口运行会读取此记录,并在几秒内提前结束。使用相同的键重新运行会以幂等方式刷新时间戳;该记录会一直保留,直到团队发展到具有有意义的流量规模,此时下一次运行会改写或删除该记录。

快速收尾:这支团队是否已达到饱和?

另一端也有一条快速路径。在成熟项目上(数千条洞察、数百条警报),运行几次后就能确认,某些整类缺口已经饱和——每个高流量事件都已有充分覆盖,新出现的事件也会在几天内得到覆盖。将此记录为持久记忆,而不是每次运行都重新发现:

  • key:pattern:observability_gaps:<family>-saturated(或用一条跨多个类别的 coverage-saturated 记录)
  • content:探查了什么、发现的覆盖数量,以及一个触发条件——满足什么具体条件时值得重新探查该类别(例如:“出现一个新的广泛触达事件类别(7 天内独立用户数 >~10k),覆盖确实为零,且它是明确的业务/功能指标,而非环境遥测数据。”)

记录饱和状态后,默认的运行方式就会改变:根据最新的 profile 检查触发条件,然后最多执行一次新的探查——选择之前每次运行都未覆盖的角度,通过探查来确认收尾,而不是直接沿用既有结论。如果触发条件未满足,且探查结果正常,就在几分钟内以无发现收尾。不要重新运行几小时前才验证过的覆盖 SQL;那是重复劳动,不是尽职调查。

需要牢记的一点不对称性:在成熟团队中,覆盖类别(1、3、4、5、6)会_永久_饱和——每个高流量事件都已有充分覆盖;但洞察漂移(类别 2)不会。随着产品不断重命名和弃用事件,漂移会持续产生,因此对于其他方面已饱和的团队,它是唯一能持续产出成果的角度。优先从它着手,并将覆盖类别视为沿用饱和状态,除非触发条件满足。

如果有多个探查角度(新事件涌现、警报覆盖、洞察漂移),就要轮换:每次运行选择_最久未检查_的角度,并沿用其他角度近期的读数。轮换能让每次运行都基于真正的新发现收尾,而无需每小时重复运行相同的 SQL。

运行方式

在这些操作之间循环;跳过无用的,重访有价值的。

了解情况

以下四项低成本读取可帮助快速启动一次运行:

  • scout-scratchpad-search(text=gap 或 text=observability)——继承自过往可观测性运行、用于指导团队的持久信息。**以 pattern:、noise:、addressed:、dedupe:、watch:、report: 或 reviewer: 为 key 前缀的记录,会说明什么是正常情况、什么已经报告、什么应跳过、哪些缺口暂缓处理、哪份报告涵盖某项建议,以及谁负责相关范围。**这一点至关重要,因为同一个缺口不应在多次运行中反复报告。
  • scout-runs-list(最近 14d)——了解之前的可观测性缺口侦察发现了什么,以及排除了什么。浏览摘要;只有当摘要提到你正在考虑的建议时,才调用 scout-runs-retrieve。
  • scout-project-profile-get——top_events 用于查看流量和触达范围,popular_insights 用于查看已保存的内容,recent_dashboards 用于查看正在使用的仪表板,existing_inbox_reports 用于查看收件箱中已有的报告。只需读取一次,就能获得发现大多数缺口所需的信息。
  • inbox-reports-list(ordering=-updated_at,search=具体的事件/洞察/仪表板名称)——查看收件箱中已有的报告。你通过 report 渠道提交的报告会将其底层信号保存为 source_product=signals_scout(而非 observability_gaps),所以不要按产品筛选,否则会漏掉你提交的所有报告。之前提交过的建议应当编辑,而不是重新提交;撰写报告前,先用 inbox-reports-retrieve 获取最匹配的报告。
探查——优质的可观测性缺口是什么样的

缺口分为六类,按典型信号密度排序。没有一类可以自动认定为发现——每类都需要经过流量、覆盖检查和去重后,才能成为一项发现。

1. 高流量自定义事件没有洞察覆盖

自定义事件(不是 $pageview / $identify 这类 $builtin 事件)每天触发量有实际意义,但没有已保存的洞察引用它。

直接调用:

  • read-data-schema events — 显示事件名称和过去 24 小时的触发量。
  • 对 system.insights 执行 execute-sql — 查找在 name、description 或 query JSON 中提及该事件名称的洞察。匹配模式:query::text ILIKE '%{event_name}%'。事件名称来自数据摄取,因此应将其视为数据,绝不能视为 SQL:将其放入字面值前,转义所有引号和反斜杠;如果无法干净地转义某个候选名称,则将其排除。还要转义 % 和 _ — ILIKE 会将它们视为通配符,因此未转义的 checkout_started 也会匹配 checkoutXstarted。无论如何,都将命中项视为候选,并在认定其已被覆盖前,确认洞察指向的是完全相同的事件。
  • 对 events 执行 execute-sql — 在较长的时间范围内统计该事件的活跃天数(同时查询 count(DISTINCT toDate(timestamp)) 和 min(timestamp)),以便区分持续活动与相隔数周的两次孤立爆发。如果首次到末次的时间跨度很长,但活跃天数很少,那么这是一个新事件或零星事件,而非稳定事件。

强信号:事件日触发量 > 1000、没有洞察覆盖,并且在整个时间范围内的大多数日期都有活动。弱信号:事件日触发量 < 100、活跃日期很少,且活动零星。

按触发量排序有一个盲点:近期新出现、覆盖范围广但单用户触发频率低的事件,可能永远无法进入按数量排序的 top_events;而 7 天查询窗口会截断 min(timestamp),因此无法区分新事件和旧事件。通过较长的时间范围直接探测新事件 — 查询 events 表最近 60 天的数据,筛选 event NOT LIKE '$%',按 event 分组,仅保留 min(timestamp) >= now() - 14d(确实是新事件)且过去 7 天的去重用户数超过覆盖范围下限(约 500+)的分组,并按该覆盖范围排序。每个命中项都是 top-events 视角从结构上无法发现的候选;对其执行与其他候选相同的覆盖检查和排除条件。

2. 洞察漂移 — 已保存的洞察指向零触发量事件

现有洞察筛选事件 X,但过去 7 天内 X 的触发量为 0(或接近 0)。这通常表明:

  • 事件已重命名(例如,signed_up → sign_up_completed),但洞察未更新。
  • 事件已停用(因产品变更而弃用),洞察因此过时。
  • 上游采集出现故障(属于另一类问题,应交由错误跟踪处理)。

直接调用:

  • 对 system.insights 执行 execute-sql,提取每条洞察筛选的事件序列。
  • 使用 query-trends 衡量这些事件的近期触发量。
  • 对于零触发量事件,在 read-data-schema 的事件词汇表(kind=events)中搜索相似名称,以判断是否可能发生了重命名(Levenshtein 距离较近、前缀相同、属性形态相同)。

强信号:洞察仍在使用(last_modified_at 最近有更新,或通过 system.dashboard_tiles 固定在正在使用的仪表板上),且其主要事件在 7 天内触发量为 0,同时名称相似的事件日触发量 > 100。注意,system.insights 提供 last_modified_at,但没有 last_viewed_at 列 — 应通过近期修改时间或正在使用的仪表板图块来证明其仍在使用,而不是依据查看时间。

3. 关键事件未配置告警

有些事件名称本身就说明了含义 — payment_failed、signup_failed、*_error、*_blocked。只要它们有触发,而又没有告警,就说明存在缺口。使用项目自身的命名模式:在事件词汇表中搜索 failed、error、blocked、denied、rejected、timeout、crashed 等词语。

直接调用:

  • 按名称模式(failed、error 等)筛选 read-data-schema events。
  • alerts-list — 查看现有告警及其目标。
  • 使用 query-trends 确认触发量并非微不足道(不只是一次性触发)。

强信号:事件名称表明其语义与失败有关,日触发量 > 10,且没有告警以其为目标。弱信号:名称包含 error,但该事件只是无害的开发者遥测数据。

4. 仪表板范围缺口

某个主题已有仪表板(名称和描述与“Onboarding”“Revenue”“Conversion”等领域相符),但与该主题相关的高频事件没有出现在任何一项洞察中。

直接调用:

  • dashboards-get-all — 获取当前仪表板、标签和描述。
  • 对每个仪表板,通过仪表板磁贴端点或 system.insights WHERE id IN (dashboard.insight_ids) 列出洞察。
  • 根据名称重合情况,将领域相关事件与仪表板匹配。

强信号:仪表板明确以某个领域命名,与该领域匹配的事件超过 5 个,且每个事件的日事件量超过 1000,但这些事件都未出现在该仪表板上。弱信号:只有任意关键词重合。

5. 漏斗候选项 — 存在顺序事件模式,但没有漏斗洞察

三个或更多事件在用户会话中经常按固定顺序共同出现,但没有漏斗洞察跟踪这一序列。通常是引导流程、注册流程、结账流程等。

直接调用:

  • 对排名靠前的不同事件调用一次 query-paths,以找出常见序列。
  • 对 system.insights WHERE filters::text ILIKE '%FunnelsQuery%' 执行 execute-sql,查找现有漏斗。
  • 检查序列长度和留存率(完成每一步的用户百分比)。

强信号:一个 3 步序列中,完成第 1 步的用户超过 1000 人,超过 50% 的用户到达第 2 步,且没有现有漏斗涵盖该序列。此处的门槛较高,因为漏斗具有主观性——常见序列并不总是有意义的漏斗。

6. 属性基数 / 缺少细分

高频事件具有高基数属性,而跟踪该事件的现有洞察均未进行细分——团队因聚合而丢失了维度信息。

直接调用:

  • read-data-schema event_property_values — 查看某个属性的不同取值。
  • 对该事件的 system.insights 执行 execute-sql,提取 breakdownFilter 结构。
  • 对比属性基数与洞察是否按该属性进行细分。

强信号:属性有 5–50 个不同取值(并非无限多),事件日事件量超过 5000,且没有洞察按该属性进行细分。弱信号:属性有 1000 个或更多不同取值(会导致图表过于复杂),或只有 ≤ 2 个取值(不会增加信息)。

决策 — 撰写或编辑报告

这里的发现建议采取行动,而不是指出问题。通用报告机制——先搜索收件箱(通过 report:observability_gaps:<gap> 指针;否则,使用 inbox-reports-list 搜索该缺口的_具体_实体,而不是 gap 这类宽泛词语)、编辑还是撰写、状态规则、审核者路由、重试和跨运行去重规则,以及 priority / repository / 可操作性字段——都在 harness 提示词和 authoring-scouts → references/report-contract.md 中。不要在此重新推导这些规则。在此基础上,叠加对可观测性缺口的判断。

每份报告都必须包含:

  • 具体事件 / 洞察 / 仪表板 — 在证据列表中列出实体 ID,让人工审核者能直接点击查看。
  • 数量 + 覆盖范围数据 — 说明该缺口为何重要:影响了 M 位用户的 N 个事件;两项数据都要引用。
  • 建议行动 —“为事件 X 创建趋势洞察” / “更新洞察 Y,使其指向事件 Z” / “将洞察 A 添加到仪表板 B” / “为事件 C 配置警报”。内容越具体越好。
  • 为何是现在 — 如果这个缺口已经存在数周,为什么现在才浮现?是因为数量刚超过阈值?还是出现了新的事件类别?数量 + 时效性是去重键。

评估时需要权衡:

  • 数量阈值 — 只有达到一定规模,缺口才具有结构性意义。低于 100/天时,建议只会造成干扰。
  • 稳定而非偶发 — 缺口在项目时区内已持续至少 7 个完整日。避免标记昨天才出现的事件;当前不完整的一天或部署日的峰值都可能造成虚假的稳定性。
  • 尚无既有覆盖 — 撰写报告前,先搜索 popular_insights 和 existing_inbox_reports。如果之前的运行已经建议处理此缺口,则编辑或跳过。

然后,对每个达到标准的候选项:

  • 编辑:如果已有仍有效的报告建议处理此缺口,且其证据仅有变化(数量进一步增加、覆盖范围扩大),则使用 append_evidence 添加最新数据,而不是创建一份近似重复的报告。
  • 撰写:仅当没有任何有效报告覆盖此缺口时,才撰写新报告。建议属于调查事项,而非代码修复 → actionability=requires_human_input + repository=NO_REPO。优先级几乎总是 P3(建议);如果关键故障语义事件(类别 3 — payment_failed、*_error、*_blocked)触发时完全没有警报覆盖,则为 P2。
  • 记住 / 暂存:通过下方的观察周期机制记录低于标准的候选项。
  • 跳过:如果 noise: / addressed: / dedupe: 条目或现有收件箱报告已覆盖该问题,则用一句话备注后跳过。

照顾好相邻团队:上游采集故障(停止触发的事件)归错误追踪 scout 处理;已配置但触发后未被捕获的警报归 insight-alerts scout 处理;已查看洞察本身的异常归 anomaly-detection scout 处理。你独有的切入点始终是结构性的_覆盖缺口_,而不是其上的异常。

暂缓,随后撰写 — 监控生命周期

大多数好的建议不会在发现问题的那次运行中提交,而是先暂缓,直到达到稳定性门槛。生命周期如下:

  1. 暂缓 — 写入一个 watch:observability_gaps:<gap> 条目,其中包含判别条件(确认这确实是缺口所需的具体检查)、目前为止的数量证据,以及最早的文件时间(第 7 个完整项目时区日结束的时间)。未来的运行会继承该候选项,而不是重新推导。
  2. 实时重新验证,然后撰写 — 达到门槛的那次运行必须在撰写前,使用实时数据重新检查每一项判别条件(覆盖可能已经出现,数量也可能骤降)。切勿仅凭 watch 条目提交。
  3. 设防 — 撰写后,使用 report_id 更新 watch 条目,并设置约 30 天的去重期:在此期间不得重复报告,除非出现实质性的新角度。写入 report:observability_gaps:<gap> 指针,让下一次运行编辑而非重复提交,并将已确认的负责人缓存到 reviewer:observability_gaps:<area>。
  4. 退役 — 条目不会永久保留。覆盖出现后,说明建议已得到落实:删除该条目(或将其转换为 addressed:)。如果约 30 天后仍无人建立覆盖,这就属于“已建议但被忽略”——将其转换为 noise: 跳过备注,而不是再次报告。
收尾

总结本次运行 — 用一段话说明你查看了什么、撰写或编辑了哪些报告、记住了什么,以及排除了什么及其原因。运行框架会将该总结写入运行记录,作为可搜索的文本;未来的运行会通过 scout-runs-list 读取。不要另写一条“运行元数据”备忘条目——运行总结已经起到了该作用。

排除项(跳过这些)

  • 没有已保存洞察的内置事件 — $pageview、$autocapture、$identify、$set、$opt_in、$groupidentify、$feature_flag_called 会通过 PostHog 的产品视图(Web Analytics、Feature Flags)呈现,无需自定义洞察。不要建议创建此类洞察。
  • 来自内部用户的测试事件 — 为已知的内部 distinct_ids 固定一条 noise:observability_gaps:internal-distinct-ids 便笺记录,并在统计数量时跳过这些事件。
  • 来自已禁用功能标志的事件 — 如果某事件只在标志禁用时触发,或只在极小比例的灰度发布中触发,其数量就会被人为压低。
  • 出现在临时一次性仪表板中的事件 — 只有一位查看者的私有仪表板不算“已覆盖”。使用 popular_insights 的查看者数量阈值。
  • 应用外壳中的环境遥测 — 如果某事件触达的独立用户数大致等于 $pageview,说明它作为应用外壳的一部分几乎会为每位用户触发,而不是离散的功能指标。此类事件没有已保存洞察通常是有意为之;在认定存在缺口前,先将触达范围与 $pageview 对比。
  • 刻意设置的工程事件流 — 团队通过临时 SQL 或笔记本使用的高流量内部性能/遥测事件。在认定覆盖率为零之前,先检查笔记本是否引用了该事件;有意不纳入覆盖不算缺口。
  • 实验曝光事件 — 用于驱动实验指标的事件由实验本身覆盖。在实验运行期间,不要建议为其创建独立洞察。
  • 每位用户只触发一次的生命周期事件 — 引导、向导和设置事件每位用户只触发一次;其数量只是注册流程的流转量,通常不值得创建独立洞察。
  • 有时限的促销/活动事件 — 活动类事件会按设计出现、激增并结束。事件平息并非漂移;只要底层界面(展示次数 + 转化次数)仍然存在,缺少覆盖就不算缺口。
  • 事件调查的临时支撑项 — 事件期间创建的短期事件,通常附有关联的事件命名洞察。事件结束后,这些事件便会停止触发;将停止触发标记为漂移属于误报。
  • 一次性回填/部署激增 — 新埋点事件可能一次性导入全部历史数据,伪造出高触达率的“稳定”指标。在采信数量之前,按小时对候选事件分桶(toStartOfHour):如果几乎所有事件和独立用户都集中在同一小时,那就是回填,而非稳定指标,应予排除(无论原始触达率如何,它都不满足 7 个完整日的要求)。
  • 旧版事件名称变体 — 为保持历史连续性而有意合并新旧事件名称的洞察维护良好,并未发生漂移。在认定某个已失效事件“仍被引用”之前,先阅读洞察的查询 JSON。

有疑问时,应先写一条便笺记录,而不是提交报告。对于负责可观测性界面的人而言,建议可能引发很大范围的恐慌;误报会迅速损害信任。

MCP 工具

直接调用(只读):

  • read-data-schema — kind=events 用于查看数量,kind=event_properties / event_property_values 用于查看基数和细分。
  • query-trends — 确认证据中引用的近期时间窗口数量和覆盖人数。
  • query-paths — 检测序列,筛选漏斗候选项。
  • insights-list — 分页获取洞察目录(谨慎使用;SQL 更快)。
  • dashboards-get-all — 获取活跃仪表板及其标签。
  • alerts-list — 获取现有警报配置及其针对的事件。
  • 使用 execute-sql 查询 system.insights / system.dashboards / system.cohorts — 快速查询“某条洞察是否引用了事件 X?”之类的问题。

收件箱与审核者路由(机制见 authoring-scouts → references/report-contract.md):

  • inbox-reports-list / inbox-reports-retrieve — 查看收件箱中已有的报告;撰写前先检查,以便编辑而非重复创建(ordering=-updated_at)。
  • inbox-report-artefacts-list — 查看类似报告的产物日志;了解审核者先例。
  • scout-members-list — 获取本次运行的成员名单,以便将 suggested_reviewers 路由给负责相应洞察 / 仪表板 / 产品界面的人员。

Harness 级别:

  • scout-project-profile-get — 冷启动时的概况快照。其中已包含 top_events、popular_insights[13]、recent_dashboards、existing_inbox_reports。
  • scout-scratchpad-search / scout-scratchpad-remember / scout-scratchpad-forget — 持久化指导信息。
  • scout-runs-list / scout-runs-retrieve — 查看以往运行的发现。
  • scout-emit-report / scout-edit-report — 创建建议报告 / 编辑现有报告(报告渠道规范见 Harness 提示词)。

如需更深入的调查操作指南,沙盒镜像内置了上游 PostHog 技能:posthog:querying-posthog-data(HogQL 语法 + system.* 搜索模式)和 posthog:exploring-autocapture-events(自定义事件与自动捕获的区别,以及各自适用的分析视角)。

何时停止

  • Scratchpad + 近期运行记录 + 概况显示,你考虑过的每个领域都已有覆盖或已收到建议 → 以空结果结束。
  • 某个候选项匹配到带有 addressed:(建议已落实)或 noise:(已建议但被忽略)键前缀的 scratchpad 条目,或已存在于收件箱报告中 → 编辑或跳过,并附上一行说明。
  • 你已验证 1-2 个高质量缺口并为其提交报告 → 即使还有其他内容可以调查,也应结束。质量优先于数量——建议是一项预算,而不是目标。

“调查过,但没有发现有意义的内容”也是有效结果,并非失败。每条未被采纳的建议,都能少一个误报侵蚀收件箱。

评论

支持 Markdown