mcpField
E
exploring-llm-traces

exploring-llm-traces

github.com/posthogエージェントワークフロー76413 回インストール今日更新
リポジトリ

exploring-llm-traces について

PostHog の LLM や AI エージェントのトレースを調査するためのスキルです。イベントツリー、入出力、エラー、所要時間を確認し、省略・秘匿されたデータに注意しながら概要から詳細へ調べます。

主な機能

  1. 01LLM トレースの検索と一覧表示
  2. 02個別トレースのイベントツリー確認
  3. 03イベントスキーマと値の検出
  4. 04概要を確認してから詳細を取得
  5. 05SQL とスクリプトによるトレース分析

活用シーン

  1. 01URL からトレースやセッションを調査
  2. 02ツールの入力・出力・エラー確認
  3. 03LLM に渡されたコンテキストの調査
  4. 04検出したイベントプロパティによる検索

MCP 対応

PostHog MCP のトレース、スキーマ、SQL ツールで LLM の活動を検索・確認します。

インストール

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

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

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
events-and-properties.md
example-llm-trace.md
example-llm-traces-list.md
scripts/
extract_conversation.py
extract_span.py
print_summary.py
print_timeline.py
search_traces.py
show_structure.py

詳細

MCP ツールを使った LLM トレースの調査

PostHog は、LLM/AI エージェントのアクティビティをトレースとして記録します。各トレースは、トップレベルのエージェント呼び出しから個々の LLM API 呼び出しまで、単一の AI インタラクションを表すイベントのツリーです。

利用可能なツール

ツール目的
posthog:query-llm-traces-listトレースを検索して一覧表示します。複数トレースの大きなペイロードを返す場合があります
posthog:query-llm-traceID を指定して、完全なイベントツリーを含む単一のトレースを取得します
posthog:read-data-schemaフィルタリングの前に、カスタムイベント/人物プロパティを確認します
posthog:execute-sql複雑なトレース分析に使用するアドホック SQL

イベント階層

完全なスキーマについては、イベントリファレンスを参照してください。

$ai_trace (top-level container)
  └── $ai_span (logical groupings, e.g. "RAG retrieval", "tool execution")
        ├── $ai_generation (individual LLM API call)
        └── $ai_embedding (embedding creation)

イベントは $ai_parent_id → 親の $ai_span_id または $ai_trace_id を介してリンクされています。

ワークフロー:URL からトレースまたはセッションをデバッグする

ステップ 1 — URL を分類する

まずパスを確認します。UUID のように見える値をすべてトレース ID として扱わないでください。

  • /ai-observability/traces/<trace_id> または従来の /llm-analytics/traces/<trace_id> / /llm-observability/traces/<trace_id> は単一のトレースです。posthog:query-llm-trace で取得します。
  • /ai-observability/sessions/<session_id> または従来の /llm-analytics/sessions/<session_id> は AI セッションであり、トレースではありません。イベントプロパティ $ai_session_id でフィルタリングして、posthog:query-llm-traces-list でトレースを取得します。

URL に date_from / date_to クエリパラメーターが含まれている場合は、その値を保持します。 どちらもなく、URL に timestamp クエリパラメーターがある場合は、そのタイムスタンプを基準にして、その前後の絶対時間範囲(たとえば timestamp - 36h から timestamp + 36h)を指定してクエリを実行します。 これにより、UI のタイムスタンプが保存されたイベントのタイムスタンプとずれている可能性がある正確なセッションリンクにも対応しながら、クエリ範囲を制限できます。 URL に明示的な日付も timestamp もない場合は、{"date_from": "-7d"} のような安全なデフォルトを使用します。

正確なトレース URL とセッション URL では、以下で使われる標準の $ai_* フィールドについて、スキーマの確認を省略します。これらは AI オブザーバビリティの組み込みフィールドであり、プロジェクト固有のカスタムプロパティではありません。

ステップ 2 — トレースの概要を確認する

トレースを確認する際は、明示的に detail: "summary" を設定します。 これにより、イベントのメタデータが返され、会話の内容は除外されるため、プロンプトや出力でコンテキストを消費せずに確認できます。 detail を省略した場合も、既存の呼び出し元との互換性のために、詳細全体が返されます。

トレース URL の場合は、次のように posthog:query-llm-trace を呼び出します。

{
  "traceId": "<trace_id>",
  "detail": "summary",
  "dateRange": { "date_from": "-7d" }
}

セッション URL の場合は、次のように posthog:query-llm-traces-list を呼び出します。

{
  "detail": "summary",
  "dateRange": { "date_from": "<timestamp_minus_36h>", "date_to": "<timestamp_plus_36h>" },
  "filterTestAccounts": false,
  "limit": 20,
  "properties": [{ "type": "event", "key": "$ai_session_id", "value": ["<session_id>"], "operator": "exact" }]
}

