Bug Description
When using client.messages.stream() with base64 images in message content, the OpenTelemetry span reports inflated input_tokens. Non-streaming client.messages.create() reports correctly.
Reproduction
import base64, io, os
from anthropic import Anthropic
from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor
from PIL import Image
AnthropicInstrumentor().instrument()
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
img = Image.new("RGB", (500, 500), color=(200, 200, 255))
buf = io.BytesIO()
img.save(buf, format="PNG")
b64 = base64.b64encode(buf.getvalue()).decode()
messages = [{
"role": "user",
"content": [
{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": b64}},
{"type": "text", "text": "What color is this? One word."},
],
}]
# Non-streaming
response = client.messages.create(model="claude-haiku-4-5-20251001", max_tokens=100, messages=messages)
print(f"[CREATE] API usage: input={response.usage.input_tokens}")
# Streaming
with client.messages.stream(model="claude-haiku-4-5-20251001", max_tokens=100, messages=messages) as stream:
response = stream.get_final_message()
print(f"[STREAM] API usage: input={response.usage.input_tokens}")
Observed Behavior
| Method |
API usage.input_tokens |
OTel span reported |
create() |
343 |
343 |
stream() |
343 |
1,633 |
Expected Behavior
OTel span should match the API's usage.input_tokens for both methods.
Environment
opentelemetry-instrumentation-anthropic: 0.57.0
anthropic: 0.89.0
- Python 3.11
Bug Description
When using
client.messages.stream()with base64 images in message content, the OpenTelemetry span reports inflatedinput_tokens. Non-streamingclient.messages.create()reports correctly.Reproduction
Observed Behavior
usage.input_tokenscreate()stream()Expected Behavior
OTel span should match the API's
usage.input_tokensfor both methods.Environment
opentelemetry-instrumentation-anthropic: 0.57.0anthropic: 0.89.0