---
title: Agent Analytics taxonomy
description: "Reference for the events Agent Analytics produces and the properties on each: SDK events, server enrichment events, the default signals, and the session hierarchy."
product: general
token_estimate: 5297
---
# Agent Analytics taxonomy

> For AI agents: a documentation index is available at [/docs/llms.txt](/docs/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

Agent Analytics uses a managed event taxonomy. Every event name and property is prefixed with `[Agent]` so agent data stays clearly separated from your product events while living in the same project. Because they share the project and the same user ID, you can chart, segment, and build cohorts across agent and product behavior.

This page is the reference for every event and property Agent Analytics produces. Events come from two producers:

- **Your SDK instrumentation** emits events in real time as your agent runs: User Message, AI Response, Tool Call, Span, Embedding, Session End, Session Enrichment, and Score.
- **Amplitude's enrichment pipeline** emits events after a session closes: Session Record and Evaluator Result. Amplitude never emits Score events; Scores always come from your application.

## Data hierarchy

Agent Analytics models each agent interaction as a hierarchy:

| Level | What it is | Identified by |
| --- | --- | --- |
| **Session** | One unit of work the user hands the agent: a conversation thread, a support ticket, a voice call, a background run. | `[Agent] Session ID` |
| **Turn** | One exchange within a session: a user message, the agent's tool calls, and the AI response. | `[Agent] Turn ID` |
| **Span** | One operation within a turn: an LLM call, a tool invocation, a retrieval step, or any custom operation you track. | Span-level IDs on each event |

An agent is a dimension on every event: Every event carries `[Agent] Agent ID` property, and in multi-agent systems child agents carry a parent reference. A single session can involve multiple agents: the session-level rollups record \[Agent\] Root Agent Name (the agent that started the session) and `[Agent] Agent Chain Depth` (how deep the delegation chain went). To compare agents, group any chart by `[Agent] Agent ID`. To analyze multi-agent sessions, filter Session Records with chain depth greater than 1.

Agent sessions are not analytics sessions: `[Agent] Session ID` identifies a unit of agent work and is set by your instrumentation (use the thread, ticket, call, or run ID your app already has). Amplitude's standard `session ID` identifies an app or web visit and powers Session Replay. One analytics session can contain several agent sessions. Refer to [the setup page](https://amplitude.com/docs/amplitude-ai/agent-analytics/setup#link-to-session-replay) for how to link the two for Session Replay.

## Event inventory

| Event | Producer | When it fires |
| --- | --- | --- |
| `[Agent] User Message` | SDK | The user sends a message to the agent. Opens a turn. |
| `[Agent] AI Response` | SDK | The model returns a response. Carries model, tokens, cost, and latency. |
| `[Agent] Tool Call` | SDK | The agent invokes a tool or function. |
| `[Agent] Span` | SDK | Any custom operation you track with `observe()` or `trackSpan()`. |
| `[Agent] Embedding` | SDK | An embedding call, for RAG and retrieval workloads. |
| `[Agent] Session End` | SDK | Your app marks the unit of work complete. Optional; refer to session closing below. |
| `[Agent] Session Enrichment` | SDK | You attach your own labels and scores to a session. Available in any privacy mode. |
| `[Agent] Score` | SDK | Your app records feedback: a user thumbs rating, your own LLM judge, or a human reviewer. Amplitude never generates this event. |
| `[Agent] Session Record` | Server | Once per closed session. Carries all signal results and session rollups. |
| `[Agent] Evaluator Result` | Server | Once per active custom evaluator per closed session. |

**Deprecated:** `[Agent] Topic Classification` no longer fires. Topic and classification outputs now land on `[Agent] Evaluator Result` (classification type) and in `[Agent] Topic Summary` on the Session Record. If you built charts on Topic Classification, migrate them to Evaluator Result.

## Signals: where quality lands

Amplitude runs a fixed set of quality signals on every closed session. **Signal results land as properties on the `[Agent] Session Record` event**, one record per session, each signal with its own result, rationale, and (where applicable) evidence property. Signals do not produce separate events.

| Signal | Result property | Type | Companion properties |
| --- | --- | --- | --- |
| Task completion | `[Agent] Task Completed` | Boolean | Rationale, Evidence |
| Response quality | `[Agent] Response Quality` | Boolean | Rationale, Evidence |
| User intent | `[Agent] User Intent` | Classification | Rationale |
| Session safety | `[Agent] Session Safety` | Classification | Rationale |
| User friction | `[Agent] Has User Friction` | Boolean | Rationale, `[Agent] Detected User Friction` (patterns) |
| Negative feedback | `[Agent] Has Negative Feedback` | Boolean | Rationale, `[Agent] Detected Negative Feedback` (phrases) |
| Data quality | `[Agent] Has Data Quality Issues` | Boolean | `[Agent] Detected Data Quality Issues` (issue list) |

Notes on signal semantics:

- The six LLM-based signals run as a single batched judge call per closed session (data quality is code-based, no LLM). Each LLM result carries a label, a rationale, and a supporting evidence quote. The judge is instructed to be conservative: signals are directional indicators, not ground truth.
- Task Completed and Response Quality are booleans, not numeric scores. To trend them, chart the share of sessions where the value is true. Task Completed credits recovery when early errors are followed by success and ignores tone; Response Quality judges the text (accurate, clear, well-structured) independent of task outcome.
- Negative feedback and user friction are related but distinct: negative feedback detects explicit dissatisfaction in what the user wrote; user friction detects behavioral patterns such as retry storms and clarification loops even when the user never complains.
- **Override rule:** if your application sends an `[Agent] Score` event with `[Agent] Score Name` = `user-feedback` for a session, that explicit feedback overrides the detected Negative Feedback signal for that session. Use this when you have a real thumbs control in your product.
- Signals run in every privacy mode, but their value depends on what content is available. In `metadata_only`, signals that read conversation text have little to work with; expect low-information results. Refer to the setup page's privacy matrix.

Classification values:

- `[Agent] User Intent`: Information Request, Analysis & Synthesis, Task Execution, Content Creation, Advice & Recommendation, Off-Topic / Social. Classified by the dominant intent across the session, not the greeting.
- `[Agent] Session Safety`: Normal (default), Off Topic, Prompt Injection, Abuse, Probing, Unsafe Output (agent produced harmful content), Data Leak (agent exposed PII, credentials, or internal info).

## Common properties

These appear on all or most SDK events:

| Property | Type | Description |
| --- | --- | --- |
| `[Agent] Session ID` | string | The agent session this event belongs to. Auto-generated if you don't pass one; always pass your real thread, ticket, call, or run ID in production. |
| `[Agent] Turn ID` | number | Ordinal turn within the session. One value per exchange: the user message, its tool calls, and its AI response all carry the same Turn ID. Ordering within a turn follows event time. |
| `[Agent] Trace ID` | string | Groups related operations within a session. |
| `[Agent] Agent ID` | string | The agent that produced this event. Required: without it, the Agent Analytics consumer still accepts the event (the HTTP API returns `200`) but can't correlate it into a session, so it lands misgrouped and stays out of Agent Analytics views. |
| `[Agent] Customer Org ID` | string | Your tenant identifier for B2B agents. |
| `[Agent] Env` | string | Deployment environment, for example production. |
| `[Agent] SDK Version` | string | Version of the Amplitude AI SDK. Diagnostic field; do not overwrite it with your app version, use agent versioning for that. |
| `[Agent] Context` | string (JSON) | Arbitrary key-value context you attach at agent creation (experiment variant, surface, prompt revision). |
| `[Agent] Git SHA` | string | Commit SHA the process was built from. Read from `AMPLITUDE_GIT_SHA` (or `GIT_SHA`) at SDK startup. Refer to [Capture deploy metadata](https://amplitude.com/docs/sdks/agent-analytics/sdk#capture-deploy-metadata). |
| `[Agent] Git Ref` | string | Git ref, typically a branch or tag, the process was built from. Read from `AMPLITUDE_GIT_REF` (or `GIT_REF`) at SDK startup. |
| `[Agent] Git Repo` | string | Repository URL. Opt-in via `AMPLITUDE_GIT_REPO` (or `GIT_REPO`); the SDK sanitizes the value by stripping any `user:pass@` userinfo. |

## Event property reference

### \[Agent\] User Message

| Property | Type | Notes |
| --- | --- | --- |
| `[Agent] Message ID` | string | Unique ID for this message. Reference it as a Score target. |
| `$llm_message.text` | string | The message content. Present only when the privacy mode sends content. |
| `[Agent] System Prompt` | string | The system prompt in effect. Optional field; gated by privacy mode. |
| `[Agent] Input State` | string | Application state when the message was sent. |
| `[Agent] Is Regeneration` | boolean | User asked for a redo of the previous response. Implicit negative signal. |
| `[Agent] Is Edit` / `[Agent] Edited Message ID` | boolean / string | User refined a prior message; links to the original. |
| Attachment properties | mixed | `Has Attachments`, `Attachment Count`, `Attachment Types`, `Total Attachment Size Bytes`, `Attachments`. |

### \[Agent\] AI Response

| Property | Type | Notes |
| --- | --- | --- |
| `[Agent] Message ID` | string | Unique ID; reference it as a Score target. |
| `[Agent] Model Name` | string | The model that produced the response, for example gpt-4o. |
| `[Agent] Provider` | string | The model provider, for example openai, anthropic. |
| `[Agent] Model Tier` | string | fast, standard, or reasoning; inferred from the model name. |
| `[Agent] Input Tokens` / `[Agent] Output Tokens` / `[Agent] Total Tokens` | number | Token usage. |
| `[Agent] Cache Read Tokens` / `[Agent] Cache Creation Tokens` | number | Present when you pass provider cache breakdowns; enables accurate blended cost. |
| `[Agent] Cost USD` | number | Auto-calculated from tokens and model pricing, or the value you pass directly. Omitted when the model cannot be priced. |
| `[Agent] Latency Ms` | number | Wall-clock time for the call. |
| `[Agent] TTFB Ms` | number | Time to first byte for streaming responses. |
| `[Agent] Temperature` | number | Sampling temperature. |
| `[Agent] Finish Reason` | string | Why generation stopped. |
| `[Agent] Is Error` / `[Agent] Error Message` | boolean / string | Whether the call failed and why. |
| `[Agent] Is Streaming` | boolean | The response was streamed. |
| `[Agent] Was Copied` | boolean | The user copied the output. Implicit positive signal. |
| `$llm_message.text` | string | Response content, gated by privacy mode. |

### \[Agent\] Tool Call

| Property | Type | Notes |
| --- | --- | --- |
| `[Agent] Tool Name` | string | Name of the invoked tool. |
| `[Agent] Tool Input` / `[Agent] Tool Output` | string | Tool payloads. Gated by privacy mode. |
| `[Agent] Tool Success` | boolean | Whether the tool call succeeded. |
| `[Agent] Is Error` / `[Agent] Error Message` | boolean / string | Failure details. |
| `[Agent] Latency Ms` | number | Tool execution time. |

### \[Agent\] Span and \[Agent\] Embedding

Spans carry `[Agent] Span Name`, `[Agent] Latency Ms`, `[Agent] Input State`, `[Agent] Output State`, `[Agent] Is Error`, optional parent span nesting, and any properties you attach. Embeddings carry model, provider, token, and cost properties like AI Response. Note that Embedding events do not participate in the session pipeline: they don't reset the idle clock and their costs are not included in Session Cost USD.

### \[Agent\] Session End

Refer to [How sessions close](https://amplitude.com/docs/amplitude-ai/agent-analytics/setup#how-sessions-close) for the lifecycle and timeout rules.

| Property | Type | Notes |
| --- | --- | --- |
| `[Agent] Output State` | string | Final application state for the session. |
| `[Agent] Abandonment Turn` | number | The turn after which the user left. A low value strongly signals first-response dissatisfaction. |
| `[Agent] Session Idle Timeout Minutes` | number | Tells the server how long to wait before auto-closing this session. Default 30. |

### \[Agent\] Score

Your application's feedback event. Amplitude never emits Scores; every Score in your project came from your code through `score()` or `trackScore()`.

| Property | Type | Notes |
| --- | --- | --- |
| `[Agent] Score Name` | string | The name you assign, for example user-feedback, quality. The name `user-feedback` has special semantics: it overrides the detected Negative Feedback signal for the session. |
| `[Agent] Score Value` | number | The numeric value. Use 0 and 1 for thumbs, or any scale you define. |
| `[Agent] Target ID` | string | The `[Agent] Message ID` or `[Agent] Session ID` being scored. |
| `[Agent] Target Type` | string | message or session. |
| `[Agent] Evaluation Source` | string | user, ai, or reviewer: who produced the judgment. |
| `[Agent] Comment` | string | Optional free text. Gated by privacy mode. |

### \[Agent\] Session Enrichment

Your own session-level labels: quality scores, outcomes, topics computed on your infrastructure. Sent through `trackSessionEnrichment()` or `setEnrichments()`. Works in any privacy mode; it is the primary data path in `customer_enriched` mode.

### \[Agent\] Session Record

Emitted once per session after it closes. This is the workhorse event for quality analysis: one row per session carrying every signal result plus rollups. There is exactly one Session Record per session.

Session identity and rollups:

| Property | Type | Notes |
| --- | --- | --- |
| `[Agent] Session ID` | string | The session. |
| `[Agent] Root Agent Name` | string | The agent that started the session. |
| `[Agent] Agent Chain Depth` | number | Delegation depth; greater than 1 means multi-agent. |
| `[Agent] Close Reason` | string | explicit\_close or timeout. |
| `[Agent] Turn Count` | number | Turns in the session. |
| `[Agent] Session Total Tokens` | number | Token rollup. |
| `[Agent] Session Cost USD` | number | Cost rollup for the session. |
| `[Agent] Session Avg Latency Ms` | number | Average response latency. |
| `[Agent] Models Used` | array | All models observed in the session. |
| `[Agent] Technical Error Count` | number | Errors across the session. |
| `[Agent] Topic Summary` | string | Short model-written summary of what the session was about. |
| `[Agent] Taxonomy Version` | string | Version of the signal taxonomy that produced this record. |
| `[Agent] Evaluated At` / `[Agent] Evaluation Source` | timestamp / string | When enrichment ran; source is ai. |

Signal results (refer to the signals table above for semantics):

| Property | Type |
| --- | --- |
| `[Agent] Task Completed`, plus Rationale and Evidence | boolean, strings |
| `[Agent] Response Quality`, plus Rationale and Evidence | boolean, strings |
| `[Agent] User Intent`, plus Rationale | classification, string |
| `[Agent] Session Safety`, plus Rationale | classification, string |
| `[Agent] Has User Friction`, plus Rationale and `[Agent] Detected User Friction` | boolean, string, array |
| `[Agent] Has Negative Feedback`, plus Rationale and `[Agent] Detected Negative Feedback` | boolean, string, array |
| `[Agent] Has Data Quality Issues`, plus `[Agent] Detected Data Quality Issues` | boolean, array |
| `[Agent] Has Technical Failure` | boolean |
| `[Agent] Has User Feedback` / `[Agent] User Score` | boolean / number, present when your app sent a user-feedback Score |

### \[Agent\] Evaluator Result

Emitted once per active custom evaluator per closed session. Custom evaluators are the ones you define and calibrate in the Amplitude UI; the built-in signals do not produce Evaluator Result events.

Evaluator identity and output:

| Property | Type | Notes |
| --- | --- | --- |
| `[Agent] Evaluator Name` | string | The evaluator, for example Completed Interaction. |
| `[Agent] Evaluator Output Type` | string | binary, classification, or score. |
| `[Agent] Evaluator Version` | string | Version of the evaluator definition. |
| `[Agent] Evaluator Model` | string | The judge model, formatted provider:model, for example openai:gpt-5-mini. |
| `[Agent] Evaluator Enrichment Cost USD` | number | What this evaluation cost to run. |
| `[Agent] Binary Label` / `[Agent] Binary Value` | boolean / number | The result, for binary evaluators. |
| `[Agent] Primary Label` / `[Agent] Subcategories` | string / array | The result, for classification evaluators. |
| `[Agent] Score Value` / `[Agent] Score Label` | number / string | The result, for score evaluators. |
| `[Agent] Evaluated At` / `[Agent] Evaluation Source` | timestamp / string | When it ran; source is ai. |

Session dimensions, echoed onto every Evaluator Result so you can segment evaluator outcomes without joining to the Session Record: `[Agent] Root Agent Name`, `[Agent] Agent Chain Depth`, `[Agent] Close Reason`, `[Agent] Turn Count`, `[Agent] Session Total Tokens`, `[Agent] Session Cost USD`, `[Agent] Session Avg Latency Ms`, `[Agent] Models Used`, `[Agent] Technical Error Count`, `[Agent] Topic Summary`, the `Has` flags, and `[Agent] User Score` when present.

## How cost is calculated

`[Agent] Cost USD` is computed exactly once, in the SDK, at the moment the event is tracked. Nothing downstream recomputes it: the server reads the value verbatim and sums it. Automatic pricing multiplies the event's token counts against a continuously maintained open-source model price catalog (Pydantic's `genai-prices` project, bundled with the SDK), so standard model identifiers matter. A cost you pass explicitly always wins over automatic pricing and is emitted as given, including zero.

What prices, and what doesn't:

- **Cache-aware blending.** With cache token breakdowns, uncached input, cache reads, and cache writes are each priced at their own rate; without them, cache-heavy workloads can overestimate by 2 to 5x.
- **Unpriceable models.** The SDK can't automatically price nonstandard names, gateway aliases (for example `openrouter/auto`), or **fine-tuned `ft:` model names**. It omits the property and logs a warning once per model. For fine-tuned or custom models, pass the cost yourself.
- **Pricing freshness.** Prices ship with the SDK's bundled catalog, and the SDK doesn't fetch updates by default. For newly released models, call `enableLivePriceUpdates()` (Node) or `enable_live_price_updates()` (Python) at startup to refresh prices hourly. If a refresh fails, the SDK continues to use its bundled catalog. Live updates don't reprice existing events. Refer to [Keep pricing data current](https://amplitude.com/docs/sdks/agent-analytics/sdk#keep-pricing-data-current) for configuration details.

If you send events directly instead of through the SDK, provide the cost yourself: `[Agent] Cost USD` for HTTP events or `gen_ai.usage.cost` for OTLP spans. Amplitude stores the value you send and doesn't reprice direct events because they may not include all inputs needed for an accurate estimate.

**`[Agent] Session Cost USD`** on the Session Record is the sum of `[Agent] Cost USD` across the session's `[Agent] AI Response` events, and it is **all-or-nothing**: if any event with token usage carries no cost (an unpriced model, for instance), the property is omitted from the Session Record entirely rather than reporting a partial total. Embedding events do not participate in the session pipeline, so embedding costs never contribute. The value is accumulated at ingest and fixed when the session is enriched; events arriving after that do not change it.

**Judge costs are separate, structurally.** `[Agent] Evaluator Enrichment Cost USD` appears on `[Agent] Evaluator Result` events for evaluators you define and can never leak into Session Cost USD. The cost of Amplitude's built-in signals is not reported anywhere; it's included in the product.

Everything is USD end to end, with no currency conversion anywhere. Treat your provider's bill as the financial source of truth; heavily cached or batch-discounted workloads may diverge. Agent Analytics cost data is the analytical view: per-agent, per-user, per-topic attribution your bill can't give you.

## Managed schema

The `[Agent]` taxonomy is managed by Amplitude: property names, types, and registration in your data catalog are handled for you. To add your own dimensions, use `[Agent] Context` (a JSON property present on SDK events and echoed onto the Session Record) or emit standard product events from your tools; do not add unregistered flat properties to `[Agent]` events, as they may not be queryable in charts.

