第 48 章

Claude Code + CI/CD:PR 自动审查 / Issue 处理 / GitHub Actions 完整配置

第四十八章:Fast Mode 与成本控制:高频任务的效率与费用平衡

48.1 Claude Code 的成本结构

在使用 Claude Code 进行日常开发之前,理解它的成本结构至关重要。Claude Code 的每次对话都会消耗 Anthropic API tokens,费用取决于:

粗略参考(2024年价格,仅供量级参考):

Claude Opus 4.5:    输入 $15/M tokens,输出 $75/M tokens
Claude Sonnet 4.5:  输入 $3/M tokens,输出 $15/M tokens
Claude Haiku 3.5:   输入 $0.8/M tokens,输出 $4/M tokens

对于一个典型的编程任务会话(约 50K tokens),费用大约在:

这些数字看起来很小,但每天多次会话、全团队使用时,累积费用可以相当可观。理解成本控制策略,可以在不牺牲效率的情况下大幅降低支出。

48.2 什么是 Fast Mode

Claude Code 的 Fast Mode 是一种在某些场景下自动或手动使用更快、更便宜模型的机制。

在正常模式下,Claude Code 使用你配置的主模型(通常是 Claude Sonnet 或 Opus)处理所有任务。Fast Mode 允许 Claude 在以下情况下切换到更轻量的模型(如 Claude Haiku):

对于这些任务,用 Opus 级别的模型完全是资源浪费。Fast Mode 让 Claude Code 根据任务复杂度自适应选择模型,在保证质量的同时大幅降低成本。

启用 Fast Mode

.claude/settings.json 中配置:

{
  "model": "claude-sonnet-4-5",
  "fastMode": {
    "enabled": true,
    "model": "claude-haiku-3-5",
    "triggers": [
      "simple-query",
      "file-check",
      "format-only"
    ]
  }
}

或者在 CLAUDE.md 中说明使用策略:

## 模型使用策略

对于以下任务,可以使用 Fast Mode(Haiku 模型):
- 确认文件是否存在
- 读取配置值
- 简单的格式调整
- 单行代码修改

对于以下任务,必须使用完整模型(Sonnet 或 Opus):
- 架构设计和重构
- 复杂的 bug 分析
- 多文件协调修改
- 安全相关的代码审查

48.3 上下文窗口的成本影响

Claude Code 的一个容易被忽视的成本来源是上下文窗口的累积。随着对话越来越长,每次新的请求都需要发送整个对话历史,导致输入 tokens 持续增长。

对话长度与成本的关系

第 1 轮请求:
  输入 = CLAUDE.md (2K) + 用户消息 (0.5K) = 2.5K tokens

第 10 轮请求:
  输入 = CLAUDE.md (2K) + 9轮对话历史 (约 20K) + 用户消息 (0.5K) = 22.5K tokens

第 20 轮请求:
  输入 = CLAUDE.md (2K) + 19轮对话历史 (约 45K) + 用户消息 (0.5K) = 47.5K tokens

一个持续 20 轮的会话,最后几轮的单次费用可能是开始时的 10-20 倍。

使用 /compact 压缩对话历史

/compact 是 Claude Code 的内置命令,用于压缩当前会话的对话历史,大幅减少上下文 token 数:

/compact

执行后,Claude 会将对话历史压缩为一个简洁的摘要,释放大量上下文空间。压缩后,后续请求的输入 tokens 会显著减少。

建议的使用时机:

使用 /clear 彻底清空上下文

当需要开始全新任务时,/clear 命令会清空整个对话历史:

/clear

这比 /compact 更彻底,适合任务之间的完全切换。代价是 Claude 会失去所有对话历史,但 CLAUDE.md 提供的项目上下文依然存在。

48.4 CLAUDE.md 的 Token 成本

CLAUDE.md 在每次请求中都被加载,它的大小直接影响每次请求的基础成本。

以不同大小的 CLAUDE.md 为例,假设每天进行 50 次 Claude 请求,使用 Sonnet 模型:

CLAUDE.md 大小 | 每次额外成本    | 每天额外成本   | 每月额外成本
100 行 (~3K)   | ~$0.009        | ~$0.45        | ~$13.5
500 行 (~15K)  | ~$0.045        | ~$2.25        | ~$67.5
1000 行 (~30K) | ~$0.090        | ~$4.50        | ~$135

这并不意味着 CLAUDE.md 应该尽量短——一个写得好的 CLAUDE.md 能节省大量反复沟通的成本,总体来说仍然是划算的。但它提示你:

  1. 删除不再相关的内容(例如已完成的迁移计划)
  2. 避免重复说明(同一规范不要在多处重复)
  3. 使用 @import 按需加载,不要把所有内容都放在主文件

48.5 读取文件的成本

每次 Read 工具调用都会将文件内容加载到上下文中,大文件会显著增加成本。

策略一:避免读取不必要的文件

在 CLAUDE.md 中告诉 Claude 哪些文件不需要读取:

## 文件读取原则

- 不要读取 node_modules/ 下的文件
- 不要读取 .git/ 下的文件
- 不要读取 dist/ 或 build/ 下的编译产物
- 不要读取超过 1000 行的日志文件

策略二:使用 Grep 替代读取完整文件

在很多情况下,你只需要文件的某一部分。Grep 工具比 Read 更高效:

# 低效方式:读取整个文件来找一个函数
读取 src/services/user.ts(可能有 500 行)

# 高效方式:使用 Grep 定位
在 src/services/ 中搜索 "function getUserById"

Grep 只返回匹配的行及少量上下文,消耗的 tokens 远少于读取完整文件。

策略三:指定读取范围

当必须读取文件时,使用 Read 工具的 offsetlimit 参数:

请读取 src/api/users.ts 的第 50-100 行

这比读取整个文件节省大量 tokens。

48.6 选择正确的模型

不同任务对模型能力的要求差异很大。根据任务类型选择合适的模型是最直接的成本控制手段:

任务-模型匹配矩阵

任务类型                    推荐模型        理由
────────────────────────────────────────────────────────
复杂架构设计                Opus            需要最强推理能力
多文件重构(>10个文件)     Opus/Sonnet     需要长距离上下文理解
安全审查                    Opus            错误代价高
复杂 bug 分析              Sonnet          平衡能力与成本
单文件功能实现              Sonnet          日常工作主力
代码格式化                  Haiku           简单任务
添加注释                    Haiku           简单任务
简单问答                    Haiku           简单任务
文件存在性检查              Haiku           极简任务

在 Claude Code 中切换模型:

# 命令行启动时指定模型
claude --model claude-haiku-3-5

# 或在 .claude/settings.json 中设置默认模型
{
  "model": "claude-sonnet-4-5"
}

48.7 批量任务的成本优化

对于批量处理任务(如批量代码审查、批量添加注释),有几种优化策略:

策略一:批量合并请求

不要为每个文件发起独立会话,而是在一次会话中批量处理:

# 低效:100个文件 = 100次独立会话 = 100次 CLAUDE.md 加载成本

# 高效:100个文件 = 1次会话,每个文件一轮对话
# CLAUDE.md 只加载一次,后续轮次共享上下文

使用 SDK 实现批量处理时,复用同一个 ClaudeCode 实例:

const claude = new ClaudeCode({ cwd: projectDir });

for (const file of filesToProcess) {
  // 在同一实例(同一会话上下文)中处理所有文件
  await claude.query(`处理文件:${file}`);
}

策略二:并行但隔离的会话

对于相互独立的任务,使用多个并行会话(但每个会话尽量精简上下文):

// 5个并行会话,每个只处理20个文件
const batchSize = 20;
const batches = chunk(filesToProcess, batchSize);

await Promise.all(batches.map(async (batch) => {
  const claude = new ClaudeCode({ cwd: projectDir });
  for (const file of batch) {
    await claude.query(`处理文件:${file}`);
  }
}));

48.8 监控与预算管理

跟踪 Token 使用量

在使用 SDK 时,始终记录 token 使用量:

interface UsageRecord {
  timestamp: string;
  task: string;
  model: string;
  inputTokens: number;
  outputTokens: number;
  cost: number;
}

function calculateCost(model: string, input: number, output: number): number {
  const prices: Record<string, { input: number; output: number }> = {
    'claude-opus-4-5': { input: 15, output: 75 },
    'claude-sonnet-4-5': { input: 3, output: 15 },
    'claude-haiku-3-5': { input: 0.8, output: 4 },
  };

  const price = prices[model] || prices['claude-sonnet-4-5'];
  return (input * price.input + output * price.output) / 1_000_000;
}

// 每次调用后记录
const result = await claude.query(prompt);
const record: UsageRecord = {
  timestamp: new Date().toISOString(),
  task: 'code-review',
  model: 'claude-sonnet-4-5',
  inputTokens: result.usage.inputTokens,
  outputTokens: result.usage.outputTokens,
  cost: calculateCost('claude-sonnet-4-5', result.usage.inputTokens, result.usage.outputTokens),
};

设置预算限制

在自动化流程中,添加预算检查防止意外高消费:

const MAX_DAILY_COST_USD = 10;
let dailyCost = 0;

async function queryWithBudget(prompt: string): Promise<string> {
  if (dailyCost >= MAX_DAILY_COST_USD) {
    throw new Error(`每日预算 $${MAX_DAILY_COST_USD} 已用完,停止执行`);
  }

  const result = await claude.query(prompt);
  const cost = calculateCost('claude-sonnet-4-5', result.usage.inputTokens, result.usage.outputTokens);
  dailyCost += cost;

  console.log(`本次花费: $${cost.toFixed(4)},今日累计: $${dailyCost.toFixed(4)}`);

  return result.response;
}

48.9 成本控制最佳实践总结

以下是一个综合的成本控制清单:

CLAUDE.md 优化:

对话管理:

文件读取:

模型选择:

监控:


小结

成本控制是 Claude Code 工程化使用的重要组成部分。通过合理的模型选择、上下文管理和批量优化,可以在不降低开发效率的情况下将 API 费用控制在合理范围内。

关键要点:

本章评分
4.6  / 5  (3 评分)

💬 留言讨论