<!-- Sema documentation — std.usage
     Sema is a new AI-native, neurosymbolic programming language most models
     have not been trained on. Full corpus: https://sema.49.12.246.95.sslip.io/llms-full.txt
     Install language support: https://sema.49.12.246.95.sslip.io/install-skill/ -->

# std.usage

> Model usage accounting — accumulate token counts across calls and price them with caller-supplied rates. Complements the ambient with meter scope.

`std.usage` is explicit **model usage accounting**: a `Usage` struct you add up
across calls, and a `Pricing` struct that turns those counts into a cost estimate.
Rates are always passed in by the caller — nothing is hardcoded.

```sema
from std.usage import Usage, Pricing, zero, estimate_cost
```

## Why it exists

Tracking tokens and cost across a pipeline is otherwise done by threading a
`(result, usage)` tuple through every function, or by a heavyweight metadata
tracker (SymbolicAI's `MetadataTracker` was ~470 lines). `std.usage` gives you a
small, addable value instead — and because `Pricing` is a parameter, the same
accounting works for any provider's rate card.

## `Usage` — an accumulating tally

`Usage` records prompt, completion, reasoning, and cached tokens, plus call and
token totals and a running `cost_estimate`. Start from `zero()` and combine tallies
with `add`, which returns a **new** summed `Usage`:

```sema
from std.usage import Usage, zero

total = zero()
total = total.add(call_one_usage)
total = total.add(call_two_usage)
print(total.total_tokens, total.total_calls)
```

## `Pricing` — caller-supplied rates

`Pricing` holds per-unit rates: `input`, `cached_input`, `output`, and per-`calls`.
`estimate_cost(u, p)` prices a `Usage` against a `Pricing`, charging cached input
tokens at the cached rate and everything else at its rate:

```sema
from std.usage import Pricing, estimate_cost

rates = Pricing(input=0.00000015, cached_input=0.000000075,
                output=0.0000006, calls=0.0)
cost = estimate_cost(total, rates)
print(cost)     # dollars, given these rates
```

## Ambient metering vs. explicit accounting

`std.usage` is the *explicit* path — you hold and pass the `Usage` values
yourself. For *ambient, automatic* accounting, Sema has a language construct:

```sema
with meter as u:
    summary = summarize(article)     # any model.invoke inside is counted
print(u.total_tokens)
```

The `with meter as u:` scope (spec §3.6) tallies every model call in its body
without any tuple threading, and `with budget(tokens=…, calls=…) as b:` adds a
hard spend cap that aborts when exceeded. Use the ambient scopes for enforcement
and convenience; use `std.usage` when you need to hold, merge, or serialize
tallies explicitly.

:::tip[Governance builds on this]
Usage accounting is the raw material for spend caps and reporting. See
[Budgets](/governance/budget/) for how `with budget(...)` turns these counts
into enforced limits.
:::

:::note[add and estimate_cost are pure]
`Usage.add`, `zero`, and `estimate_cost` all carry `!{}` — no I/O, no model
calls. They are safe to use anywhere in the deterministic core.
:::

See the full field and function reference in the generated
[std.usage API reference](/reference/stdlib-api/usage/).
