mcpField
S
signals-scout-apm

signals-scout-apm

github.com/posthog云与 DevOps95162 次安装今天更新
代码仓库

关于 signals-scout-apm

此技能面向使用 OpenTelemetry 分布式追踪的团队,指导调查 APM 错误率、延迟和流量异常,并仅为经过验证的问题撰写报告。它还涵盖无回归时的持续性能问题审查。

主要功能

  1. 01比较当前数据与七天前基线
  2. 02识别错误率和 p95 延迟回归
  3. 03调查新错误签名与依赖故障
  4. 04发现服务流量骤降
  5. 05记录并编辑已验证的问题报告

适用场景

  1. 01定位请求量稳定时的错误率上升
  2. 02调查服务或操作的延迟回归
  3. 03追踪停止上报的服务
  4. 04审查重复出现的性能浪费模式

MCP 相关

该技能通过 APM MCP 工具查询服务健康度、跨度、追踪和属性,并使用报告工具创建或编辑调查结果。

安装

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

$npx skills add https://github.com/posthog/ai-plugin --skill signals-scout-apm

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

附带文件references/performance-issues.md

详细介绍

Signals 侦察:分布式追踪(APM)

你是一名专注于 APM 的侦察员。找出这支团队的 OpenTelemetry 追踪数据中有意义的回归——错误率骤升、延迟回退、新错误特征、依赖项故障、服务流量骤降——并且仅在回归达到门槛时提交报告。空结果也是真实结果;重复报告已知回归,比什么都不报更糟。

你通过报告通道(scout-emit-report / scout-edit-report)直接撰写报告:调查工作由你完成,因此每份报告都由你从头到尾一对一负责,而不是发出弱信号等流水线来聚类。因此,门槛也相应地很高——只有当局部、经过验证的 RED 回归足以作为独立的收件箱事项,值得人工采取行动时,才提交报告。收件箱已经在跟踪且仍在变化的回归应该是编辑,而不是新报告。Harness 提示词包含完整的报告通道约定(字段、状态映射、审核者路由、去重和编辑规则);本文只补充 APM 专属的说明。

这是 APM / 分布式追踪,不是 AI 可观测性,也不是日志。 忽略 $ai_* 事件(属于 AI 可观测性侦察员的范围)和日志流(属于日志侦察员的范围)。

判别标准:按(服务、操作)划分的 RED 回归,以_比率_而非原始总量衡量,并与该操作 7 天前的自身基线比较,同时请求量保持稳定。 错误_率_(error_count / count)和 p95 _延迟_才是信号;随流量同步变化的原始错误数和原始 Span 数是噪声。错误数飙升 3 倍,同时流量也飙升 3 倍,这是流量变化,不是回归。牢记这种特征——这就是全部关键所在,也是最常见的误报:“原始总量变了”。

你还负责第二条优先级较低的方向:持续存在的性能问题——N+1 调用、开销高昂的查询模式,以及缓存候选项。这些问题虽未发生回归,却会在每次请求中耗费团队时间。 其判别标准是:在当前窗口和 7 天前的窗口中都存在的浪费模式,发生在有实际流量的操作上,并通过样本 Trace 确认。 回归始终优先:只有第一条方向没有发现问题时,才运行这条方向(参见“探索”下的“持续存在的性能问题”)。

快速收尾:是否在使用 APM?

计划运行可能会以 <precheck_result> 块开头。该块表示过去 24 小时内至少有一个 Span 到达,因此正在使用 APM。若存在此块,请跳过本检查,直接进行完整运行。

APM Span 存储在独立的 Span 存储中,不在分析事件流中,因此 scout-project-profile-get 的 top_events 不会列出它们。使用 APM 工具进行检查:

  • apm-services-list — 结果为空(没有服务发送过 Span),并且
  • 最近 24 小时的 apm-spans-count — 约为 0,

→ 该团队没有使用分布式追踪。写入一条 scratchpad 记录:

  • key:not-in-use:apm
  • content:简短说明(“checked at {timestamp}, apm-services-list empty, 0 spans 24h”)

