### Exploring LLM Clusters
Works with
Identify usage patterns by analyzing AI/LLM traffic clusters generated via embedding similarity and Temporal workflows.
Use SQL queries to retrieve cluster metadata, compute cost and latency metrics, and identify high-error or high-cost traffic segments.
Drill into specific traces using trace IDs to inspect representative samples and verify AI-generated cluster descriptions.
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versionexploring-llm-clustersExecute the skills CLI command in your project's root directory to begin installation:
Fetches exploring-llm-clusters from PostHog/skills and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate exploring-llm-clusters. Access via /exploring-llm-clusters in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
0
total installs
0
this week
15
GitHub stars
0
upvotes
Run in your terminal
0
installs
0
this week
15
stars
| name | exploring-llm-clusters |
| description | 'Investigate LLM analytics clusters — understand usage patterns in AI/LLM traffic, compare cluster behavior, compute cost/latency metrics, and drill into individual traces within clusters.' |
Use this skill when investigating LLM analytics clusters — understanding what patterns exist in your AI/LLM traffic, comparing cluster behavior, and drilling into individual clusters.
| Tool | Purpose |
|---|---|
posthog:llm-analytics-clustering-jobs-list | List clustering job configurations for the team |
posthog:llm-analytics-clustering-jobs-retrieve | Get a specific clustering job by ID |
posthog:execute-sql | Query cluster run events and compute metrics |
posthog:query-llm-traces-list | Find traces belonging to a cluster |
posthog:query-llm-trace | Inspect a specific trace in detail |
PostHog clusters LLM traces (or individual generations) by embedding similarity.
A Temporal workflow runs periodically or on-demand, producing cluster events stored as
$ai_trace_clusters (trace-level) or $ai_generation_clusters (generation-level).
Each cluster event contains:
$ai_clustering_run_id — unique run identifier (format: <team_id>_<level>_<YYYYMMDD>_<HHMMSS>[_<job_id>])$ai_clustering_level — "trace" or "generation"$ai_window_start / $ai_window_end — time window analyzed$ai_total_items_analyzed — number of traces/generations processed$ai_clusters — JSON array of cluster objects$ai_clustering_params — algorithm parameters used$ai_clusters){
"cluster_id": 0,
"size": 42,
"title": "User authentication flows",
"description": "Traces involving login, signup, and token refresh operations",
"traces": {
"<trace_or_generation_id>": {
"distance_to_centroid": 0.123,
"rank": 0,
"x": -2.34,
"y": 1.56,
"timestamp": "2026-03-28T10:00:00Z",
"trace_id": "abc-123",
"generation_id": "gen-456"
}
},
"centroid_x": -2.1,
"centroid_y": 1.4
}
cluster_id: -1 is the noise/outlier cluster (items that didn't fit any cluster)traces are keyed by trace ID (trace-level) or generation event UUID (generation-level)rank orders items by proximity to centroid (0 = closest)x, y are 2D coordinates for visualization (UMAP/PCA/t-SNE reduced)Each team can have up to 5 clustering jobs. A job defines:
"trace" or "generation"Default jobs named "Default - trace" and "Default - generation" are auto-created
and disabled when a custom job is created for the same level.
posthog:execute-sql
SELECT
JSONExtractString(properties, '$ai_clustering_run_id') as run_id,
JSONExtractString(properties, '$ai_clustering_level') as level,
JSONExtractString(properties, '$ai_window_start') as window_start,
JSONExtractString(properties, '$ai_window_end') as window_end,
JSONExtractInt(properties, '$ai_total_items_analyzed') as total_items,
timestamp
FROM events
WHERE event IN ('$ai_trace_clusters', '$ai_generation_clusters')
AND timestamp >= now() - INTERVAL 7 DAY
ORDER BY timestamp DESC
LIMIT 10
posthog:execute-sql
SELECT
JSONExtractString(properties, '$ai_clustering_run_id') as run_id,
JSONExtractString(properties, '$ai_clustering_level') as level,
JSONExtractString(properties, '$ai_clustering_job_id') as job_id,
JSONExtractString(properties, '$ai_clustering_job_name') as job_name,
JSONExtractString(properties, '$ai_window_start') as window_start,
JSONExtractString(properties, '$ai_window_end') as window_end,
JSONExtractInt(properties, '$ai_total_items_analyzed') as total_items,
JSONExtractRaw(properties, '$ai_clusters') as clusters,
JSONExtractRaw(properties, '$ai_clustering_params') as params
FROM events
WHERE event IN ('$ai_trace_clusters', '$ai_generation_clusters')
AND JSONExtractString(properties, '$ai_clustering_run_id') = '<run_id>'
LIMIT 1
The clusters field is a JSON array. Parse it to see cluster titles, sizes, and descriptions.
Important: The clusters JSON can be very large (thousands of trace IDs with coordinates).
When the result is too large for inline display, it auto-persists to a file.
Use print_clusters.py from scripts/ to get a readable summary.
For trace-level clusters, compute cost/latency/token metrics:
posthog:execute-sql
SELECT
JSONExtractString(properties, '$ai_trace_id') as trace_id,
sum(toFloat(properties.$ai_total_cost_usd)) as total_cost,
max(toFloat(properties.$ai_latency)) as latency,
sum(toInt(properties.$ai_input_tokens)) as input_tokens,
sum(toInt(properties.$ai_output_tokens)) as output_tokens,
countIf(properties.$ai_is_error = 'true') as error_count
FROM events
WHERE event IN ('$ai_generation', '$ai_embedding', '$ai_span')
AND timestamp >= parseDateTimeBestEffort('<window_start>')
AND timestamp <= parseDateTimeBestEffort('<window_end>')
AND JSONExtractString(properties, '$ai_trace_id') IN ('<trace_id_1>', '<trace_id_2>', ...)
GROUP BY trace_id
For generation-level clusters, match by event UUID:
posthog:execute-sql
SELECT
toString(uuid) as generation_id,
toFloat(properties.$ai_total_cost_usd) as cost,
toFloat(properties.$ai_latency) as latency,
toInt(properties.$ai_input_tokens) as input_tokens,
toInt(properties.$ai_output_tokens) as output_tokens,
if(properties.$ai_is_error = 'true', 1, 0) as is_error
FROM events
WHERE event = '$ai_generation'
AND timestamp >= parseDateTimeBestEffort('<window_start>')
AND timestamp <= parseDateTimeBestEffort('<window_end>')
AND toString(uuid) IN ('<gen_uuid_1>', '<gen_uuid_2>', ...)
Once you've identified interesting clusters, use the trace tools to inspect individual traces:
posthog:query-llm-trace
{
"traceId": "<trace_id_from_cluster>",
"dateRange": {"date_from": "<window_start>", "date_to": "<window_end>"}
}
avg(cost), avg(latency), sum(cost) per clustertraces field)rank (closest to centroid = most representative)query-llm-trace to understand the patterntitle and description for the AI-generated summaryerror_countitems_with_errors / total_itemshttps://app.posthog.com/llm-analytics/clustershttps://app.posthog.com/llm-analytics/clusters/<url_encoded_run_id>https://app.posthog.com/llm-analytics/clusters/<url_encoded_run_id>/<cluster_id>Always surface these links so the user can verify visually in the PostHog UI.
cluster_id: -1) contains outliers that didn't fit any patternllm-analytics-clustering-jobs-list to understand what clustering configs are activequery-llm-trace for deep inspectionPrerequisites
Time Estimate
15-45 minutes depending on use case complexity
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
PostHog/skills
PostHog/skills
PostHog/skills
PostHog/skills
PostHog/skills
PostHog/skills
We added exploring-llm-clusters from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
exploring-llm-clusters is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
I recommend exploring-llm-clusters for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
exploring-llm-clusters reduced setup friction for our internal harness; good balance of opinion and flexibility.
exploring-llm-clusters fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
exploring-llm-clusters reduced setup friction for our internal harness; good balance of opinion and flexibility.
Keeps context tight: exploring-llm-clusters is the kind of skill you can hand to a new teammate without a long onboarding doc.
exploring-llm-clusters fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
We added exploring-llm-clusters from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
I recommend exploring-llm-clusters for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
showing 1-10 of 61