-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Closed
Labels
ai/providerprovider/amazon-bedrockIssues related to the @ai-sdk/amazon-bedrock providerIssues related to the @ai-sdk/amazon-bedrock providerprovider/anthropicsupport
Description
Description
I've noticed that the logic for calculating inputTokens and inputTokenDetails is inconsistent for claude between Anthropic as the provider and Amazon Bedrock as the provider. Here's an example script:
import "dotenv/config"
import logger from "@/utils/logger"
import { generateText } from "ai"
import { anthropic } from "@ai-sdk/anthropic"
import { createAmazonBedrock } from "@ai-sdk/amazon-bedrock"
import { env } from "@/env.mjs"
const bedrock = createAmazonBedrock({
region: "us-east-2",
accessKeyId: env.accessKeyId,
secretAccessKey: env.secretAccessKey,
})
// System prompt must be at least 1024 tokens for Anthropic caching to work
const systemPrompt = `<a long system prompt...>`
const userMessage = "What is 2 + 2? Reply with just the number."
async function testAnthropicProvider() {
logger.info("=== Testing Anthropic Provider ===")
const result = await generateText({
model: anthropic("claude-sonnet-4-5-20250929"),
messages: [
{
role: "system",
content: systemPrompt,
providerOptions: {
anthropic: { cacheControl: { type: "ephemeral" } },
},
},
{
role: "user",
content: userMessage,
},
],
})
logger.info("Anthropic response", { text: result.text })
logger.info("Anthropic usage", { usage: result.usage })
}
async function testBedrockProvider() {
logger.info("=== Testing Bedrock Provider ===")
const result = await generateText({
model: bedrock("global.anthropic.claude-sonnet-4-5-20250929-v1:0"),
messages: [
{
role: "system",
content: systemPrompt,
providerOptions: {
bedrock: { cachePoint: { type: "default" } },
},
},
{
role: "user",
content: userMessage,
},
],
})
logger.info("Bedrock response", { text: result.text })
logger.info("Bedrock usage", { usage: result.usage })
}
export default async function main() {
try {
await testAnthropicProvider()
} catch (error) {
logger.error("Anthropic error", { error })
}
try {
await testBedrockProvider()
} catch (error) {
logger.error("Bedrock error", { error })
}
}
logger.info(`${scriptName}...`)
await main()
logger.info(`${scriptName}... done`)Here is the Anthropic usage:
{
"inputTokens": 2590,
"inputTokenDetails": {
"noCacheTokens": 21,
"cacheReadTokens": 0,
"cacheWriteTokens": 2569
},
"outputTokens": 5,
"outputTokenDetails": {},
"totalTokens": 2595,
"raw": {
"input_tokens": 21,
"output_tokens": 5,
"cache_creation_input_tokens": 2569,
"cache_read_input_tokens": 0,
"cache_creation": {
"ephemeral_5m_input_tokens": 2569,
"ephemeral_1h_input_tokens": 0
},
"service_tier": "standard"
},
"cachedInputTokens": 0
}Here is the Bedrock usage
{
"inputTokens": 21,
"inputTokenDetails": {
"noCacheTokens": 21,
"cacheReadTokens": 0,
"cacheWriteTokens": 2569
},
"outputTokens": 5,
"outputTokenDetails": {
"textTokens": 5
},
"totalTokens": 26,
"raw": {
"inputTokens": 21,
"outputTokens": 5,
"totalTokens": 2595,
"cacheReadInputTokens": 0,
"cacheWriteInputTokens": 2569
},
"cachedInputTokens": 0
}Anthropic includes the cacheReadTokens and cacheWriteTokens in the inputTokens whereas Bedrock does not. Additionally Bedrock computes the noCacheTokens as inputTokens - cacheReadTokens which often times results in a negative value.
AI SDK Version
"@ai-sdk/amazon-bedrock": "^4.0.4",
"@ai-sdk/anthropic": "^3.0.1",
"ai": "^6.0.3",
Code of Conduct
- I agree to follow this project's Code of Conduct
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
ai/providerprovider/amazon-bedrockIssues related to the @ai-sdk/amazon-bedrock providerIssues related to the @ai-sdk/amazon-bedrock providerprovider/anthropicsupport