Claude Code 成本优化与 Token 管理实战:让每一分钱都花在刀刃上

系列文章

本篇是 Claude Code 系列的第 10 篇(补充篇)。系列将从安装入门到高级实战,由浅入深地拆解这个终端原生 Coding Agent 的每一个能力。

🚀 入门篇

  1. Claude Code 是什么?从安装到第一次对话
  2. 日常开发工作流:用 Claude Code 重塑你的编码习惯

🔧 核心篇

  1. 内置命令全解:从 /compact 到 /doctor 的实战指南
  2. CLAUDE.md:项目上下文工程的艺术

⚡ 进阶篇

  1. 多文件重构与复杂任务实战
  2. Hooks、MCP 与能力扩展

🏗️ 高级篇

  1. Headless 模式与 CI/CD 集成
  2. 多 Agent 协作:从 Claude Code 到 Codex

🧭 全景总结

  1. Claude Code 系列全景总结:从入门到多 Agent 协作的知识地图

💰 成本优化(本文)


一、开篇:为什么需要聊”钱”?

在前九篇文章中,我们系统地学习了 Claude Code 的安装、日常使用、内置命令、上下文工程、多文件重构、能力扩展、CI/CD 集成和多 Agent 协作。但有一个话题我们一直没有正面触及——成本

这不是一个可有可无的话题。

Claude Code 的计费模型和你用过的任何 SaaS 工具都不一样。它不是按月付费无限使用的,也不是按请求次数计费的。它的核心计费单位是 Token——你输入的每一个字符、Claude 输出的每一个字、甚至项目中被扫描的代码文件,都在消耗 Token。

一个典型的 Java 开发者日常使用 Claude Code 的场景:

  • 上午:让 Claude Code 帮你重构一个 Service 层(消耗 ~50K tokens)
  • 下午:调试一个复杂的并发 Bug(消耗 ~80K tokens,因为需要多轮对话)
  • 晚上:用 Headless 模式跑批量代码审查(消耗 ~200K tokens)

一天下来,轻松消耗 300K+ tokens。按 Claude Sonnet 4 的定价(输入 $3/M tokens,输出 $15/M tokens),一天的花费可能在 $1-3 之间。一个月下来就是 $30-90。

这个数字本身不算高——一个 Java 高级开发者的日薪远不止这个数。但问题在于:你是否把每一分钱都花在了刀刃上?

很多开发者在使用 Claude Code 时存在严重的 Token 浪费:

  • 上下文窗口堆积了大量无关的历史对话,模型每次都要”重新阅读”
  • 没有利用 /compact 命令压缩上下文,导致同一个信息被重复计费
  • CLAUDE.md 写得过于冗长,每次对话都要加载
  • 不知道何时该开新会话 vs 继续旧会话

本文就是要解决这些问题。我们将从 Claude Code 的 Token 消耗机制讲起,逐步深入到上下文管理、命令优化、CLAUDE.md 瘦身等实战技巧,最后给出一套可量化的成本优化框架。


二、理解 Token:Claude Code 的”燃料”

2.1 什么是 Token?

在深入优化之前,我们必须先理解 Token 到底是什么。

Token 是大语言模型处理文本的基本单位。它不是字符,不是单词,而是介于两者之间的一个概念。对于英文,一个 token 大约是 4 个字符(约 0.75 个单词)。对于中文,一个汉字通常被编码为 1-2 个 token。

这意味着什么?同样表达一个意思,中文的 Token 消耗通常比英文高 30-50%。这不是 Claude Code 的问题,而是所有大语言模型的共性。

Java 开发者特别注意:代码中的缩进、空格、括号、注释都是 Token。一段格式良好的 Java 代码,Token 数通常是字符数的 1/3 到 1/4。

1
2
3
4
5
6
// 这行注释消耗约 15 个 tokens
public ResponseEntity<UserDTO> getUserById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}

2.2 Claude Code 的 Token 消耗模型

Claude Code 的 Token 消耗分为三个部分:

1. 输入 Token(Input Tokens)

