Skip to content

Agent Metrics

Buddy records token usage and timing for every run. Metrics come from two places: the per-run RunResponse.metrics dictionary and the cumulative agent.session_metrics object.

SessionMetrics

buddy.agent.metrics.SessionMetrics is a dataclass holding cumulative counters for a session:

Field Type Meaning
input_tokens int Prompt tokens sent to the model.
output_tokens int Tokens generated by the model.
total_tokens int Sum of input and output tokens.
prompt_tokens / completion_tokens int Provider-reported prompt/completion counts.
audio_tokens, input_audio_tokens, output_audio_tokens int Audio token counts.
cached_tokens / cache_write_tokens int Prompt-cache read/write tokens.
reasoning_tokens int Tokens spent on reasoning.
prompt_tokens_details / completion_tokens_details dict Provider-specific breakdowns.
additional_metrics dict Any extra provider metrics.
time float Total elapsed time (seconds).
time_to_first_token float Latency to the first streamed token.

SessionMetrics supports + and sum() so per-message metrics aggregate cleanly across a session.

Accessing metrics after a run

After a run completes, read the aggregated per-run metrics from the RunResponse, and the cumulative session totals from the agent:

from buddy import Agent
from buddy.models.openai import OpenAIChat

agent = Agent(model=OpenAIChat(id="gpt-4o"))
response = agent.run("Explain vector databases in two sentences.")

# Per-run aggregated metrics (dict of lists, one entry per assistant message)
print(response.metrics)
# e.g. {'input_tokens': [42], 'output_tokens': [58], 'total_tokens': [100],
#       'time': [1.84], ...}

# Cumulative SessionMetrics for the whole session
print(agent.session_metrics.total_tokens)
print(agent.session_metrics.time)

Shape of RunResponse.metrics

RunResponse.metrics is a dict[str, list]. Each key (for example input_tokens or time) maps to a list with one value per qualifying assistant message in the run. This is produced by Agent.aggregate_metrics_from_messages().

How metrics are computed

  • Each model response carries MessageMetrics. During a run, Buddy sums these into agent.session_metrics via calculate_metrics() and aggregates them into the run dict via aggregate_metrics_from_messages().
  • Only assistant messages from the current run (from_history is False) are counted, so replayed history does not double-count tokens.
  • Timing fields are driven by an internal Timer; time_to_first_token is set on the first streamed token.

Persistence

When storage is configured, session_metrics is serialized into the session record (session_data["session_metrics"]) and rehydrated into a SessionMetrics instance when the session is read back. This lets token and time totals survive across process restarts.

Tip

To attribute cost, multiply input_tokens / output_tokens from session_metrics by your provider's per-token pricing. The prompt_tokens_details and completion_tokens_details dicts can break this down further when the provider supplies them.

See Agent lifecycle for where metric aggregation happens during a run.