investigate-metric
Original:🇺🇸 English
Translated
2 scripts
Diagnose why a product metric changed (dropped, spiked, or plateaued) by orchestrating breakdowns, actors, paths, lifecycle, retention, and annotations queries. Use when the user reports an anomaly, asks "why did X change?", or needs root-cause analysis for a trend, funnel, retention, stickiness, or lifecycle metric.
12installs
Sourceposthog/ai-plugin
Added on
NPX Install
npx skill4agent add posthog/ai-plugin investigate-metricTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Investigating a metric change
For "why did X change?" questions about a saved insight, dashboard tile, or pasted query.
Don't load this skill for plain "what is X?" questions — only when there's an observed
change to explain.
Tools
Targets PostHog MCP v2. Typed query tools accept the query body directly — pass
, , as top-level fields, do not wrap in .
kindseriesdateRangeInsightVizNode| Tool | Purpose |
|---|---|
| Trends (count over time) |
| Funnels (multi-step conversion) |
| Retention (cohort return rates) |
| Stickiness (active days per user) |
| Lifecycle (new/returning/resurrecting/dormant) |
| Paths (navigation flow) |
| Users behind a trend bucket (trends source only) |
| HogQL — when no typed tool fits |
| Discover events, properties, sample values |
| Fetch a saved insight's metadata / data |
Plus the standard PostHog tools the playbooks reference by name (,
, , , ,
, , ,
).
feature-flag-get-allexperiment-get-allannotations-listquery-error-tracking-issues-listquery-logsquery-session-recordings-listcohorts-list/-createannotation-createinsight-createHelper scripts
- — auto-detects interval and compares recent values to the natural cycle (day-of-week, hour-of-week, or sequential). Use to resolve step 2.2 cheaply.
compare_to_prior_periods.py - — ranks breakdown segments by absolute delta and flags offsetting moves.
breakdown_attribution.py
bash
python3 scripts/compare_to_prior_periods.py < query_result.json
WINDOW=7 python3 scripts/breakdown_attribution.py < breakdown_result.jsonStep 1 — Classify the metric
Read from the source the user pointed at:
query.kind- Saved insight (URL, ):
short_id→posthog:insight-get. Usequery.kindif you also need the numbers.posthog:insight-query - A query you already ran or the user pasted: read directly.
kind - Nothing pointed at: ask for the URL or short_id. Don't guess.
| kind | Playbook |
|---|---|
| trend-playbook.md |
| funnel-playbook.md |
| retention-playbook.md |
| stickiness-playbook.md |
| lifecycle-playbook.md |
| paths-playbook.md |
| route by what the SQL aggregates (see below) |
If and , use
box-plot-playbook.md — distribution metric, no
breakdowns.
kind === "TrendsQuery"trendsFilter.display === "BoxPlot"For insights, classify by the SQL's shape: count over time → trend
playbook, multi-step conversion → funnel playbook, cohort return → retention playbook.
Run the SQL through to get the data, then follow the closest
playbook's steps. See HogQL insights in shared-patterns.md.
HogQLQueryposthog:execute-sqlIf the user's question spans multiple kinds, run the playbooks in sequence.
Step 2 — Common opening moves
2.1 Confirm the anomaly
Run the primary tool. Record baseline, current, delta (absolute and %), and the start
of the anomaly window.
2.2 Variance check
Widen to 3–4× the user's interval (or use on
TrendsQuery / StickinessQuery; for other kinds run two date ranges).
Pipe the widened result through
— it flags
seasonality, partial right-edge buckets, and real anomalies. If the movement is
normal variance, report that and stop.
compareFilter: {"compare": true}compare_to_prior_periods.py2.3 Known changes in the window
In rough order of signal:
- → flags with
posthog:feature-flag-get-allnear the anomaly start.updated_at - →
posthog:experiment-get-all/start_datenear the start.end_date - →
posthog:annotations-listnear the start.date_marker - for the window if the repo is reachable (highest signal when available).
git log
Any match is a hypothesis to confirm in the playbook (usually via breakdown on
, , or ).
$feature/<flag_key>app_versionutm_sourceStep 3 — Run the playbook
Open the playbook for the kind from Step 1 and follow its numbered steps. Carry the
record from 2.1 and any candidates from 2.3 into it.
Step 4 — Cross-check
Pick a segment the suspected cause should not have affected and rerun there. Stable
in the control = strong hypothesis; moved too = expand the investigation. Skip when
2.2 already explained the movement.
Step 5 — Write findings
Use the format below. Offer to save key charts via . If a
cause is found and no annotation marks it, offer . See
common-causes.md for the cause taxonomy.
posthog:insight-createposthog:annotation-createmarkdown
# Investigation: <metric>
**Anomaly**: <baseline> → <current> (<delta>) starting <date>
## Likely cause
<one sentence>
**Confidence**: low | medium | high — <one-line reason>
**Evidence**
- <query result>
- <flag / experiment / annotation / commit if applicable>
## Possible causes (ruled out)
- <hypothesis>: <why>
## Affected segment
- <shared properties of affected users/events>
## Data gaps
- <checks skipped and why>
## Suggested follow-ups
- <concrete next action>
- <offer to save chart / create annotation>Confidence rule of thumb:
- high — multiple independent signals corroborate (e.g. a segment isolates the delta and a flag/version aligns and an error or annotation matches).
- medium — one corroborating signal, or strong pattern-match without a cross-check.
- low — pattern matches a known cause but no corroboration, or the data only rules things out.
Link insights and dashboards inline: .
[Name](/insights/short_id)Reference files
- Playbooks: trend, box-plot, funnel, retention, stickiness, lifecycle, paths
- shared-patterns.md — recipes used across playbooks
- common-causes.md — cause taxonomy with confirming queries