这是消耗最大的部分。每次你发一条消息给 Claude Code,它收到的”输入”包括:

  • 系统提示词:Claude Code 的内置指令(固定消耗,约 2-3K tokens)
  • CLAUDE.md 内容:项目级、用户级、目录级的所有 CLAUDE.md 文件
  • 对话历史:本次会话中所有之前的对话记录
  • 你的消息:你刚输入的内容
  • 工具结果:Claude Code 读取文件、执行命令的返回结果

一个典型的单次输入结构:

1
2
3
4
5
6
7
系统提示词:           ~2,500 tokens (固定)
CLAUDE.md: ~500-2,000 tokens (取决于你写了多少)
对话历史: ~5,000-50,000 tokens (随对话增长)
当前消息: ~200-1,000 tokens
工具结果: ~1,000-10,000 tokens (取决于读了什么文件)
─────────────────────────────────────────
单次输入总计: ~9,200-65,500 tokens

2. 输出 Token(Output Tokens)

Claude Code 生成的回复,包括思考过程、代码修改、命令调用等。通常比输入少,但复杂任务的输出也可能很长。

3. 缓存读取 Token(Cache Read Tokens)

这是 Claude Code 的一个优化机制。系统提示词、CLAUDE.md 等不变的内容会被缓存,后续请求命中缓存时按更低的价格计费(通常是正常输入价格的 10%)。

这意味着:CLAUDE.md 虽然每次都会被”发送”,但如果内容不变,实际花费很低。 但对话历史不会被缓存——每一轮对话,历史都要重新发送。

2.3 查看当前消耗:/cost 命令

Claude Code 提供了 /cost 命令来查看当前会话的 Token 消耗:

1
2
3
4
5
6
7
claude> /cost
Session cost:
Input tokens: 45,230
Output tokens: 12,450
Cache read tokens: 38,100
Cache write tokens: 7,130
Total cost: $0.23

关键指标

  • Input tokens / Cache read tokens 的比例:如果 Cache read 占比高,说明你的 CLAUDE.md 和系统提示词被有效缓存了
  • Output tokens:如果输出远高于输入,说明 Claude 在做大量”思考”——可能是任务描述不够清晰
  • Total cost:实时花费,帮你判断这个任务值不值得继续

三、上下文窗口:成本的最大黑洞

3.1 上下文窗口的工作原理

Claude Code 使用的是 200K token 的上下文窗口。这意味着在一次会话中,模型能”记住”大约 200K tokens 的内容。听起来很多?让我们算一笔账。

一个典型的 Java Spring Boot 项目的文件结构:

1
2
3
4
5
6
7
8
9
src/main/java/com/example/
├── controller/ (5 个文件,每个 ~200 行) ~4,000 tokens
├── service/ (8 个文件,每个 ~300 行) ~9,600 tokens
├── repository/ (6 个文件,每个 ~100 行) ~2,400 tokens
├── model/ (10 个文件,每个 ~150 行) ~6,000 tokens
├── config/ (4 个文件,每个 ~200 行) ~3,200 tokens
└── pom.xml ~800 tokens
───────────────────────────────────────────────────
项目代码总计: ~26,000 tokens

一个 200K 的上下文窗口,理论上可以装下 7-8 个这样的项目。但实际上,你不会把整个项目都塞进去。问题在于:随着对话进行,上下文会被历史消息逐渐填满

3.2 上下文膨胀的三个阶段

阶段一:轻量期(0-20K tokens)

刚开始对话时,上下文很干净。CLAUDE.md + 系统提示词 + 你的第一条消息,总共约 5-8K tokens。这个阶段的响应速度最快,成本最低。

阶段二:膨胀期(20K-100K tokens)

经过 5-10 轮对话后,上下文开始膨胀。每一轮对话都会把之前的所有历史带上。如果你让 Claude Code 读了几个大文件,上下文可能迅速飙升到 50-80K tokens。

这个阶段的典型症状:

  • 响应速度明显变慢
  • Claude 开始”忘记”早期对话的细节
  • Token 消耗开始加速

阶段三:临界期(100K+ tokens)

