Skip to content

Commit cc022b0

Browse files
authored
fix(anthropic): include cache creation/read tokens in input_tokens of usage metadata (#9520)
1 parent dc396c4 commit cc022b0

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

.changeset/cool-times-tell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@langchain/anthropic": patch
3+
---
4+
5+
Includes cache creation/read tokens in input_tokens of usage metadata

libs/providers/langchain-anthropic/src/tests/chat_models.int.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,11 +867,17 @@ test("system prompt caching", async () => {
867867
res.usage_metadata?.input_token_details?.cache_creation
868868
).toBeGreaterThan(0);
869869
expect(res.usage_metadata?.input_token_details?.cache_read).toBe(0);
870+
expect(res.usage_metadata?.input_tokens).toBeGreaterThan(
871+
res.usage_metadata?.input_token_details?.cache_creation ?? 0
872+
);
870873
const res2 = await model.invoke(messages);
871874
expect(res2.usage_metadata?.input_token_details?.cache_creation).toBe(0);
872875
expect(res2.usage_metadata?.input_token_details?.cache_read).toBeGreaterThan(
873876
0
874877
);
878+
expect(res2.usage_metadata?.input_tokens).toBeGreaterThan(
879+
res2.usage_metadata?.input_token_details?.cache_read ?? 0
880+
);
875881
const stream = await model.stream(messages);
876882
let agg;
877883
for await (const chunk of stream) {

libs/providers/langchain-anthropic/src/utils/message_outputs.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export function _makeMessageChunkFromAnthropicEvent(
2323
} | null {
2424
const response_metadata = { model_provider: "anthropic" };
2525
if (data.type === "message_start") {
26-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2726
const { content, usage, ...additionalKwargs } = data.message;
2827
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2928
const filteredAdditionalKwargs: Record<string, any> = {};
@@ -35,10 +34,16 @@ export function _makeMessageChunkFromAnthropicEvent(
3534
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3635
const { input_tokens, output_tokens, ...rest }: Record<string, any> =
3736
usage ?? {};
37+
// Total input tokens in a Claude API request is the summation of `input_tokens`, `cache_creation_input_tokens`, and `cache_read_input_tokens`.
38+
// ref: https://platform.claude.com/docs/en/api/messages
39+
const totalInputTokens =
40+
input_tokens +
41+
rest.cache_creation_input_tokens +
42+
rest.cache_read_input_tokens;
3843
const usageMetadata: UsageMetadata = {
39-
input_tokens,
44+
input_tokens: totalInputTokens,
4045
output_tokens,
41-
total_tokens: input_tokens + output_tokens,
46+
total_tokens: totalInputTokens + output_tokens,
4247
input_token_details: {
4348
cache_creation: rest.cache_creation_input_tokens,
4449
cache_read: rest.cache_read_input_tokens,

0 commit comments

Comments
 (0)