セッションのクエリには、URL に date_from / date_to の値があれば使用します。 URL に timestamp しかない場合は、-1h のような相対範囲を使うのではなく、そのタイムスタンプから絶対日付範囲を計算します。 正確な URL では filterTestAccounts: false を設定し、アカウントフィルターによって要求されたトレースが非表示にならないようにします。

結果には、トレースとイベントのメタデータのみが含まれます。 プロンプト、出力、スパンの状態、$ai_error、$ai_feedback_text は除外され、それらの名前はプロパティバッグの横にある _summaryOmittedKeys に一覧表示されます。 _detail: { "mode": "summary" } を含むトレースには、会話の内容は一切含まれません。 内容を読むには、detail: "full" を指定します。

結果からは、次の情報を取得できます。

  • 種類($ai_span、$ai_generation など)を含むすべてのイベント
  • スパン名($ai_span_name)— ツール/ステップ名です
  • レイテンシー、エラーフラグ、使用されたモデル
  • $ai_parent_id による親子関係
  • _posthogUrl — ユーザーが UI を開けるように、必ず回答に含めてください
ステップ 3 — 調査に必要なコンテンツを読む

トレースを選択したら、ツールの引数を詳しく調べる、モデルが受け取ったコンテキストを確認する、または会話の内容を検索する前に、detail: "full" を指定して posthog:query-llm-trace をリクエストします。

{
  "traceId": "<trace_id>",
  "detail": "full",
  "dateRange": { "date_from": "-7d" }
}

例の期間をコピーするのではなく、元の URL または検索クエリの日付範囲を維持します。 関連するプロパティフィルターを維持して、読み取るデータを絞り込みます。ユーザーがすでにトレースを特定しており、正確な内容が必要な場合は、最初から詳細全体をリクエストできます。

どちらのモードにも、レスポンスサイズの上限が適用されます。 結論を出す前に、省略および切り詰めを示すマーカーを確認します。 ドロップされたイベント、_summaryOmittedKeys または _redactedKeys に記載された名前、あるいはサマリーにないキーワードは、トレースにそれが存在しなかった証拠にはなりません。 詳細全体を取得しても切り詰められている場合は、関連するイベントにクエリを絞り込むか、完全なデータを確認するために _posthogUrl を開きます。 どちらの詳細モードでも、以下の非公開プロパティで説明する、AI ペイロード以外のプロパティは返されません。

ステップ 4 — スクリプトで詳細全体の大きな結果を解析する

結果がファイルに保存されている場合($ai_input/$ai_output_choices 全体を含む大きなトレースなど)、解析スクリプトを使って内容を調べます。

まずサマリーを確認して全体像を把握し、その後、詳細を掘り下げます。

# 1. Overview: metadata, tool calls, final output, errors
python3 scripts/print_summary.py /path/to/persisted-file.json

# 2. Timeline: chronological event list with truncated I/O
python3 scripts/print_timeline.py /path/to/persisted-file.json

# 3. Drill into a specific span's full input/output
SPAN="tool_name" python3 scripts/extract_span.py /path/to/persisted-file.json

# 4. Full conversation with thinking blocks and tool calls
python3 scripts/extract_conversation.py /path/to/persisted-file.json

# 5. Search for a keyword across the returned properties
SEARCH="keyword" python3 scripts/search_traces.py /path/to/persisted-file.json

すべてのスクリプトで、切り詰めを制御する MAX_LEN=N env var を使用できます(0 = 無制限)。

非公開プロパティ

2 つのトレースツールが返すのは AI ペイロードのみです。 PostHog の分類で定義された $ai_* プロパティに加え、$ai_generation_id、$ai_cache_read_cost_usd、$ai_cache_creation_cost_usd、$ai_effort、$session_id、$lib、$lib_version のみが返されます。 それ以外のイベントプロパティと、すべての人物プロパティは、どちらの詳細モードでも非公開となり、各プロパティバッグの横にある _redactedKeys に名前が記載されます。 $ai_base_url と $ai_request_url は、クエリ文字列を除いて返されます。

これには、project_id や conversation_id など、プロジェクト独自のカスタムプロパティも含まれます。 非公開プロパティは PostHog 上では変更されません。 このプロパティを使った絞り込みは引き続き可能で、その値は PostHog の UI または execute-sql で確認できます。 _redactedKeys に名前がある場合、そのプロパティはイベントに存在し、値のみが非公開であることを意味します。 search_traces.py では、非公開プロパティにのみ含まれるキーワードは見つかりません。

調査のパターン

「エージェントはツールを正しく使いましたか?」
  1. ツール呼び出しの $ai_span を見つけます($ai_span_name を確認します)
  2. $ai_input_state を確認します。ツールにはどのような引数が渡されましたか?
  3. $ai_output_state を確認します。ツールは何を返しましたか?
  4. $ai_is_error を確認します。ツール呼び出しは失敗しましたか?