当上下文接近 100K tokens 时,问题变得严重:

  • 每次请求的成本是轻量期的 10-20 倍
  • 模型的注意力被稀释,输出质量下降
  • 出现”幻觉”的概率增加(模型开始混淆不同文件的内容)

3.3 /compact:上下文压缩的核心武器

/compact 命令是 Claude Code 内置的上下文压缩工具。它的工作原理是:

  1. 把当前对话历史总结为一段精简的摘要
  2. 用这段摘要替换完整的对话历史
  3. 上下文窗口从 80K+ tokens 压缩到 10-20K tokens

使用方法:

1
2
3
4
5
6
7
8
# 基本压缩
claude> /compact

# 带自定义指令的压缩(告诉 Claude 保留什么信息)
claude> /compact 保留关于 UserService 重构的所有细节

# 压缩后继续工作
claude> 继续修改 UserRepository 的查询方法

关键技巧/compact 的自定义指令非常重要。默认压缩可能会丢失你需要的上下文。比如:

1
2
3
4
5
6
7
8
# ✗ 太笼统,可能丢失关键信息
claude> /compact

# ✓ 精确指定保留内容
claude> /compact 保留当前重构计划、已修改的文件列表、以及待修复的编译错误

# ✓ 对于调试场景
claude> /compact 保留错误堆栈、已排查的假设、和下一步调试计划

3.4 何时该 /compact vs 开新会话?

这是一个常见的决策点。经验法则:

/compact 的场景

  • 任务还在进行中,需要保留上下文
  • 上下文已经膨胀到 50K+ tokens
  • 你要切换到同一个大任务的子任务
  • 对话质量开始下降但任务尚未完成

开新会话的场景

  • 当前任务已完成,要开始新任务
  • 上下文已经超过 100K tokens 且 /compact 后仍然很大
  • 你要切换到一个完全不同的项目或模块
  • 对话已经进行 15+ 轮,模型开始出现”健忘”症状
1
2
3
4
5
# 开新会话的方式
claude> /exit
$ claude

# 或者用 Ctrl+C 退出后重新启动

四、CLAUDE.md 的成本影响

4.1 CLAUDE.md 的隐藏成本

在第 4 篇文章中,我们详细讨论了 CLAUDE.md 的编写技巧。但有一个维度我们没有覆盖:成本

CLAUDE.md 的内容会在每次请求时被发送给模型。这意味着:

  • 一个 1000 tokens 的 CLAUDE.md,在一次 10 轮对话中,会被发送 10 次
  • 如果没有缓存命中,总共消耗 10,000 tokens(输入价格)
  • 如果缓存命中,实际消耗约 1,000 tokens(缓存价格)

但缓存有一个前提:CLAUDE.md 的内容必须完全不变。如果你在对话过程中修改了 CLAUDE.md,缓存会失效,所有内容重新计费。

4.2 瘦身 CLAUDE.md 的实战技巧

技巧一:删除冗余信息

很多开发者的 CLAUDE.md 里充满了”显而易见”的信息:

1
2
3
4
5
6
7
8
9
10
11
12
# ✗ 冗余的 CLAUDE.md
## 项目概述
这是一个使用 Spring Boot 框架开发的 Java Web 应用程序。
项目使用 Maven 作为构建工具,使用 Git 进行版本控制。
项目运行在 Java 17 环境上。

## 技术栈
- Spring Boot 3.2
- Spring Data JPA
- PostgreSQL
- Redis
- Docker

Claude Code 从 pom.xml 和项目结构就能推断出大部分信息。精简版:

1
2
3
4
5
6
# ✓ 精简的 CLAUDE.md
## 关键约定
- Java 17 + Spring Boot 3.2,Maven 构建
- 数据库:PostgreSQL(主),Redis(缓存)
- 测试用 H2,不用真实数据库
- API 路径统一用 /api/v1/ 前缀

Token 消耗从 ~200 降到 ~50,减少了 75%。

技巧二:用引用代替内联

