关于 signals-scout-observability-gaps
面向产品团队的可观测性差距侦察技能,比较事件活动与现有洞察、仪表板和告警,并直接提交有依据的建议报告。强调去重、覆盖核验与低信号时空结果关闭。
主要功能
- 01检查事件与观测覆盖差距
- 02识别洞察漂移和告警缺失
- 03核验事件量、覆盖与重复项
- 04直接撰写或编辑建议报告
- 05记录团队模式以供后续运行
适用场景
- 01发现高频事件尚无洞察覆盖
- 02排查洞察引用的事件已停用
- 03查找失败类事件缺少告警
- 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或queryJSON 中提及该事件名称的洞察。匹配模式: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 处理。你独有的切入点始终是结构性的_覆盖缺口_,而不是其上的异常。
暂缓,随后撰写 — 监控生命周期
大多数好的建议不会在发现问题的那次运行中提交,而是先暂缓,直到达到稳定性门槛。生命周期如下:
- 暂缓 — 写入一个
watch:observability_gaps:<gap>条目,其中包含判别条件(确认这确实是缺口所需的具体检查)、目前为止的数量证据,以及最早的文件时间(第 7 个完整项目时区日结束的时间)。未来的运行会继承该候选项,而不是重新推导。 - 实时重新验证,然后撰写 — 达到门槛的那次运行必须在撰写前,使用实时数据重新检查每一项判别条件(覆盖可能已经出现,数量也可能骤降)。切勿仅凭 watch 条目提交。
- 设防 — 撰写后,使用
report_id更新 watch 条目,并设置约 30 天的去重期:在此期间不得重复报告,除非出现实质性的新角度。写入report:observability_gaps:<gap>指针,让下一次运行编辑而非重复提交,并将已确认的负责人缓存到reviewer:observability_gaps:<area>。 - 退役 — 条目不会永久保留。覆盖出现后,说明建议已得到落实:删除该条目(或将其转换为
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 个高质量缺口并为其提交报告 → 即使还有其他内容可以调查,也应结束。质量优先于数量——建议是一项预算,而不是目标。
“调查过,但没有发现有意义的内容”也是有效结果,并非失败。每条未被采纳的建议,都能少一个误报侵蚀收件箱。