「コンテキストは正しかったですか?」/「適切なファイルが表示されましたか?」
  1. LLM が判断を下した $ai_generation イベントを見つけます
  2. $ai_input を確認します。これは LLM が見たメッセージ履歴全体です
  3. それより前の $ai_span イベントで、検索/取得の手順を確認します
  4. それらの $ai_output_state を確認します。どのような内容が取得され、LLM に渡されましたか?
「サブエージェントは動作しましたか?」
  1. 構造の概要で、別のスパンの子であるスパン($ai_parent_id を使用)を見つけます
  2. 親スパンはオーケストレーター、子スパンはサブエージェントの各手順です
  3. 各子スパンの $ai_output_state と $ai_is_error を確認します
  4. 子スパンに $ai_generation イベントが含まれている場合、それらはサブエージェントによる LLM 呼び出しです
「LLM はなぜ X と言いましたか?」
  1. search_traces.py を使って、そのテキストが現れる場所を見つけます。SEARCH="the text" python3 scripts/search_traces.py FILE
  2. テキストを含むイベントとプロパティパスが表示されます
  3. その生成処理の $ai_input を確認し、LLM が X と言う前に何を伝えられていたかを確認します

UI リンクの構築

トレースツールは _posthogUrl を返します。必ずユーザーに提示してください。

リンクは手動で構築することもできます。

  • トレース詳細:https://app.posthog.com/ai-observability/traces/<trace_id>?timestamp=<url_encoded_timestamp>&event=<optional_event_id>
  • フィルター付きトレース一覧:query-llm-traces-list の _posthogUrl に返されます

timestamp クエリパラメーターは必須です。トレース内の最も早いイベントの createdAt を URL エンコードして使用してください(例:timestamp=2026-04-01T19%3A39%3A20Z)。

調査結果を提示する際は、ユーザーが確認できるよう、必ず関連する PostHog URL を含めてください。

トレースの検索

posthog:query-llm-traces-list を detail: "summary" で使用して、トレースを検索およびフィルタリングします。

重要:トレーニングデータを根拠に、イベント名、プロパティ名、プロパティ値を決して推測しないでください。 プロジェクトごとに異なるカスタムプロパティが計測されています。自由形式の検索やカスタムフィルターでは、フィルターを作成する前に posthog:read-data-schema を呼び出し、プロジェクトのデータに実際に存在するプロパティと値を確認してください。

例外は、AI オブザーバビリティのトレース/セッション URL が正確に指定されている場合です。組み込みの $ai_trace_id/$ai_session_id フィールドを直接使用し、スキーマの確認は省略してください。

まずスキーマを確認する

トレースをフィルタリングする前に、利用可能なデータを確認してください。

  1. AI イベントが存在することを確認する — kind: "events" を指定して posthog:read-data-schema を呼び出し、$ai_* イベントを探します
  2. フィルター可能なプロパティを確認する — kind: "event_properties" と event_name: "$ai_generation"(または別の AI イベント)を指定して posthog:read-data-schema を呼び出し、記録されているプロパティを確認します
  3. 実際の値を取得する — kind: "event_property_values"、event_name: "$ai_generation"、property_name: "$ai_model" を指定して posthog:read-data-schema を呼び出し、実際に使われているモデル名を確認します

その後で、プロパティフィルターを指定して query-llm-traces-list を呼び出します。

これは、project_id、conversation_id、user_tier などのカスタムプロパティでは特に重要です。これらはプロジェクトごとに異なるため、推測できません。 値がレスポンスで非表示になっていても、カスタムプロパティはフィルターとして使用できます。

$ai_* プロパティは確認する必要はありませんが、人物の email など、それ以外のプロパティは確認してください。

フィルターによる検索
posthog:query-llm-traces-list
{
  "detail": "summary",
  "dateRange": {"date_from": "-1h"},
  "filterTestAccounts": true,
  "limit": 20,
  "properties": [
    {"type": "event", "key": "$ai_model", "value": "gpt-4o", "operator": "exact"}
  ]
}

複数のフィルターは AND 条件で結合されます。

posthog:query-llm-traces-list
{
  "detail": "summary",
  "dateRange": {"date_from": "-1h"},
  "filterTestAccounts": true,
  "properties": [
    {"type": "event", "key": "$ai_provider", "value": "anthropic", "operator": "exact"},
    {"type": "event", "key": "$ai_is_error", "value": ["true"], "operator": "exact"}
  ]
}

人物プロパティでフィルタリングすることもできます(kind: "entity_properties" と entity: "person" を指定して read-data-schema で確認してください)。