不要在 CLAUDE.md 中贴大段代码示例。用文件引用代替:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# ✗ 内联代码(消耗 ~500 tokens)
## API 规范
\```java
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<UserDTO> getUser(@PathVariable Long id) { ... }
}
\```

# ✓ 文件引用(消耗 ~20 tokens)
## API 规范
参考 src/main/java/com/example/controller/UserController.java 的风格

技巧三:分层 CLAUDE.md

利用 Claude Code 的分层加载机制:

1
2
3
项目根目录/CLAUDE.md          → 全局约定(始终加载)
src/main/java/CLAUDE.md → Java 代码约定(只在操作 Java 文件时加载)
src/test/java/CLAUDE.md → 测试约定(只在操作测试文件时加载)

这样,当你在修改 src/test/ 下的测试文件时,src/main/java/CLAUDE.md 不会被加载,节省了 Token。

4.3 测量 CLAUDE.md 的实际成本

想知道你的 CLAUDE.md 到底消耗多少 Token?用这个方法:

1
2
3
4
5
6
# 1. 查看 CLAUDE.md 的内容
cat CLAUDE.md | wc -c

# 2. 粗略估算 Token 数(中文约 1.5 token/字符,英文约 0.25 token/字符)
# 更精确的方法:用 Claude Code 自带的 token 计数
claude> 请告诉我当前加载的 CLAUDE.md 总共消耗了多少 tokens

五、模型选择的成本策略

5.1 不同模型的价格差异

Claude Code 支持多种模型,价格差异显著:

模型 输入价格 (/M tokens) 输出价格 (/M tokens) 缓存读取 (/M tokens) 适用场景
Claude Sonnet 4 $3 $15 $0.30 日常开发主力
Claude Opus 4 $15 $75 $1.50 复杂推理、架构设计
Claude Haiku 3.5 $0.80 $4 $0.08 简单任务、批量处理

关键洞察:Sonnet 4 是大多数开发场景的最佳性价比选择。Opus 4 只在真正需要深度推理时才值得用。

5.2 按任务选择模型的决策框架

1
2
3
4
5
6
7
8
9
10
11
# 日常编码(80% 的时间)→ Sonnet 4
claude --model claude-sonnet-4-20250514
claude> 帮我给 UserService 添加一个批量查询方法

# 复杂架构决策(15% 的时间)→ Opus 4
claude --model claude-opus-4-20250514
claude> 分析当前项目的微服务拆分方案,给出详细的迁移路径

# 简单批量任务(5% 的时间)→ Haiku 3.5
claude --model claude-haiku-3-5-20241022
claude> 给 src/main/java 下所有 Controller 添加 @Tag 注解

5.3 动态切换模型

在同一个会话中,你可以随时切换模型:

1
2
3
4
5
6
7
8
9
10
11
# 先用 Sonnet 做日常开发
claude> /model claude-sonnet-4-20250514
claude> 帮我重构 OrderService

# 遇到复杂问题,切换到 Opus
claude> /model claude-opus-4-20250514
claude> 这个并发死锁问题的根因是什么?请深入分析

# 切回 Sonnet 继续日常开发
claude> /model claude-sonnet-4-20250514
claude> 按照分析结果修改代码

六、实战:一天的成本优化案例

让我们通过一个真实的 Java 开发场景,看看优化前后的成本差异。

6.1 场景:Spring Boot 应用的用户认证模块重构

任务描述:将基于 Session 的认证迁移到 JWT + Spring Security 的方案。涉及 15 个文件的修改。

优化前的工作方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 启动 Claude Code,直接开始
claude

# 第 1 轮:描述需求
claude> 把当前项目的 Session 认证改成 JWT

# Claude 读取了 10 个文件,输出了一个方案
# 消耗:~25K tokens

# 第 2-5 轮:逐个修改文件
claude> 修改 SecurityConfig
claude> 修改 UserController
claude> 修改 UserService
claude> 添加 JwtUtil

# 每轮都带着前面的全部历史
# 消耗:每轮 ~30-50K tokens

# 第 6-8 轮:调试编译错误
claude> 编译报错了,错误信息是...
claude> 还有这个错误...
claude> 测试跑不过...

# 上下文已经膨胀到 120K tokens
# 消耗:每轮 ~80-100K tokens

# 第 9 轮:重新看代码
claude> 帮我再看一下 SecurityConfig 的完整代码

# Claude 重新读取文件(因为之前的上下文已经被"稀释"了)
# 消耗:~50K tokens

优化前总消耗:约 450K input tokens + 80K output tokens
优化前成本:约 $1.35 + $1.20 = $2.55

6.2 优化后的工作方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 1. 先用 /model 选择合适的模型
claude --model claude-sonnet-4-20250514

# 2. 先描述完整需求,让 Claude 制定计划
claude> 把 Session 认证改成 JWT + Spring Security。
需要修改的文件:SecurityConfig, UserController, UserService,
UserRepository, 新增 JwtUtil, JwtFilter。
先给我一个修改计划,不要直接改代码。

# Claude 输出计划(只读取了关键文件)
# 消耗:~15K tokens

# 3. 批量执行(而不是逐个文件)
claude> 按照计划执行,一次改完所有文件

# Claude 一次性修改所有 15 个文件
# 消耗:~40K tokens

# 4. 在上下文膨胀前压缩
claude> /compact 保留修改计划和已修改的文件清单

# 上下文从 55K 压缩到 10K
# 消耗:~10K tokens(压缩本身)

# 5. 继续调试
claude> 编译一下看看有没有错误

# 清爽的上下文,响应速度快
# 消耗:~15K tokens

# 6. 修复错误
claude> 修复这些编译错误

# 消耗:~25K tokens

# 7. 运行测试
claude> 运行 mvn test

# 消耗:~10K tokens

优化后总消耗:约 115K input tokens + 40K output tokens
优化后成本:约 $0.35 + $0.60 = $0.95

节省:62%,约 $1.60

6.3 优化要点总结

优化手段 节省比例 难度
先规划再执行(避免返工) 20-30%
及时 /compact 15-25%
批量操作代替逐个修改 10-20%
选择合适的模型 50-80%
精简 CLAUDE.md 5-10%

七、高级优化:Prompt Caching 与 Context Window 管理

7.1 理解 Prompt Caching 的运作机制

Claude Code 的 Prompt Caching 是一个自动化的优化机制,不需要你手动配置。但理解它的运作方式可以帮助你更好地利用它。

缓存命中的条件:

  • 系统提示词(每次都会缓存)
  • CLAUDE.md 内容(内容不变时缓存命中)
  • 会话中早期的消息(如果它们没有变化)

缓存不会命中的情况:

  • CLAUDE.md 被修改(哪怕只改了一个字)
  • 会话中途切换模型
  • 使用 /compact 后(压缩后的内容是新的,需要重新缓存)

实战建议

1
2
3
4
5
# ✓ 好的做法:在会话开始前就确定好 CLAUDE.md
# 这样整个会话都能命中缓存

# ✗ 不好的做法:在对话过程中反复修改 CLAUDE.md
# 每次修改都会导致缓存失效

7.2 Context Window 的主动管理

除了 /compact,还有几种方式可以管理上下文:

方式一:/clear 清除全部历史

1
2
# 完全清除对话历史,从零开始
claude> /clear

这比 /exit + 重新启动更快,因为它保留了会话状态(CLAUDE.md、权限设置等),只清除了对话历史。

方式二:/compact 带精确指令

1
2
3
# 只保留与当前任务相关的上下文
claude> /compact 只保留 UserService 和 SecurityConfig 的修改记录,
删除所有已解决的错误信息

方式三:利用 --resume 恢复会话

1
2
3
4
5
# 恢复之前的会话(避免重复描述背景)
claude --resume

# 恢复特定会话
claude --resume <session-id>

这比从头开始一个新会话更省 Token,因为它复用了之前的上下文。


八、Headless 模式下的成本控制

8.1 Headless 模式的特殊成本考量

在第 7 篇文章中,我们介绍了 Headless 模式用于 CI/CD 集成。Headless 模式的成本控制有其特殊性:

特点一:批量任务的 Token 消耗可以很高

1
2
3
4
# 批量审查 50 个文件
for file in src/main/java/**/*.java; do
claude -p "审查这个文件的代码质量" < "$file"
done

每个文件都是一个独立的会话,没有缓存共享。50 个文件 × 5K tokens/文件 = 250K tokens 的输入。

特点二:可以利用 --model 选择更便宜的模型

1
2
3
4
# 批量任务用 Haiku 就够了
for file in src/main/java/**/*.java; do
claude -p "给这个文件添加 JavaDoc 注释" --model claude-haiku-3-5-20241022 < "$file"
done

特点三:--max-turns 限制轮数

1
2
# 限制每轮对话最多 3 个工具调用
claude -p "修复这个编译错误" --max-turns 3 < error.log

这可以防止 Claude Code 在自动模式下”跑偏”,消耗过多 Token。

8.2 Headless 模式的成本估算公式

1
2
3
4
5
6
7
8
# 粗略估算公式
# 总成本 ≈ (文件数 × 平均文件大小 × 1.5) × 输入价格 + 输出预估

# 示例:审查 20 个 Java 文件,平均 300 行
# 输入:20 × 300 × 4 tokens/行 × 1.5 = 36,000 tokens
# 输出:约 10,000 tokens(每个文件约 500 tokens 的审查意见)
# Sonnet 4 成本:36000 × $3/M + 10000 × $15/M = $0.11 + $0.15 = $0.26
# Haiku 成本:36000 × $0.80/M + 10000 × $4/M = $0.03 + $0.04 = $0.07

九、团队级成本管理

9.1 API Key 管理

对于团队使用,API Key 的管理至关重要:

1
2
3
4
5
6
7
8
# 使用环境变量(推荐)
export ANTHROPIC_API_KEY=sk-ant-xxx

# 使用 .env 文件(注意不要提交到 Git)
echo "ANTHROPIC_API_KEY=sk-ant-xxx" >> .env

# 使用密钥管理服务(企业级)
# AWS Secrets Manager, HashiCorp Vault, etc.

安全提醒:永远不要把 API Key 提交到 Git 仓库。在 .gitignore 中添加:

1
2
.env
.claude/

9.2 使用统计与预算控制

Anthropic 提供了 API 使用统计面板。结合 Claude Code 的日志,你可以:

1
2
3
4
5
# 查看会话日志
ls ~/.claude/projects/

# 每个会话都有详细的成本记录
cat ~/.claude/projects/<project>/sessions/<session-id>/cost.json

对于团队预算控制,建议:

  • 为每个开发者设置独立的 API Key
  • 在 Anthropic Console 中设置月度预算上限
  • 定期审查使用报告,识别异常消耗

9.3 API vs Max 计划的选择

Claude Code 有两种使用方式:

维度 API 计费 Claude Max 订阅
计费方式 按 Token 实时计费 固定月费($100 或 $200)
适合场景 间歇性使用、自动化任务 日常重度使用
成本可控性 完全可控,用多少付多少 固定成本,不怕超支
模型选择 所有模型 取决于订阅级别

决策建议

  • 如果你每天使用 Claude Code 超过 2 小时 → Max 计划更划算
  • 如果你主要用 Headless 模式做自动化 → API 计费更灵活
  • 如果你是团队管理 → API 计费 + 预算控制更可控

十、总结:成本优化的核心原则

回顾全文,Claude Code 的成本优化可以归纳为三个核心原则:

原则一:管理上下文,而非囤积上下文

上下文窗口不是越大越好。及时使用 /compact 压缩,保持上下文精简,既能降低成本,又能提高输出质量。记住:一个 20K tokens 的精炼上下文,比一个 100K tokens 的臃肿上下文更有价值。

原则二:选择对的模型,而非最强的模型

80% 的日常开发任务,Sonnet 4 就足够了。不要因为”可能需要更好的推理”就默认使用 Opus 4。当你真正需要深度推理时再切换,用完切回来。

原则三:投资 CLAUDE.md,而非堆砌 CLAUDE.md

一个好的 CLAUDE.md 不在于字数多,而在于信息密度高。用最少的 Token 传达最关键的项目约定,让 Claude Code 每次都能”秒懂”你的项目上下文。

这三个原则的本质是同一个:让每一颗 Token 都承载有效的信息。当你的 Token 利用率提高了,成本自然就降下来了。


参考资料