LLM.Usage (LLM v0.2.0)

Copy Markdown View Source

Token usage and cost information from an LLM request.

Reports token counts and optionally computed costs when pricing data is available. All fields default to 0 so usage structs can be accumulated across multiple requests without nil-checking.

Fields

  • :input_tokens — tokens in the prompt/messages sent to the model
  • :output_tokens — tokens in the model's response
  • :cache_read_tokens — tokens served from prompt cache
  • :cache_write_tokens — tokens written to prompt cache
  • :total_tokens — sum of all token counts
  • :input_cost — USD cost for input tokens
  • :output_cost — USD cost for output tokens
  • :cache_read_cost — USD cost for cache read tokens
  • :cache_write_cost — USD cost for cache write tokens
  • :total_cost — sum of all USD cost fields

Accumulation

Use add/2 to merge usage across tool-call rounds or multi-turn requests. Use sum/1 to reduce a list of usage structs.

usage1 = LLM.Usage.new(input_tokens: 100, output_tokens: 50)
usage2 = LLM.Usage.new(input_tokens: 200, output_tokens: 80)
LLM.Usage.add(usage1, usage2)
#=> %LLM.Usage{input_tokens: 300, output_tokens: 130, total_tokens: 430}

Cost computation

When pricing data is available (from provider or call-site options), compute_cost/2 calculates USD costs from token counts:

pricing = %{input: 3.0, output: 15.0}
usage = LLM.Usage.new(input_tokens: 1_000_000, output_tokens: 500_000)
LLM.Usage.compute_cost(usage, pricing)
#=> %LLM.Usage{..., input_cost: 3.0, output_cost: 7.5, total_cost: 10.5}

Summary

Functions

Sum corresponding fields of two usage structs.

Compute USD costs from token counts using per-million-token pricing.

Create a usage struct from a keyword list or map.

Reduce a list of usage structs into a single summed usage.

Types

pricing()

@type pricing() :: %{
  input: number(),
  output: number(),
  cache_read: number(),
  cache_write: number()
}

t()

@type t() :: %LLM.Usage{
  cache_read_cost: number(),
  cache_read_tokens: non_neg_integer(),
  cache_write_cost: number(),
  cache_write_tokens: non_neg_integer(),
  input_cost: number(),
  input_tokens: non_neg_integer(),
  output_cost: number(),
  output_tokens: non_neg_integer(),
  total_cost: number(),
  total_tokens: non_neg_integer()
}

Functions

add(a, b)

@spec add(t(), t()) :: t()

Sum corresponding fields of two usage structs.

Useful for accumulating token usage across multiple API calls or tool-call rounds.

usage1 = LLM.Usage.new(input_tokens: 100, output_tokens: 50)
usage2 = LLM.Usage.new(input_tokens: 200, output_tokens: 80)
LLM.Usage.add(usage1, usage2)
#=> %LLM.Usage{input_tokens: 300, output_tokens: 130, total_tokens: 430}

compute_cost(usage, pricing)

@spec compute_cost(t(), pricing()) :: t()

Compute USD costs from token counts using per-million-token pricing.

Pricing is a map with cost per million tokens:

pricing = %{input: 3.0, output: 15.0, cache_read: 0.3, cache_write: 3.75}

Only computes costs if the usage struct has non-zero token counts and pricing values are provided. Returns the usage struct with cost fields populated.

usage = LLM.Usage.new(input_tokens: 1_000_000, output_tokens: 500_000)
LLM.Usage.compute_cost(usage, %{input: 3.0, output: 15.0})
#=> %LLM.Usage{..., input_cost: 3.0, output_cost: 7.5, total_cost: 10.5}

new(attrs)

@spec new(Enumerable.t()) :: t()

Create a usage struct from a keyword list or map.

Computes total_tokens automatically if not provided.

LLM.Usage.new(input_tokens: 10, output_tokens: 20)
#=> %LLM.Usage{input_tokens: 10, output_tokens: 20, total_tokens: 30}

sum(usages)

@spec sum([t()]) :: t()

Reduce a list of usage structs into a single summed usage.

usages = [
  LLM.Usage.new(input_tokens: 100, output_tokens: 50),
  LLM.Usage.new(input_tokens: 200, output_tokens: 80)
]
LLM.Usage.sum(usages)
#=> %LLM.Usage{input_tokens: 300, output_tokens: 130, total_tokens: 430}