Scenario A: AI agent observability¶
Part of Streaming Transformations › Scenarios.
Goal¶
An AI agent works in multi-step runs: it calls a model, then one or more tools. Each run sends one telemetry record with token counts, latency, and the list of tool calls it made. To see what agents do and what they cost, teams need one row per tool call, with the model provider and an estimated cost, and without health checks and internal evaluation runs.
Transformations used¶
- Lateral Flatten on the stream: expand the array of tool calls in each agent run, before the dimension join (derived table).
- Stream enrichment: map each model to its provider and token prices.
- Stream filtering on stream columns: drop health-check and evaluation runs.
Source data¶
Stream¶
Each streamed record is one agent run. The example uses these five runs:
Dimension table¶
The PIPE joins this dimension table, refreshed periodically:
Target table¶
The PIPE lands transformed and filtered rows in this target table, with one row per tool call:
Transformation¶
The PIPE flattens streamed records, enriches by joining the dimension table, and filters rows before landing by applying a WHERE on a stream column:
Result¶
Querying the target table returns rows like these:
| EVENT_TS | AGENT | TRACE_ID | MODEL | PROVIDER | TOOL_NAME | TOOL_MS | ESTIMATED_COST_USD |
|---|---|---|---|---|---|---|---|
| 2026-10-09 11:00:00 | support-bot | t-1001 | claude-sonnet | anthropic | search_kb | 420 | 0.0087 |
| 2026-10-09 11:00:00 | support-bot | t-1001 | claude-sonnet | anthropic | create_ticket | 180 | 0.0087 |
| 2026-10-09 11:00:05 | code-review-bot | t-1002 | claude-haiku | anthropic | read_file | 90 | 0.0056 |
| 2026-10-09 11:00:05 | code-review-bot | t-1002 | claude-haiku | anthropic | run_tests | 2300 | 0.0056 |
| 2026-10-09 11:00:05 | code-review-bot | t-1002 | claude-haiku | anthropic | post_comment | 150 | 0.0056 |
| 2026-10-09 11:00:15 | research-bot | t-1004 | custom-llm | NULL | web_search | 900 | NULL |
| 2026-10-09 11:00:15 | research-bot | t-1004 | custom-llm | NULL | summarize | 700 | NULL |
The health-check run t-1003 and the evaluation run t-1005 are filtered out. Each tool call gets its own row, and the estimated cost of the run repeats on every row of the trace. The model custom-llm has no entry in dim_models, so its provider and cost are NULL.
Considerations¶
- Dimension data is a snapshot that refreshes periodically, so updates can take several minutes to appear. This works well for slow-moving reference data. Dynamic tables can be used as dimension tables.
- A flatten before the dimension join must be wrapped in a derived table.
ERROR_LOGGINGcurrently can’t be enabled on the target table of a pipe that usesLATERAL FLATTEN.
See also¶
See Stream filtering, Stream enrichment, and Lateral Flatten for more information on the transformations used in this scenario.
Previous: Scenarios · Next: Scenario B: Observability logs and OpenTelemetry