mcpField
E
exploring-llm-clusters

exploring-llm-clusters

github.com/posthogデータ・データベース76410 回インストール今日更新
リポジトリ

exploring-llm-clusters について

LLMトレース、生成、評価のクラスタを調査するPostHogスキルです。オブザーバビリティを扱うユーザーが利用パターンや指標を比較し、代表的なトレースを詳しく確認できます。

主な機能

  1. 01クラスタリングジョブと実行履歴の一覧
  2. 02トレース・生成・評価クラスタの確認
  3. 03コスト・レイテンシ・トークン・エラー指標の算出
  4. 04代表的なトレースの確認
  5. 05実行間のクラスタ比較

活用シーン

  1. 01LLMトラフィックの傾向把握
  2. 02コストやレイテンシが高いクラスタの特定
  3. 03エラーが多いクラスタの調査
  4. 04期間ごとのクラスタ傾向の比較

MCP 対応

PostHog MCPツールを使い、クラスタリングジョブの一覧表示、SQLによるクラスタイベントの検索、LLMトレースの確認を行います。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/posthog/skills --skill exploring-llm-clusters

インストール後、Claude Code で/exploring-llm-clustersを入力して読み込まれたか確認します。

同梱ファイルscripts/print_clusters.py

詳細

LLM クラスターの調査

AI オブザーバビリティのクラスターを調査する際にこのスキルを使用します。 AI/LLM トラフィックにどのようなパターンがあるかを把握し、 クラスターの動作を比較して、個々のクラスターを詳しく調べます。

ツール

ツール目的
posthog:llma-clustering-job-listチームのクラスタリングジョブ設定の一覧を取得する
posthog:llma-clustering-job-getID を指定してクラスタリングジョブを取得する
posthog:execute-sqlクラスター実行イベントをクエリし、メトリクスを算出する
posthog:query-llm-traces-listクラスターに属するトレースを検索する
posthog:query-llm-trace特定のトレースの詳細を調べる

クラスタリングの仕組み

PostHog は、埋め込みの類似度に基づいて LLM トレース、個々の生成、または評価イベントをクラスター化します。 Temporal ワークフローが定期的またはオンデマンドで実行され、クラスターイベントを生成します。イベントは $ai_trace_clusters(トレースレベル)、$ai_generation_clusters(生成レベル)、または $ai_evaluation_clusters(評価レベル)として保存されます。

各クラスターイベントには以下が含まれます。

  • $ai_clustering_run_id — 一意の実行 ID(形式:<team_id>_<level>_<YYYYMMDD>_<HHMMSS>[_<job_id>])
  • $ai_clustering_level — "trace"、"generation"、または "evaluation"
  • $ai_window_start / $ai_window_end — 分析対象データの時間範囲
  • $ai_total_items_analyzed — 処理されたトレース、生成、または評価の数
  • $ai_clusters — クラスターオブジェクトの JSON 配列
  • $ai_clustering_params — 使用されたアルゴリズムのパラメーター

分析対象の時間範囲は実行開始時に終了し、クラスターイベントは実行完了後に生成されます。 そのため、クラスターイベント自体のtimestampは、数秒から数時間後まで、常に$ai_window_endより後になります。 分析されたトレース、生成、評価を絞り込む場合にのみ、この時間範囲を使用してください。 クラスターイベント自体を見つけるには、最近の時間範囲を指定して$ai_clustering_run_idで絞り込みます。

