Contains token usage information returned from an LLM.
Example
%TokenUsage{
input: 30,
output: 15,
raw: %{
"total_tokens" => 29
}
}Input is the tokens from the prompt. Output is the completion or generated tokens returned.
Refer to the raw token usage information for access to LLM-specific information that may be available.
Combining usage
Two different questions call for two different combinations, and the caller knows which one it is asking:
add/2combines several readings of the same message, as a streamed response produces. Each reading is a snapshot of the message so far, so the combination keeps the largest count per field.add_total/2combines the final usage of different messages into a running total for a conversation. Each operand is already settled for its own message, so the combination sums them.
Summary
Functions
Combines two readings of the same message into one.
Adds one completed message's usage to a running total across messages.
Extracts token usage information from a LangChain.Message or
LangChain.MessageDelta struct's metadata. Returns nil if no token usage
information is found.
Build a new TokenUsage and return an :ok/:error tuple with the result.
Build a new TokenUsage and return it or raise an error if invalid.
Sets the token usage information on a LangChain.Message or
LangChain.MessageDelta struct in the metadata under the :usage key.
Sets the token usage information on a LangChain.Message or
LangChain.MessageDelta struct when wrapped in an :ok,:error tuple in the metadata under the :usage key.
Return the total token usage amount. The total is the sum of input and output.
Types
Functions
Combines two readings of the same message into one.
A streamed response reports usage more than once, and each reading is a
snapshot of the message so far rather than a description of one delta's share.
Anthropic opens with the input classes on message_start and closes with a
total on message_delta; Gemini repeats the running totals on every chunk;
OpenAI-shaped providers answer with a single snapshot on a usage-only terminal
chunk. Combining snapshots keeps the larger of the two readings per field.
Token counts are counters, so a count never decreases while a message is being generated. Providers differ in how completely each reading repeats the picture: some report every class every time, some report only the classes that changed, and some normalize an unreported class to zero. Keeping the larger reading is correct under all three -- a fuller reading advances the total, and a partial one cannot erase a class it never meant to describe.
The raw maps are merged the same way, at every depth, so map-valued usage
details such as prompt_tokens_details and completion_tokens_details advance
per-key rather than the later map replacing the earlier one. A detail reported
as a list of per-modality objects, the shape Gemini uses for
promptTokensDetails, offers no key to advance against and is taken from the
later usage whole.
Keeping the larger count is sound for a primitive counter. A raw key holding
a value derived from other counts within a single reading, such as a
total_tokens an adapter computes as input + output, is only meaningful
alongside the reading it came from and does not survive the merge intact. Read
the total from total/1 rather than from raw.
To total usage across different messages, use add_total/2.
If both arguments are nil, returns nil. If one argument is nil, returns the non-nil argument.
Example
iex> alias LangChain.TokenUsage
iex> opening = TokenUsage.new!(%{input: 25, output: 1, raw: %{"input_tokens" => 25}})
iex> closing = TokenUsage.new!(%{output: 15, raw: %{"output_tokens" => 15}})
iex> combined = TokenUsage.add(opening, closing)
iex> {combined.input, combined.output}
{25, 15}
iex> combined.raw
%{"input_tokens" => 25, "output_tokens" => 15}
Adds one completed message's usage to a running total across messages.
Use this, rather than add/2, whenever the two operands are totals for
different messages. Each assembled message's usage is already final for that
message, so the values are summed, at every depth of the raw map.
If both arguments are nil, returns nil. If one argument is nil, returns the non-nil argument.
Example
iex> alias LangChain.TokenUsage
iex> first = TokenUsage.new!(%{input: 100, output: 20})
iex> second = TokenUsage.new!(%{input: 150, output: 35})
iex> total = TokenUsage.add_total(first, second)
iex> {total.input, total.output}
{250, 55}
Extracts token usage information from a LangChain.Message or
LangChain.MessageDelta struct's metadata. Returns nil if no token usage
information is found.
Example
iex> message = %LangChain.Message{metadata: %{usage: %LangChain.TokenUsage{input: 10, output: 20}}}
iex> LangChain.TokenUsage.get(message)
%LangChain.TokenUsage{input: 10, output: 20}
iex> message = %LangChain.Message{metadata: %{}}
iex> LangChain.TokenUsage.get(message)
nil
@spec new(attrs :: map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
Build a new TokenUsage and return an :ok/:error tuple with the result.
Build a new TokenUsage and return it or raise an error if invalid.
Sets the token usage information on a LangChain.Message or
LangChain.MessageDelta struct in the metadata under the :usage key.
Example
iex> message = %LangChain.Message{metadata: %{}}
iex> token_usage = %LangChain.TokenUsage{input: 10, output: 20}
iex> LangChain.TokenUsage.set(message, token_usage)
%LangChain.Message{metadata: %{usage: %LangChain.TokenUsage{input: 10, output: 20}}}
@spec set_wrapped( {:ok, %{metadata: nil | map()}} | {:error, any()} | any(), nil | t() ) :: {:ok, %{metadata: %{usage: t()}}} | {:error, any()} | any()
Sets the token usage information on a LangChain.Message or
LangChain.MessageDelta struct when wrapped in an :ok,:error tuple in the metadata under the :usage key.
Return the total token usage amount. The total is the sum of input and output.
A count a provider never reported is nil and contributes nothing to the
total. Anthropic's closing message_delta event, for one, carries only
output_tokens, so a usage built from it alone has no input count.