Skip to content

Bug: .NET: Gemini connector emits duplicate token usage metrics during streaming (similar to #12977 for Python/OpenAI) #13382

@Cozmopolit

Description

@Cozmopolit

Describe the bug

The .NET Gemini connector emits OpenTelemetry token usage metrics for every streaming chunk instead of only once at the end. This causes inflated token usage and cost tracking in downstream telemetry systems.

To Reproduce

  1. Use GeminiChatCompletionClient with streaming enabled
  2. Monitor the OpenTelemetry counters (s_promptTokensCounter, s_completionTokensCounter, s_totalTokensCounter) which expose the metrics Microsoft.SemanticKernel.Connectors.Google.tokens.prompt, Microsoft.SemanticKernel.Connectors.Google.tokens.completion, and Microsoft.SemanticKernel.Connectors.Google.tokens.total.
  3. Observe metrics are emitted for every chunk (e.g., 30 chunks = 30 metric events for a single API call)

Expected: Token usage metrics emitted once per API call
Actual: Token usage metrics emitted once per streaming chunk

Root Cause

In ProcessChatResponseStreamAsync (around line 540 in commit 5948dbc), the method calls ProcessChatResponse() for every streaming chunk, which in turn calls LogUsage() (around line 568).

The Gemini API sends accumulated token counts in every chunk (not deltas), so each LogUsage() call emits the full token count to the OpenTelemetry counters (around lines 600–602).

File: dotnet/src/Connectors/Connectors.Google/Core/Gemini/Clients/GeminiChatCompletionClient.cs

Comparison with OpenAI Connector

The OpenAI connector does not call LogUsage() during streaming—only after non-streaming completion (see GetChatMessageContentsAsync around line 173 in the same commit).

File: dotnet/src/Connectors/Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs

Related

This appears to be the same bug pattern that was fixed for Python/OpenAI in #12977 (merged Sep 3, 2025).

Impact

Production systems show inflated costs (e.g., $0.40 logged vs. $0.02 actual API cost) due to duplicate telemetry.

Environment

  • SK Version: 1.66.0 (commit 5948dbc)
  • Connector: Microsoft.SemanticKernel.Connectors.Google
  • Models: All Gemini models (observed with gemini-2.5-pro)
  • .NET: 8+

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions