> ## Documentation Index
> Fetch the complete documentation index at: https://docs.upsonic.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Metrics

> Track tokens, cost, requests, tool calls, and timing across every model call this agent participates in.

## Overview

Every agent exposes a single read-only **`agent.usage`** property. It returns an `AggregatedUsage` view derived from the [centralized usage registry](/concepts/usage-registry) on each access, scoped to this agent's `agent_usage_id`.

Sub-pipeline model calls — memory summarization, reliability validator/editor, culture, policy, and sub-agents invoked as tools — automatically inherit the agent's scope and roll into `agent.usage` without any manual propagation.

When printing is enabled (`print_do` / `print_do_async`), an **Agent Metrics** panel is displayed after each task so you can see the updated totals.

## Accessing Agent Metrics

Read **`agent.usage`** on any `Agent` instance. It always returns an `AggregatedUsage` — zero-valued before the first run, populated thereafter.

### Token Metrics

| Property             | Type  | Description                                    |
| -------------------- | ----- | ---------------------------------------------- |
| `input_tokens`       | `int` | Total prompt/input tokens across all runs      |
| `output_tokens`      | `int` | Total completion/output tokens across all runs |
| `total_tokens`       | `int` | Sum of `input_tokens + output_tokens`          |
| `cache_read_tokens`  | `int` | Tokens read from prompt cache                  |
| `cache_write_tokens` | `int` | Tokens written to prompt cache                 |
| `reasoning_tokens`   | `int` | Reasoning (chain-of-thought) tokens            |

### Request & Tool Metrics

| Property     | Type  | Description                           |
| ------------ | ----- | ------------------------------------- |
| `requests`   | `int` | Total number of LLM API requests made |
| `tool_calls` | `int` | Total number of tool calls executed   |

### Timing Metrics

| Property                 | Type            | Description                                                     |
| ------------------------ | --------------- | --------------------------------------------------------------- |
| `duration`               | `float`         | Sum of per-call durations across contributing entries (seconds) |
| `model_execution_time`   | `float`         | Total time spent inside LLM API calls (seconds)                 |
| `tool_execution_time`    | `float`         | Total time spent executing tools (seconds)                      |
| `upsonic_execution_time` | `float`         | Framework overhead = `duration − model − tool` (seconds)        |
| `time_to_first_token`    | `float \| None` | Earliest TTFT across contributing entries                       |

### Cost Metrics

| Property | Type            | Description                                                                                                |
| -------- | --------------- | ---------------------------------------------------------------------------------------------------------- |
| `cost`   | `float \| None` | Sum of `cost_usd` across contributing entries. `None` if no entry was priced; `0.0` means priced and free. |

### Aggregation Metadata

| Property      | Type        | Description                                                      |
| ------------- | ----------- | ---------------------------------------------------------------- |
| `entry_count` | `int`       | Number of underlying `UsageEntry` rows contributing to this view |
| `models`      | `list[str]` | Distinct model identifiers that contributed (first-seen order)   |

## Example

```python theme={null}
from upsonic import Agent, Task

agent = Agent("anthropic/claude-sonnet-4-5", print=True)
agent.print_do(Task("What is 2 + 2? Reply with one number."))
agent.print_do(Task("What is 3 + 3? Reply with one number."))

u = agent.usage

print(f"Requests:        {u.requests}")
print(f"Input tokens:    {u.input_tokens}")
print(f"Output tokens:   {u.output_tokens}")
print(f"Tool calls:      {u.tool_calls}")
if u.cost is not None:
    print(f"Cost:            ${u.cost:.4f}")
print(f"Model time:      {u.model_execution_time:.2f}s")
print(f"Tool time:       {u.tool_execution_time:.2f}s")
print(f"Framework time:  {u.upsonic_execution_time:.2f}s")
print(f"Models used:     {u.models}")
```

## Printed Panel

When you use `print_do` or `print_do_async`, the **Agent Metrics** panel displays after each task:

```
╭──────────────────── Agent Metrics ────────────────────╮
│  Agent:                  MyAgent                      │
│                                                       │
│  Total Requests:         4                            │
│  Total Input Tokens:     1,552                        │
│  Total Output Tokens:    915                          │
│  Total Tool Calls:       2                            │
│  Total Estimated Cost:   $0.0008                      │
│  Total Duration:         21.55 seconds                │
│  Model Execution Time:   18.17 seconds                │
│  Tool Execution Time:    1.00 seconds                 │
│  Framework Overhead:     2.38 seconds                 │
╰───────────────────────────────────────────────────────╯
```

## Scope & Propagation

* **Across tasks** — Every call to `do` / `print_do` / `do_async` / `print_do_async` records entries against the agent's scope. Reading `agent.usage` re-aggregates them, so the figures always reflect the latest state.
* **Sub-pipeline rollup** — Memory summarization, reliability validator/editor, culture, policy, and sub-agent calls inherit the parent's scope via context variables and roll into `agent.usage` automatically.
* **Retry idempotency** — The registry is keyed by `entry_id`. Retried requests replace their prior entry instead of double-counting.
* **Independent agents** — Each `Agent` instance has its own `agent_usage_id`. Two different agents never share usage.
* **JSON snapshot** — Call `agent.usage.to_dict()` for a flat dict suitable for logs and dashboards.

## Legacy Migration

<Note>
  Legacy surfaces have been removed in favour of `agent.usage`:

  | Legacy                                                  | Replacement                            |
  | ------------------------------------------------------- | -------------------------------------- |
  | `agent.cost` (dict)                                     | `agent.usage.to_dict()`                |
  | `AgentUsage.incr()` / accumulator fields                | (registry-derived; no mutation needed) |
  | `agent._finalize_agent_usage`, retry baseline machinery | (registry is idempotent)               |
</Note>

## Related Documentation

* [Usage Registry](/concepts/usage-registry) — Architecture, scope tags, persistence
* [Task Metrics](/concepts/tasks/metrics) — Per-task scoped view
* [Chat Metrics](/concepts/chat/metrics) — Per-session scoped view
* [Team Metrics](/concepts/team/metrics) — Per-team scoped view
