Skip to content

fix(eval): leave turns with no reported usage out of the token_usage_v1 average - #7735

Closed
Fruiterer333 wants to merge 1 commit into
google:mainfrom
Fruiterer333:fix/token-usage-average
Closed

Fruiterer333 wants to merge 1 commit into
google:mainfrom
Fruiterer333:fix/token-usage-average

Conversation

@Fruiterer333

@Fruiterer333 Fruiterer333 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Problem:

token_usage_v1 reports n/a for a turn whose model calls returned no usage metadata, but _TokenUsageV1Evaluator._average still counts that turn in the denominator as 0 tokens. With one turn that used 1,000 tokens and one turn with no reported usage, the overall is 500. The efficiency metrics README says "n/a never means zero", and inference_call_count_v1 and invocation_duration_v1 already leave n/a turns out of their averages.

Solution:

_average now builds its shared denominator from the invocations that reported at least one count. Within those invocations, a missing count still averages as zero (unchanged behavior, covered by test_token_usage_averages_an_unreported_count_as_zero_for_that_turn), and total == input + output still holds after averaging. If no invocation reported usage, every count stays None, as before.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Added test_token_usage_average_leaves_out_a_turn_that_reported_no_usage. It fails on main (assert 520.0 == 1040.0) and passes with this change.

$ pytest tests/unittests/evaluation/test_efficiency_evaluators.py
40 passed
$ pytest tests/unittests/evaluation
1136 passed

pyink --check, isort --check-only, codespell and mypy pass on the changed files.

Manual End-to-End (E2E) Tests:

Ran the reproduction script from #7734, which gets the evaluators through DEFAULT_METRIC_EVALUATOR_REGISTRY (no model call needed):

# before (main)
token_usage_v1           per turn=[1000.0, None]  overall=500.0
inference_call_count_v1  per turn=[1.0, 1.0]  overall=1.0
 
# after
token_usage_v1           per turn=[1000.0, None]  overall=1000.0
inference_call_count_v1  per turn=[1.0, 1.0]  overall=1.0

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

I used Claude Code to help find the issue and draft the change. I reproduced the bug, reviewed every line, and ran the tests above myself.

copybara-service Bot pushed a commit that referenced this pull request Oct 27, 2026
Merge #7735

The overall `token_usage_v1` value, and each averaged count under it, now
divides by the turns that reported input or output tokens. A turn that
reported neither already read n/a, including one that reported only cached
tokens; it no longer lowers the overall value as a zero. Per-turn values are unchanged, and a count missing from a
turn that did report usage still averages as zero.

Fixes #7734

PiperOrigin-RevId: 1007857232
@adk-bot

adk-bot commented Oct 27, 2026

Copy link
Copy Markdown
Collaborator

Thank you @Fruiterer333 for your contribution! 🎉

Your changes have been successfully imported and merged via Copybara in commit 5e52b21.

Closing this PR as the changes are now in the main branch.

@adk-bot adk-bot added the merged [Status] This PR is merged label Oct 27, 2026
@adk-bot adk-bot closed this Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged [Status] This PR is merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

token_usage_v1 averages a turn with no reported usage as 0, so the overall understates tokens per turn

3 participants