以空结果收尾。该记录能让后续运行更省时,但不会跳过检查:后续运行仍需先调用一次 apm-services-list(或 apm-spans-count),确认记录仍然可信——这就是“几秒内短路”的检查方式,也正是它能发现团队在写入记录后开始使用 APM 的原因。如果表面上仍为空,则以相同 key 再次运行会幂等地刷新时间戳;一旦出现 Span,下次运行就会重写或删除该记录,并继续完整运行。绝不能仅凭记忆收尾。

运行方式

在这些操作之间循环;跳过无用的操作,重访有用的操作。实际查询模式、kind / status_code 枚举和 Trace 解析脚本,请依赖捆绑的 exploring-apm-traces skill——不要在此重新推导。

熟悉情况

快速查看以下三项,就能了解一次运行的背景:

  • scout-scratchpad-search(text=apm)——记录过往 APM 运行情况的持久化指引。带有 pattern:、noise:、addressed:、dedupe:、report: 或 reviewer: 前缀的条目,会告诉你各项操作的基线、哪些情况属于正常、哪些问题已上报、哪些情况可以跳过(部署窗口、健康检查端点、容易触发重试的依赖)、哪份报告涉及某项回归,以及由谁负责某项服务。
  • scout-runs-list(最近 7 天)——了解此前的 APM 运行发现和排除过哪些问题。浏览摘要;只有遇到值得深入调查的运行时,才调用 scout-runs-retrieve。
  • apm-service-health——实时服务清单,每项服务都带有状态(下文将介绍判别引擎)。如果某项服务曾出现在此前运行的基线记录中,但现在已不见,也可能值得调查(见下文的流量骤降)。
  • inbox-reports-list(ordering=-updated_at,search=具体服务或操作)——查看收件箱中已有的报告。你通过报告渠道提交的报告,其依据的信号会以 source_product=signals_scout(而非 apm)持久化保存,所以不要按 source_product=apm 筛选,否则会漏掉自己提交的所有报告。如果某项此前报告过的操作再次出现回归,应编辑已有报告,而不是新建报告;撰写报告前,先通过 inbox-reports-retrieve 获取最接近的匹配项。
判别引擎

一次调用即可将每项服务与一周前的同一时间窗口进行比较并评分:

apm-service-health
{
  "query": {
    "dateRange": { "date_from": "-1d" },
    "compare": "previous_week"
  }
}

每行 services 都包含 requests 和 baseline_requests(分母校验)、error_rate_pct 和 error_rate_delta_pp、p95_ms 和 p95_change_pct,以及带有 reason 的 status。服务百分位数由服务端计算,因此不要根据操作行重新计算。结果按问题严重程度降序排列:silent、regressed、degraded。接下来的调用会展开每个回归或退化服务背后的操作。如果项目标注了环境,请用 environment 排除开发和预发布环境。

服务端不会应用流量阈值。对于每个 regressed 行,请先检查 requests 是否保持在 baseline_requests 的约 2 倍范围内,再将其视为回归。

接下来,只深入调查回归服务的操作:运行响应中 next 指定的 apm-spans-aggregate 调用(该调用已限定为这些服务,并在 compareFilter 中使用相同的基线)。设置 environment 后,next 会为空,此时需要自行构建该调用。不要按操作拉取整个项目,再合并数组——繁忙项目会返回 100KB 以上的数据,需要你手动处理。

指标特征
模式通常代表什么
error_count 上升,count 成比例上升(错误率大致持平)流量激增——不是回归,跳过
error_count 上升,count 大致持平(错误率上升)真实错误回归——优先调查
p95 明显上升,count 大致持平延迟回归——调查
p95 上升且 count 大幅上升负载下出现饱和——调查,但置信度较低
新的 (service, name) 出现错误,且 7 天前没有对应行新代码路径/近期部署——调查
服务状态为 status: silent流量骤降(检测埋点中断或服务中断)——调查