クラスターオブジェクトの形式($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はノイズ/外れ値クラスターです(どのクラスターにも適合しなかったアイテム)
  • traces内のアイテムは、トレース ID(トレースレベル)、生成イベント UUID(生成レベル)、または評価イベント UUID(評価レベル)をキーとします
  • rankは重心への近さでアイテムを並べます(0 = 最も近い)
  • x、yは可視化用の2次元座標です(UMAP/PCA/t-SNEで次元削減)

クラスタリングジョブ

各チームは最大10件のクラスタリングジョブを設定できます。ジョブでは以下を定義します。

  • name — 人が読みやすいラベル
  • analysis_level — "trace"、"generation"、または "evaluation"
  • event_filters — 対象に含めるアイテムを絞り込むプロパティフィルター
  • enabled — ジョブをスケジュールに従って実行するかどうか

"Default - traces"、"Default - generations"、"Default - evaluations"という名前のデフォルトジョブは自動作成されます。 同じレベルのカスタムジョブを作成すると、デフォルトジョブは無効になります。

ワークフロー:クラスターを調べる

ステップ1 — 最近のクラスタリング実行を一覧表示する
posthog:execute-sql
SELECT
    toString(properties.$ai_clustering_run_id) AS run_id,
    toString(properties.$ai_clustering_level) AS level,
    toString(properties.$ai_clustering_job_id) AS job_id,
    toString(properties.$ai_clustering_job_name) AS job_name,
    toString(properties.$ai_window_start) AS window_start,
    toString(properties.$ai_window_end) AS window_end,
    toFloat64OrNull(toString(properties.$ai_total_items_analyzed)) AS total_items,
    timestamp
FROM events
WHERE event IN ('$ai_trace_clusters', '$ai_generation_clusters', '$ai_evaluation_clusters')
    AND timestamp >= now() - INTERVAL 14 DAY
ORDER BY timestamp DESC
LIMIT 10
ステップ2 — 特定の実行からクラスターを取得する
posthog:execute-sql
SELECT
    toString(properties.$ai_clustering_run_id) AS run_id,
    toString(properties.$ai_clustering_level) AS level,
    toString(properties.$ai_clustering_job_id) AS job_id,
    toString(properties.$ai_clustering_job_name) AS job_name,
    toString(properties.$ai_window_start) AS window_start,
    toString(properties.$ai_window_end) AS window_end,
    toFloat64OrNull(toString(properties.$ai_total_items_analyzed)) AS total_items,
    properties.$ai_clusters AS clusters,
    properties.$ai_clustering_params AS params,
    timestamp
FROM events
WHERE event IN ('$ai_trace_clusters', '$ai_generation_clusters', '$ai_evaluation_clusters')
    AND timestamp >= now() - INTERVAL 14 DAY
    AND toString(properties.$ai_clustering_run_id) = '<run_id>'
ORDER BY timestamp DESC
LIMIT 1

実行についてステップ1で報告されたtimestampを含むよう、検索対象の時間範囲を十分に広く設定してください。 このクエリを$ai_window_start/$ai_window_endで絞り込まないでください。 クラスターイベントは時間範囲の終了後に生成されるため、これらの境界を使うと行が0件になります。

clustersフィールドは JSON 配列です。解析すると、クラスターのタイトル、サイズ、説明、任意のmetrics、および各クラスターのtracesマップを確認できます。

重要: クラスター JSON は非常に大きくなる場合があります(座標を含む、数千件のトレース、生成、または評価 ID)。 結果がインライン表示には大きすぎる場合、自動的にファイルに保存されます。 読みやすい要約を取得するには、scripts/にあるprint_clusters.pyを使用してください。

ステップ 3 — クラスターのメトリクスを計算する

トレースレベルのクラスターでは、コスト/レイテンシー/トークンのメトリクスを計算します。

posthog:execute-sql
SELECT
    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 properties.$ai_trace_id IN ('<trace_id_1>', '<trace_id_2>', ...)
GROUP BY trace_id

生成レベルのクラスターでは、イベント 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 uuid IN ('<gen_uuid_1>', '<gen_uuid_2>', ...)

評価レベルのクラスターでは、まず $ai_clusters の各クラスターの metrics フィールドを確認します(たとえば、合格率、N/A 率、主要な評価者名、平均判定コストなど)。個々の評価行が必要な場合は、イベント UUID を使って照合します。

posthog:execute-sql
SELECT
    toString(uuid) AS evaluation_id,
    toString(properties.$ai_trace_id) AS trace_id,
    toString(properties.$ai_target_event_id) AS generation_id,
    toString(properties.$ai_evaluation_name) AS evaluation_name,
    toString(properties.$ai_evaluation_result) AS evaluation_result,
    toString(properties.$ai_evaluation_reasoning) AS evaluation_reasoning,
    toFloatOrNull(toString(properties.$ai_total_cost_usd)) AS judge_cost,
    timestamp
FROM events
WHERE event = '$ai_evaluation'
    AND timestamp >= parseDateTimeBestEffort('<window_start>')
    AND timestamp <= parseDateTimeBestEffort('<window_end>')
    AND uuid IN ('<eval_uuid_1>', '<eval_uuid_2>', ...)
ステップ 4 — 特定のトレースを詳しく調べる

興味深いクラスターを特定したら、トレースツールを使って個々のトレースを調べます。

posthog:query-llm-trace
{
  "traceId": "<trace_id_from_cluster>",
  "dateRange": {"date_from": "<window_start>", "date_to": "<window_end>"}
}
メッセージの内容が必要な場合

クラスターのイベント、ID、コスト/レイテンシー/トークンのメトリクス、評価行には events を使用します。 ユーザーメッセージやモデルの入出力全体が必要な場合は、events.properties.$ai_input、$ai_output、$ai_output_choices をクエリしないでください。 これらの大きなフィールドは posthog.ai_events にあります。

代表的な例をいくつか確認する場合は、query-llm-trace を使用してください。posthog.ai_events を読み取り、イベントツリー全体を返します。 一括抽出する場合は、まずクラスターからトレース ID を取得してから、trace_id を起点に posthog.ai_events をクエリします。

posthog:execute-sql
SELECT
    trace_id,
    timestamp,
    span_id,
    event,
    model,
    input,
    output_choices
FROM posthog.ai_events
WHERE trace_id IN ('<trace_id_1>', '<trace_id_2>', ...)
ORDER BY trace_id, timestamp

posthog.ai_events の保持期間は events より短いため、古いクラスターにはメタデータやメトリクスが残っていても、メッセージの内容がない場合があります。 $ai_* イベントのスキーマ全体を確認するには、exploring-llm-traces スキルを読み込んでください。

調査パターン

「どのような種類の LLM 使用状況がありますか?」
  1. 最近のクラスタリング実行を一覧表示します(ステップ 1)
  2. 最新の実行のクラスターを読み込みます(ステップ 2)
  3. クラスターのタイトルと説明を確認します。それぞれが異なる使用パターンを表しています
  4. クラスターのサイズを比較し、トラフィックの分布を把握します
「最もコストが高い/最も遅いクラスターはどれですか?」
  1. 実行からクラスターを読み込みます(ステップ 2)
  2. 各クラスターからトレース ID を抽出します
  3. クラスターごとにメトリクスを計算します(ステップ 3)
  4. クラスターごとに avg(cost)、avg(latency)、sum(cost) を集計します
  5. クラスター間で比較します
「このクラスターには何が含まれていますか?」
  1. クラスターのトレースを読み込みます(traces フィールドから)
  2. rank で並べ替えます(セントロイドに最も近いものが、最も代表的です)
  3. 上位 3~5 件のトレースを query-llm-trace で調べ、パターンを把握します
  4. クラスターの title と description を確認し、AI が生成した概要を把握します
「エラーの多いクラスターはありますか?」
  1. error_count を使ってメトリクスを計算します(ステップ 3)
  2. クラスターごとにエラー率を計算します:items_with_errors / total_items
  3. エラー率の高いクラスターに注目します
  4. エラーのあるトレースを詳しく調べ、根本原因を特定します
「実行間でクラスターはどのように変化していますか?」
  1. 複数の実行を一覧表示します(ステップ 1)
  2. 各実行のクラスターを読み込みます
  3. クラスターのタイトルを比較します。実行間で似たタイトルがあれば、パターンが安定していることを示します
  4. クラスターのサイズの変化を追跡し、トラフィックパターンの変化を検出します

UI リンクの作成

  • クラスターの概要:https://app.posthog.com/ai-observability/clusters
  • 特定の実行:https://app.posthog.com/ai-observability/clusters/<url_encoded_run_id>
  • クラスターの詳細:https://app.posthog.com/ai-observability/clusters/<url_encoded_run_id>/<cluster_id>

ユーザーが PostHog UI で目視確認できるよう、これらのリンクを必ず提示してください。

ヒント

  • SQL クエリでは必ず時間範囲を設定してください。時間範囲を指定せずにクラスターイベントを検索すると時間がかかります
  • クラスターイベントを検索する際は、分析対象の期間ではなく、イベントが発生した時点を基準に範囲を指定してください。実行の $ai_window_end はイベント自体の timestamp より前です
  • まず実行の一覧を確認して全体像を把握し、その後、特定のクラスターを詳しく調べてください
  • クラスターのタイトルと説明は AI が生成した要約です。トレースを調べて内容を確認してください
  • ノイズクラスター(cluster_id: -1)には、どのパターンにも当てはまらなかった外れ値が含まれます
  • 有効なクラスタリング設定を把握するには、llma-clustering-job-list を使用してください
  • クラスター内のトレース ID は、詳細な調査に query-llm-trace で直接使用できます
  • メッセージの内容は events.properties ではなく posthog.ai_events にあります。独自の一括 SQL クエリが必要な場合を除き、query-llm-trace を使用してください
  • 大規模なクラスターでは、代表例を確認するため、順位が最も高い(重心に最も近い)トレースを調べてください

コメント