posthog:query-llm-traces-list
{
  "detail": "summary",
  "dateRange": {"date_from": "-1h"},
  "filterTestAccounts": true,
  "properties": [
    {"type": "person", "key": "email", "value": "@company.com", "operator": "icontains"}
  ]
}
外部識別子による検索

顧客は独自の ID をイベントまたは人物のプロパティとして保存していることがよくあります。 posthog:read-data-schema を使って存在するカスタムプロパティを確認し、その後でフィルタリングします。

  1. kind: "event_properties" と event_name: "$ai_trace" を指定して posthog:read-data-schema を呼び出し、カスタムプロパティを確認します
  2. 返されたプロパティとサンプル値を確認します
  3. 確認したプロパティキーと既知の値を使ってフィルターを作成します
posthog:query-llm-traces-list
{
  "detail": "summary",
  "dateRange": {"date_from": "-7d"},
  "properties": [
    {"type": "event", "key": "project_id", "value": "proj_abc123", "operator": "exact"}
  ]
}

より複雑な SQL パターンについては、次のリファレンスを参照してください。

  • 単一トレースの取得 — すべてのイベントとプロパティを含む単一トレースを ID で取得します(TraceQuery HogQL をレンダリングします)
  • 集計メトリクス付きトレース一覧 — 2 段階のクエリです。最初にトレース ID を検索し、次にレイテンシー、トークン数、コスト、エラー数を集計して取得します

大きなトレース結果の解析

トレースツールの結果は JSON です。インラインで読むには大きすぎる場合、Claude Code はその結果をファイルに保存します。 コンテンツの抽出やキーワード検索には、詳細をすべて含むレスポンスを使用してください。 スクリプトでは、概要から省略されたコンテンツ、プロパティバッグから非表示になったコンテンツ、または切り捨てによって削除されたコンテンツを復元できません。

保存されたファイルの形式
[{ "type": "text", "text": "{\"results\": [...], \"_posthogUrl\": \"...\"}" }]
トレース JSON の構造
results (array for list, object for single trace)
  ├── id, traceName, createdAt, totalLatency, totalCost
  ├── inputState, outputState (trace-level state)
  └── events[]
        ├── event ($ai_span | $ai_generation | $ai_embedding | $ai_metric | $ai_feedback)
        ├── id, createdAt
        └── properties
              ├── $ai_span_name, $ai_latency, $ai_is_error
              ├── $ai_input_state, $ai_output_state (span tool I/O)
              ├── $ai_input, $ai_output_choices (generation messages)
              ├── $ai_model, $ai_provider
              └── $ai_input_tokens, $ai_output_tokens, $ai_total_cost_usd
利用可能なスクリプト
スクリプト用途使用方法
print_summary.pyリスト/セッションの合計、トレースのメタデータ、ツール呼び出し、エラー、LLM の最終出力を集計しますpython3 scripts/print_summary.py FILE
print_timeline.pyI/O の概要を含む、イベントの時系列を表示しますpython3 scripts/print_timeline.py FILE
extract_span.py名前を指定して、特定のスパンの入力/出力全体を抽出しますSPAN="name" python3 scripts/extract_span.py FILE
extract_conversation.py思考ブロックとツール呼び出しを含む LLM メッセージを表示しますpython3 scripts/extract_conversation.py FILE
search_traces.pyすべてのイベントプロパティからキーワードを検索しますSEARCH="keyword" python3 scripts/search_traces.py FILE
show_structure.py値を表示せずに JSON のキーと型を表示しますcat blob.json | python3 scripts/show_structure.py

ヒント

  • 常に dateRange を設定してください。時間範囲のないクエリは遅くなります。広範な一覧クエリには狭い範囲(-30m、-1h)を使用し、トレース ID や特定のプロパティ値で絞り込む狭いクエリには、広い範囲(-7d、-30d)を使用できます
  • ユーザーがリンク先にアクセスできるよう、回答には必ず _posthogUrl を含めてください
  • スパンの $ai_input_state/$ai_output_state には、ツール呼び出しの入力と出力が含まれます
  • 生成の $ai_input/$ai_output_choices には、LLM との会話全体が含まれます。数メガバイトになることがあります。結果がファイルに保存されている場合は、解析スクリプトを使用してください
  • 生の SQL では、サイズの大きいコンテンツ($ai_input/$ai_output/$ai_output_choices/$ai_input_state/$ai_output_state/$ai_tools)は events.properties ではなく、posthog.ai_events テーブルにのみ存在します。列の対応関係とトレース ID を基点としたクエリパターンについては、イベントリファレンスを参照してください
  • 検索時に内部/テストのトラフィックを除外するには、filterTestAccounts: true を使用してください
  • $ai_trace イベントは events 配列には含まれません。そのデータは、トレースレベルの inputState、outputState、traceName を通じて提供されます

コメント