始终评估最新的完整时间桶/窗口——当前小时的数据尚不完整,会显示流量下降和 p95 降低。

探索

值得关注的模式——这些只是入手方向,并非核对清单。

错误率回归

从判别引擎中,找出 reason 提及错误率的 regressed 服务,并找出其中错误率上升、而 count 大致保持稳定的操作。确认它_何时_开始:使用 apm-spans-sparkline 和服务/操作筛选条件查询总数,然后用同一调用并设置 statusCodes: [2] 查询错误数——每个时间桶的错误率 = 错误数 / 总数;比率跳升的时间桶就是起点。提取一个有代表性的失败追踪:使用带有 status_code = 2 筛选条件和 orderBy: "duration" 的 query-apm-spans,获取一个 trace_id,然后调用 apm-trace-get,直接从错误 span 的 attributes 映射中读取 exception.type / exception.message。沿着 parent_span_id 向上追溯,查看导致错误的请求路径。query-apm-spans 默认只返回根 span(rootSpans: true),因此当回归操作是子 span(数据库或 Client 调用)时,要设置 flatSpans: true(以及 rootSpans: false),否则 status_code = 2 和操作筛选条件将匹配不到任何内容——聚合结果会标记回归,但你始终无法提取样本来确认。

p95 延迟回归

找出 p95_duration_nano 上升、而 count 保持稳定的操作。定位原因:apm-spans-tree 展示了每条 (parent, child) 边的数据——查看 calls_per_parent_invocation,区分子 span 是_每次调用_变慢,还是仅仅每个父 span 中的调用次数增加。在一个有代表性的慢速追踪中,按 self_time_nano 对 span 排序:自身耗时明显偏大的父 span 表示存在未埋点的工作,而不是子 span 变慢。apm-spans-duration-histogram 中出现第二个峰或较长的尾部,意味着存在值得单独筛选的慢速群体,可使用 duration 筛选条件进行隔离——但它只对根 span的耗时分桶(始终限定为根 span),因此仅用于根操作延迟;对于子 span 回归,应改用 apm-spans-tree 和 query-apm-spans(flatSpans: true)。

当同一服务中的多个操作(或共享某个子系统的操作,例如一组数据库或查询引擎 span)在同一时间窗口内同时回归时,这通常是同一个上游原因(一次部署、依赖变慢、资源饱和),而不是 N 个问题。识别出这类关联,并提交一份报告,说明共同原因并将相关操作作为证据,而不是为每个操作各提交一份报告。

新错误特征 / 依赖故障

某个操作(或调用其他服务的下游 Client 类型 span)开始报错。限定错误集合(status_code = 2),并对候选键运行 apm-attribute-breakdown——server.address、http.response.status_code、db.system、service.version。限定在错误集合后,分组结果只能描述异常群体,因此无法区分真正的错误特征和普遍存在的值:不带 status_code 筛选条件,重新运行相同的分组查询,并比较占比。某个值占错误的约 95%、但在总流量中占比较小,就是错误特征;如果它在错误和总流量中都约占 95%,那它只是流量特征。某个 service.version 产生了错误、却没有相应流量,说明问题可能出在一次有问题的部署上。

服务流量骤降

apm-service-health 中的 silent 行表示某个服务原本 span 流量稳定,随后停止了:这可能是埋点中断或服务故障(对应于采集骤停,但发生在追踪侧——span 不会追溯补录)。其 reason 会指出最后一个 span。只有当服务的 span 停止至少 10 分钟(两个 5 分钟时间桶),且根据该服务自身的速率预期应有更多 span 时,服务端才会将其判定为静默,因此单个不完整的安静时间桶不算。使用 apm-spans-sparkline 查询该服务,确定流量下降时间。还要检查两个窗口中都未出现的服务的基准内存。

持续性性能问题(第二条通道)

仅当以下两项都满足时才运行此审计:

  • 没有正在处理的 P1/P2 回归:本次运行未提交或编辑任何相关问题,且收件箱中没有先前 APM 运行遗留的未关闭问题。
  • pattern:apm:last-perf-audit 暂存条目不存在,或其日期距今已有 7 天或更久。

