Loading...
    • 开发者指南
    • API 参考
    • MCP
    • 资源
    • 更新日志
    Search...
    ⌘K
    入门
    Claude 简介快速开始
    模型与定价
    模型概览选择模型Claude 4.6 新特性迁移指南模型弃用定价
    使用 Claude 构建
    功能概览使用 Messages API处理停止原因提示词最佳实践
    上下文管理
    上下文窗口压缩上下文编辑
    能力
    提示缓存扩展思考自适应思考推理力度流式消息批量处理引用多语言支持Token 计数嵌入视觉PDF 支持Files API搜索结果结构化输出
    工具
    概览如何实现工具使用细粒度工具流式传输Bash 工具代码执行工具程序化工具调用计算机使用工具文本编辑器工具网页抓取工具网页搜索工具记忆工具工具搜索工具
    Agent Skills
    概览快速开始最佳实践企业级 Skills通过 API 使用 Skills
    Agent SDK
    概览快速开始TypeScript SDKTypeScript V2(预览版)Python SDK迁移指南
    流式输入实时流式响应处理停止原因处理权限用户审批与输入使用钩子控制执行会话管理文件检查点SDK 中的结构化输出托管 Agent SDK安全部署 AI 智能体修改系统提示词SDK 中的 MCP自定义工具SDK 中的子智能体SDK 中的斜杠命令SDK 中的 Agent Skills跟踪成本与用量待办事项列表SDK 中的插件
    API 中的 MCP
    MCP 连接器远程 MCP 服务器
    第三方平台上的 Claude
    Amazon BedrockMicrosoft FoundryVertex AI
    提示工程
    概览提示词生成器使用提示词模板提示词优化器清晰直接使用示例(多样本提示)让 Claude 思考(思维链)使用 XML 标签赋予 Claude 角色(系统提示词)链式复杂提示长上下文技巧扩展思考技巧
    测试与评估
    定义成功标准开发测试用例使用评估工具降低延迟
    加强安全护栏
    减少幻觉提高输出一致性防范越狱攻击流式拒绝减少提示词泄露保持 Claude 角色设定
    管理与监控
    Admin API 概览数据驻留工作空间用量与成本 APIClaude Code Analytics API零数据留存
    Console
    Log in
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...

    Solutions

    • AI agents
    • Code modernization
    • Coding
    • Customer support
    • Education
    • Financial services
    • Government
    • Life sciences

    Partners

    • Amazon Bedrock
    • Google Cloud's Vertex AI

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Company

    • Anthropic
    • Careers
    • Economic Futures
    • Research
    • News
    • Responsible Scaling Policy
    • Security and compliance
    • Transparency

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Help and security

    • Availability
    • Status
    • Support
    • Discord

    Terms and policies

    • Privacy policy
    • Responsible disclosure policy
    • Terms of service: Commercial
    • Terms of service: Consumer
    • Usage policy
    指南

    跟踪成本和用量

    了解和跟踪 Claude Agent SDK 中用于计费的 token 用量

    SDK 成本跟踪

    Claude Agent SDK 为每次与 Claude 的交互提供详细的 token 用量信息。本指南说明如何正确跟踪成本和理解用量报告,特别是在处理并行工具使用和多步骤对话时。

    有关完整的 API 文档,请参阅 TypeScript SDK 参考。

    理解 Token 用量

    当 Claude 处理请求时,它会在消息级别报告 token 用量。这些用量数据对于跟踪成本和适当地向用户计费至关重要。

    关键概念

    1. 步骤(Steps):步骤是应用程序与 Claude 之间的单个请求/响应对
    2. 消息(Messages):步骤中的单个消息(文本、工具使用、工具结果)
    3. 用量(Usage):附加到助手消息的 token 消耗数据

    用量报告结构

    单个与并行工具使用

    当 Claude 执行工具时,用量报告会根据工具是顺序执行还是并行执行而有所不同:

    import { query } from "@anthropic-ai/claude-agent-sdk";
    
    // 示例:在对话中跟踪用量
    const result = await query({
      prompt: "Analyze this codebase and run tests",
      options: {
        onMessage: (message) => {
          if (message.type === 'assistant' && message.usage) {
            console.log(`Message ID: ${message.id}`);
            console.log(`Usage:`, message.usage);
          }
        }
      }
    });

    消息流示例

    以下是在典型多步骤对话中消息和用量的报告方式:

    <!-- 步骤 1:包含并行工具使用的初始请求 -->
    assistant (text)      { id: "msg_1", usage: { output_tokens: 100, ... } }
    assistant (tool_use)  { id: "msg_1", usage: { output_tokens: 100, ... } }
    assistant (tool_use)  { id: "msg_1", usage: { output_tokens: 100, ... } }
    assistant (tool_use)  { id: "msg_1", usage: { output_tokens: 100, ... } }
    user (tool_result)
    user (tool_result)
    user (tool_result)
    
    <!-- 步骤 2:后续响应 -->
    assistant (text)      { id: "msg_2", usage: { output_tokens: 98, ... } }

    重要的用量规则

    1. 相同 ID = 相同用量

    所有具有相同 id 字段的消息报告相同的用量。当 Claude 在同一轮中发送多条消息(例如,文本 + 工具使用)时,它们共享相同的消息 ID 和用量数据。

    // 所有这些消息具有相同的 ID 和用量
    const messages = [
      { type: 'assistant', id: 'msg_123', usage: { output_tokens: 100 } },
      { type: 'assistant', id: 'msg_123', usage: { output_tokens: 100 } },
      { type: 'assistant', id: 'msg_123', usage: { output_tokens: 100 } }
    ];
    
    // 每个唯一消息 ID 只收费一次
    const uniqueUsage = messages[0].usage; // 具有此 ID 的所有消息相同

    2. 每步只收费一次

    您应该每步只向用户收费一次,而不是为每条单独的消息收费。当您看到多条具有相同 ID 的助手消息时,使用其中任何一条的用量即可。

    3. 结果消息包含累计用量

    最终的 result 消息包含对话中所有步骤的总累计用量:

    // 最终结果包含总用量
    const result = await query({
      prompt: "Multi-step task",
      options: { /* ... */ }
    });
    
    console.log("Total usage:", result.usage);
    console.log("Total cost:", result.usage.total_cost_usd);

    4. 按模型的用量明细

    结果消息还包含 modelUsage,它提供权威的按模型用量数据。与 total_cost_usd 一样,此字段是准确的,适合用于计费目的。当使用多个模型时(例如,Haiku 用于子代理,Opus 用于主代理),这尤其有用。

    // modelUsage 提供按模型的明细
    type ModelUsage = {
      inputTokens: number
      outputTokens: number
      cacheReadInputTokens: number
      cacheCreationInputTokens: number
      webSearchRequests: number
      costUSD: number
      contextWindow: number
    }
    
    // 从结果消息中访问
    const result = await query({ prompt: "..." });
    
    // result.modelUsage 是模型名称到 ModelUsage 的映射
    for (const [modelName, usage] of Object.entries(result.modelUsage)) {
      console.log(`${modelName}: $${usage.costUSD.toFixed(4)}`);
      console.log(`  Input tokens: ${usage.inputTokens}`);
      console.log(`  Output tokens: ${usage.outputTokens}`);
    }

    有关完整的类型定义,请参阅 TypeScript SDK 参考。

    实现:成本跟踪系统

    以下是实现成本跟踪系统的完整示例:

    import { query } from "@anthropic-ai/claude-agent-sdk";
    
    class CostTracker {
      private processedMessageIds = new Set<string>();
      private stepUsages: Array<any> = [];
      
      async trackConversation(prompt: string) {
        const result = await query({
          prompt,
          options: {
            onMessage: (message) => {
              this.processMessage(message);
            }
          }
        });
        
        return {
          result,
          stepUsages: this.stepUsages,
          totalCost: result.usage?.total_cost_usd || 0
        };
      }
      
      private processMessage(message: any) {
        // 仅处理带有用量的助手消息
        if (message.type !== 'assistant' || !message.usage) {
          return;
        }
        
        // 如果已处理此消息 ID 则跳过
        if (this.processedMessageIds.has(message.id)) {
          return;
        }
        
        // 标记为已处理并记录用量
        this.processedMessageIds.add(message.id);
        this.stepUsages.push({
          messageId: message.id,
          timestamp: new Date().toISOString(),
          usage: message.usage,
          costUSD: this.calculateCost(message.usage)
        });
      }
      
      private calculateCost(usage: any): number {
        // 在此实现您的定价计算
        // 这是一个简化示例
        const inputCost = usage.input_tokens * 0.00003;
        const outputCost = usage.output_tokens * 0.00015;
        const cacheReadCost = (usage.cache_read_input_tokens || 0) * 0.0000075;
        
        return inputCost + outputCost + cacheReadCost;
      }
    }
    
    // 使用方式
    const tracker = new CostTracker();
    const { result, stepUsages, totalCost } = await tracker.trackConversation(
      "Analyze and refactor this code"
    );
    
    console.log(`Steps processed: ${stepUsages.length}`);
    console.log(`Total cost: $${totalCost.toFixed(4)}`);

    处理边缘情况

    输出 Token 差异

    在极少数情况下,您可能会观察到具有相同 ID 的消息具有不同的 output_tokens 值。当这种情况发生时:

    1. 使用最高值 - 组中的最后一条消息通常包含准确的总数
    2. 与总成本核对 - 结果消息中的 total_cost_usd 是权威的
    3. 报告不一致 - 在 Claude Code GitHub 仓库 提交问题

    缓存 Token 跟踪

    使用提示缓存时,请分别跟踪这些 token 类型:

    interface CacheUsage {
      cache_creation_input_tokens: number;
      cache_read_input_tokens: number;
      cache_creation: {
        ephemeral_5m_input_tokens: number;
        ephemeral_1h_input_tokens: number;
      };
    }

    最佳实践

    1. 使用消息 ID 进行去重:始终跟踪已处理的消息 ID 以避免重复收费
    2. 监控结果消息:最终结果包含权威的累计用量
    3. 实施日志记录:记录所有用量数据以用于审计和调试
    4. 优雅地处理失败:即使对话失败也要跟踪部分用量
    5. 考虑流式传输:对于流式响应,在消息到达时累积用量

    用量字段参考

    每个用量对象包含:

    • input_tokens:处理的基础输入 token 数
    • output_tokens:响应中生成的 token 数
    • cache_creation_input_tokens:用于创建缓存条目的 token 数
    • cache_read_input_tokens:从缓存读取的 token 数
    • service_tier:使用的服务层级(例如,"standard")
    • total_cost_usd:以美元计的总成本(仅在结果消息中)

    示例:构建计费仪表板

    以下是如何为计费仪表板聚合用量数据:

    class BillingAggregator {
      private userUsage = new Map<string, {
        totalTokens: number;
        totalCost: number;
        conversations: number;
      }>();
      
      async processUserRequest(userId: string, prompt: string) {
        const tracker = new CostTracker();
        const { result, stepUsages, totalCost } = await tracker.trackConversation(prompt);
        
        // 更新用户总计
        const current = this.userUsage.get(userId) || {
          totalTokens: 0,
          totalCost: 0,
          conversations: 0
        };
        
        const totalTokens = stepUsages.reduce((sum, step) => 
          sum + step.usage.input_tokens + step.usage.output_tokens, 0
        );
        
        this.userUsage.set(userId, {
          totalTokens: current.totalTokens + totalTokens,
          totalCost: current.totalCost + totalCost,
          conversations: current.conversations + 1
        });
        
        return result;
      }
      
      getUserBilling(userId: string) {
        return this.userUsage.get(userId) || {
          totalTokens: 0,
          totalCost: 0,
          conversations: 0
        };
      }
    }

    相关文档

    • TypeScript SDK 参考 - 完整的 API 文档
    • SDK 概述 - SDK 入门指南
    • SDK 权限 - 管理工具权限

    Was this page helpful?

    • 理解 Token 用量
    • 1. 相同 ID = 相同用量
    • 2. 每步只收费一次
    • 3. 结果消息包含累计用量
    • 4. 按模型的用量明细
    • 输出 Token 差异
    • 缓存 Token 跟踪