mcpField
E
exploring-llm-traces

exploring-llm-traces

github.com/posthogAgent 工作流76413 次安装今天更新
代码仓库

关于 exploring-llm-traces

用于调查 PostHog 中 LLM 和 AI Agent 轨迹的技能,可查看事件树、输入、输出、错误和耗时。它引导先浏览摘要再深入检查,并提醒处理被省略或脱敏的数据。

主要功能

  1. 01搜索和列出 LLM 轨迹
  2. 02检查单条轨迹的事件树
  3. 03发现事件架构和属性值
  4. 04先查看摘要再读取完整轨迹
  5. 05使用 SQL 和脚本分析轨迹

适用场景

  1. 01根据 URL 排查轨迹或会话
  2. 02检查工具输入、输出和错误
  3. 03调查提供给 LLM 的上下文
  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 Agent 活动记录为跟踪记录。每条跟踪记录都是由多个事件构成的树,表示一次 AI 交互——从顶层 Agent 调用到单个 LLM API 调用。

可用工具

工具用途
posthog:query-llm-traces-list搜索并列出跟踪记录;可能返回包含多条跟踪记录的大型数据载荷
posthog:query-llm-trace根据 ID 获取单条跟踪记录及其完整事件树
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 会话,而非跟踪记录。使用 posthog:query-llm-traces-list,并按事件属性 $ai_session_id 筛选,以获取跟踪记录。

如果 URL 中包含 date_from / date_to 查询参数,请保留。 如果没有这些参数,但 URL 中包含 timestamp 查询参数,则使用该时间戳作为锚点,并围绕它查询一个绝对时间范围,例如从 timestamp - 36h 到 timestamp + 36h。 这样既能处理 UI 时间戳可能与存储的事件时间戳存在偏差的精确会话链接,又能将查询范围限定在合理区间内。 如果 URL 中既没有明确日期,也没有 timestamp,请使用 {"date_from": "-7d"} 这样的安全默认值。

对于精确的跟踪记录和会话 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 步 — 读取调查所需的内容

选定一条追踪记录后,请先调用 posthog:query-llm-trace 并设置 detail: "full",然后再检查具体的工具参数、查看模型收到的上下文或搜索对话内容:

{
  "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 环境变量来控制截断长度(0 = 不限)。

被隐藏的属性

这两个追踪工具仅返回 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 无法查找仅出现在被隐藏属性中的关键词。

调查模式

“Agent 是否正确使用了工具?”
  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?
“子 Agent 是否正常工作?”
  1. 在结构概览中,找到作为其他 span 子项的 span(通过 $ai_parent_id)
  2. 父 span 是编排器;子 span 是子 Agent 的步骤
  3. 检查每个子项的 $ai_output_state 和 $ai_is_error
  4. 如果某个子 span 包含 $ai_generation 事件,这些就是子 Agent 的 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 事件存在——调用 posthog:read-data-schema 并设置 kind: "events",查找 $ai_* 事件
  2. 查找可筛选的属性——调用 posthog:read-data-schema 并设置 kind: "event_properties" 和 event_name: "$ai_generation"(或其他 AI 事件),查看采集了哪些属性
  3. 获取实际值——调用 posthog:read-data-schema 并设置 kind: "event_property_values"、event_name: "$ai_generation" 和 property_name: "$ai_model",查看实际使用的模型名称

只有完成上述步骤后,才能在 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"}
  ]
}

你也可以按人员属性筛选(使用 read-data-schema 并设置 kind: "entity_properties" 和 entity: "person" 来发现这些属性):

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. 调用 posthog:read-data-schema 并设置 kind: "event_properties" 和 event_name: "$ai_trace",查找自定义属性
  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 模式,请阅读以下参考资料:

解析大型追踪结果

追踪工具的结果为 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汇总列表/会话总数、追踪元数据、工具调用、错误和最终大模型输出python3 scripts/print_summary.py FILE
print_timeline.py按时间顺序展示事件时间线和 I/O 摘要python3 scripts/print_timeline.py FILE
extract_span.py按名称提取指定 span 的完整输入/输出SPAN="name" python3 scripts/extract_span.py FILE
extract_conversation.py提取包含思考区块和工具调用的大模型消息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,方便用户点击查看
  • span 上的 $ai_input_state / $ai_output_state 包含工具调用的输入和输出
  • generation 上的 $ai_input / $ai_output_choices 包含完整的大模型对话,可能达到数 MB;如果结果已保存到文件,请使用解析脚本
  • 在原始 SQL 中,大量内容($ai_input / $ai_output / $ai_output_choices / $ai_input_state / $ai_output_state / $ai_tools)只存在于 posthog.ai_events 表中,而不在 events.properties 中——有关列映射和以追踪 ID 为锚点的查询模式,请参阅事件参考
  • 搜索时使用 filterTestAccounts: true 排除内部/测试流量
  • $ai_trace 事件不在 events 数组中——其数据通过追踪级别的 inputState、outputState 和 traceName 提供

评论

支持 Markdown