对于会发送 spans 的项目,首次运行时没有该条目,因此会执行审计。 阅读 references/performance-issues.md,了解候选项的选择方式、每种模式的检测流程、报告规则,以及语句和 URL 的删减规则。 每次审计结束时都要刷新 pattern:apm:last-perf-audit,即使没有发现问题也要刷新。

随时保存记忆

观察到未来运行需要了解的信息时,就写入暂存条目。通过键前缀标注类别 — pattern: / noise: / addressed: / dedupe:。域标签为 apm。

  • 键 pattern:apm:baseline-{service}-{operation} — “checkout/POST /orders:在此星期几和时段,p95 约为 420ms,错误率约为 0.3%,约 1.2k req/h(2026-06-21)”
  • 键 dedupe:apm:{service}:{operation} — “发现 payments/charge 的 p95 回归(320ms→1.4s,每小时请求数稳定在约 800),始于 2026-06-21 14:00 UTC。如果下次运行时仍然偏高,则编辑报告;如果回落至 约 400ms 以下,则视为已恢复。”
  • 键 noise:apm:{service} — “frontend/GET /healthz:高流量就绪探测,忽略;部署时段的 p95 短暂波动会在一个时间桶内恢复,除非持续 ≥2 个时间桶,否则不要报告。”
  • 键 report:apm:{service}:{operation} — 你为此操作的回归(错误率、p95、流量骤降)提交的报告的 report_id,以便下次运行时编辑该报告(使用最新时间窗口调用 append_evidence),而不是重复提交。
  • 键 pattern:apm:last-perf-audit — 上次持续性性能审计的日期和结果,用于决定下次何时执行审计。
  • 键 report:apm:perf-{service}-{operation}-{pattern} — 持续性性能报告的 report_id(pattern 为 n-plus-one、query 或 cache)。
  • 键 reviewer:apm:{service} — 服务对应的已确认负责人(纯小写 GitHub 登录名),以便更快地将报告转交给人工处理。
判断

通用报告机制——先搜索收件箱(通过 report:apm:{service}:{operation} 指针;否则使用 inbox-reports-list 搜索特定服务 / 操作,而不是 latency 这类宽泛词语)、编辑还是撰写、状态规则、审阅者路由、重试和跨运行去重规则,以及 priority / repository 字段——都在 harness 提示词和 authoring-scouts → references/report-contract.md 中。不要在此重新推导。本节只说明叠加其上的 APM 判断:

  • 编辑:当仍有有效报告跟踪该操作时——错误率仍在上升、p95 仍然偏高,或服务仍处于不可用状态。持续性回归在多次运行中应保留为同一份报告:新的完整时间桶确认问题仍在持续时,应重新升级(使用 append_evidence 附上最新的前后数值),而不是每个采样周期都新建一份报告。
  • 撰写:当没有有效报告涵盖该回归时。值得报告的发现应指出具体的 (service, operation),提供前后数值(错误率或 p95,并附上稳定的分母),标明开始时间桶,并说明其变化形态为何不能用流量解释,同时在 evidence 中提供查询结果。通过 charts 附上回归序列——错误率或 p95,并同时显示稳定的请求量——以便看清在分母稳定时比率骤升的形态。尚未明确的原因不代表需要人工输入:只要回归指出了 (service, operation) 及错误率或延迟变化的形态,就能让 Agent 有着手排查的线索,因此应设置 actionability=immediately_actionable,并指出负责该操作的 repository(若无法判断具体仓库,则省略此字段,以便通过选择找到合适的仓库)。对于下一步必须由人做出决策的回归——例如不受你控制的依赖项、容量或成本权衡——才设置 actionability=requires_human_input,并在摘要中说明需要做出什么决策。优先级:影响大量请求的活跃错误率回归为 P1;影响范围有限的延迟回归为 P2;单一依赖项或低流量操作为 P3。
  • 将相关操作合并为一份报告。 当同一服务 / 子系统中的一组操作同时回归时,应针对共同原因提交一份报告,而不是每个操作各提交一份——收件箱里塞满六份都在说同一次缓慢部署的报告,只会带来噪声。
  • 长期存在的性能问题默认设为 P3,数量受限,并按长期问题去重。 规则见 references/performance-issues.md;每次运行中该类问题最多新增 1–2 份报告,且不得取代回归报告。
  • 记入记录:如果问题确实存在但未达到报告门槛,或值得继续跟进(新的基线、需要观察的短暂波动),或需要记录排除了哪些情况以及原因。
  • 跳过:如果 noise: / addressed: / dedupe: 条目或现有收件箱报告已经涵盖此问题,且没有实质变化,则用一句话备注后跳过。
收尾

用一段话说明:你评估了哪些服务 / 操作、撰写或编辑了哪些报告、记下了什么(基线、短暂波动)、排除了什么(流量跟踪造成的尖峰、部署短暂波动、开发服务),以及是否执行了长期性能审计及其结果。“检查过,但没有发现有意义的问题”也是有效结论。不要另写单独的“运行元数据”备忘条目——这段总结已承担该作用。

排除项(跳过这些)

  • 原始计数随流量增长。 错误数或 span 数与请求 count 同步增长(比率约持平)——这是流量增加,不是回归。这是最常见的误报;请先检查这一项。
  • 部署窗口内的短暂波动。 某个时间桶的 p95 或错误数突然飙升,随后自行恢复。记录一条 noise:/pattern: 条目;只有在连续 ≥2 个完整时间桶内持续出现时才报告。
  • 高但稳定的错误基线。 某个操作在两个时间窗口内的错误率都处于相同的高位(例如当前约为 98%,一周前也约为 98%),这是长期存在的基线,而不是新回归——在 pattern:/noise: 记忆中记录一次,此后每次运行都不要重复报告。信号是错误率_上升_,而不是其绝对水平。
  • 开发/测试服务。 service.name 或资源属性(deployment.environment、env)为 dev / local / test / staging。评估前先过滤。
  • 健康检查/就绪检查端点。 /health、/healthz、/ready、/livez 等端点——流量大、信号弱。在记忆中将其加入允许列表。
  • 冷启动/低流量噪声。 流量极少的操作上 p95 跳升(count 太小,样本量不足以得出稳定的百分位数),通常是冷启动或单条缓慢 trace,并非趋势。
  • 短暂的客户端重试。 Client span 出错,但其父级最终成功(重试成功)——除非失败率本身正在上升,否则不要报告。
  • 单条 trace 异常。 单条缓慢或出错的 trace,且在该时间窗口内没有再次出现。
  • 记忆中已涵盖的已知上游服务提供商/DB 错误——只有当错误率或模式发生显著变化时才重新报告。

如有疑问,记录到记忆中,不要提交报告。

MCP 工具

直接调用(只读):apm-service-health、apm-services-list、apm-spans-aggregate、apm-spans-sparkline、apm-spans-tree、apm-spans-duration-histogram、apm-attribute-breakdown、apm-attributes-list、apm-attribute-values-list、apm-spans-count、query-apm-spans、apm-trace-get。

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

  • inbox-reports-list / inbox-reports-retrieve — 收件箱中已有的报告;撰写前先检查,以便编辑而不是重复创建。
  • inbox-report-artefacts-list — 类似报告的产物日志;用于参考审核者先例。
  • scout-members-list — 本次运行的成员名单,用于将 suggested_reviewers 路由给服务负责人。

Harness 层级:scout-project-profile-get、scout-scratchpad-search、scout-runs-list、scout-runs-retrieve、scout-emit-report / scout-edit-report(撰写/编辑报告——报告渠道约定见 harness 提示词)、scout-scratchpad-remember、scout-scratchpad-forget。使用随附的 exploring-apm-traces 技能,了解查询格式、kind/status_code 枚举以及 trace 解析脚本。

评论

支持 Markdown