一、Token 计费机制
API 按 token 数量计费,分为输入和输出两部分。核心问题:每轮请求都会将完整对话历史作为输入重新发送,导致成本随对话轮次非线性增长。
第 1 轮 输入 = system prompt + msg_1 → ~3K tokens 第 2 轮 输入 = system prompt + msg_1 + resp_1 + msg_2 → ~8K tokens 第 3 轮 输入 = system prompt + msg_1..3 + resp_1..2 → ~15K tokens 第 N 轮 输入 = 全部累积 → 持续增长
一个 20 轮对话,后几轮的单次请求成本可能是第一轮的 10 倍以上。理解这一点,是后续所有优化策略的出发点。
二、上下文膨胀的常见原因
| 原因 | 说明 | 影响 |
|---|---|---|
| 读取大文件 | 文件内容全量进入上下文,2000 行文件约 8K+ tokens | 高 |
| 冗余工具调用 | 搜索结果、命令输出等全部保留在对话历史中 | 高 |
| 长对话累积 | 每轮都把完整历史重复发送一次 | 高 |
| 系统提示过长 | 每次请求都携带,属于固定开销 | 中 |
| 输出冗长 | 模型回复也计入后续输入,冗余回复相当于双倍计费 | 中 |
三、通用优化策略
3.1 控制对话长度
任务完成后及时新开会话。把一个超长对话拆成多个聚焦的短对话,能显著减少累计 token 开销——因为每一轮重复发送的"历史"会变得短很多。
3.2 精准读取文件
避免全量读取,让模型只取需要的行范围。Claude Code 的 Read 工具支持 offset 和 limit 参数(下方为工具调用的内部表示,实际用自然语言告知模型即可):
# 读取整个 2000 行文件 → ~8000 tokens Read(file_path="file.ts") # 只读第 100-150 行 → ~200 tokens(节省 97%) Read(file_path="file.ts", offset=100, limit=50)
3.3 减少冗余工具调用
每次工具调用的返回值都会进入上下文。常见的浪费来自"广撒网"式搜索——比如先 grep "user"、再 grep "User"、再 grep "userService",三次累积的结果可能轻松占掉 5K+ tokens。
建议:动手前先想清楚要找什么,用一次精准查询代替多次试探;查找完成后,必要时用 /compact 把无关的中间结果压缩掉。
3.4 按任务选模型
Anthropic 提供 Opus、Sonnet、Haiku 三档模型,能力与价格各有侧重:
| 任务类型 | 推荐模型 | 说明 |
|---|---|---|
| 复杂架构设计、深度推理、智能体编排 | Claude Opus | Anthropic 当前最强模型,适合需要长链路思考、多步骤规划的任务 |
| 日常编码、代码审查、写作 | Claude Sonnet | 能力与价格平衡,覆盖大部分开发场景,是 Claude Code 的默认选择 |
| 分类、格式转换、轻量提取 | Claude Haiku | 三档中价格最低、响应最快,适合 API 批量调用与轻量任务(Claude Code 场景下用得较少) |
按 Anthropic 官方公布的 token 单价计算,Sonnet 替代 Opus 处理日常任务,理论成本可降低约 80%(输入 $3/M vs $15/M,输出 $15/M vs $75/M)。具体倍率以你所选 VibeAPI 渠道为准。
3.5 精简系统提示
系统提示是每次请求的固定开销。删除不必要的示例和冗余说明,把使用频率低的指令移到用户消息中按需发送,能直接让每一轮都"瘦一圈"。
四、利用 Prompt Caching
这是 Anthropic 官方提供的成本优化机制,对长对话和大上下文场景尤其有效。
什么是 Prompt Caching:当请求中包含大块重复内容(系统提示、对话历史、引用文档)时,Anthropic 服务端会把这部分缓存下来。下次请求只要前缀完全一致,就能命中缓存。按官方公布的价格关系:
- 缓存写入:约为普通输入价格的 1.25 倍(首次写入时收取)
- 缓存读取:约为普通输入价格的 0.1 倍(命中时收取,仅 1/10)
- 默认 TTL:5 分钟(每次命中会刷新;Anthropic 也提供 1 小时 TTL 选项)
对长对话场景来说,缓存命中率随轮次增加而升高。即便选了倍率较高的渠道,长期单轮有效成本会持续下降——这是高倍率渠道在长对话下"看起来贵、实际不贵"的根本原因。
实操层面要注意什么
- 渠道是否支持缓存 — VibeAPI 的官方满血版、AWS 企业版都支持缓存,标准版不返回缓存字段。长对话场景优先用前两者,详见渠道选择指南。
- 保持稳定的前缀 — 缓存命中要求请求前缀按 token 完全一致。频繁修改系统提示或 CLAUDE.md 都会让缓存失效。
- 注意 TTL 窗口 — 默认缓存 5 分钟内不重新使用就会过期。连续对话能持续命中;中间断开太久就需要重新写入。
- Claude Code 已经默认启用缓存 — 不需要你手动配置,只要选了支持缓存的渠道,就会自动生效。
五、Claude Code 专属优化
5.1 精简 CLAUDE.md 降低固定开销
CLAUDE.md 的内容在每次请求中都作为系统提示发送。文件越长,每轮对话的固定 token 开销越大。
优化前(冗余写法):
# 项目说明
这是一个使用 React 和 TypeScript 构建的前端项目。
我们使用 Vite 作为构建工具,使用 pnpm 作为包管理器。
项目采用了 ESLint 和 Prettier 进行代码规范检查。
测试框架使用的是 Vitest,配合 Testing Library 进行组件测试。
请在编写代码时遵循项目现有的代码风格和规范。
部署使用 Vercel,CI 使用 GitHub Actions。
// ~120 tokens
优化后(紧凑写法):
Tech: React + TS, Vite, pnpm
Lint: ESLint + Prettier
Test: Vitest + Testing Library
Deploy: Vercel, CI: GitHub Actions
// ~30 tokens — 节省 75%
CLAUDE.md 写法原则:只写模型无法从代码中推断的信息。项目结构、依赖关系等可以通过读取 package.json 和目录结构获得,不需要重复写入。
分层管理:利用 CLAUDE.md 的层级机制,把模块特定的规则放到对应子目录中。
project-root/ ├── CLAUDE.md # 全局规则(所有对话都加载,尽量精简) ├── src/ │ └── CLAUDE.md # 前端规则(仅在 src/ 下工作时加载) └── server/ └── CLAUDE.md # 后端规则(仅在 server/ 下工作时加载)
全局 CLAUDE.md 控制在 20 行以内,特定模块的细节下沉到子目录。这是降低每轮固定开销最直接的办法。
5.2 按任务切换模型
Claude Code 支持在会话中随时切换模型,不需要退出重开。Anthropic 官方文档列出的方式:
# 方法一:对话中输入 /model 进入交互式选择 /model # 弹出菜单:Default / Opus / Sonnet / Haiku # 方法二:启动 Claude Code 时通过 --model 指定 claude --model sonnet # 直接以 Sonnet 启动 claude --model opus # 以 Opus 启动 # 方法三:在 ~/.claude/settings.json 中配置默认模型 { "model": "claude-sonnet-4-6" }
实操建议:
- 默认设为 Sonnet,覆盖大部分日常编码场景
- 遇到复杂架构设计或多文件重构时,临时切到 Opus
- 处理完复杂任务记得切回 Sonnet,避免后续轻量任务也跑 Opus
5.3 对话管理与上下文控制
Claude Code 提供了几个直接控制上下文大小的命令:
| 命令 | 作用 | 使用场景 |
|---|---|---|
/clear | 清空当前对话历史,从零开始 | 任务完成后、切换到不相关任务时 |
/compact | 压缩对话历史,保留关键信息,丢弃细节 | 对话过长但还需要部分上下文时 |
/compact <说明> | 带 focus 指令的压缩,告诉模型保留哪部分 | 只想保留特定结论或决策时 |
实操流程:
# 场景:完成了 bug 修复,接下来要做新功能 # 方案 A:彻底清空(推荐,最省 token) /clear # 方案 B:带 focus 指令压缩 /compact 只保留最终的修复方案和涉及的文件列表
子代理(Sub-agent)隔离上下文:Claude Code 内置 Task 工具,可以让模型把一段查询/调研任务派发给独立的子代理。子代理在自己的上下文里跑,最后只把摘要回传到主对话,避免大量中间结果污染主上下文。
# 在主对话中直接搜索 → 搜索结果全部进入上下文 "帮我找到所有用到 UserService 的文件" → 可能 5000+ tokens 的搜索结果 # 用 Task 派发到子代理 → 只有摘要进入主对话 "调研一下项目中 UserService 的使用情况,给我一个总结" → ~200 tokens 的摘要
5.4 权限模式与自动化
每次权限确认都会产生一轮额外交互(模型输出 → 等待确认 → 继续)。合理配置权限模式可以减少不必要的来回。
# 跳过所有确认(适合个人项目、熟悉的操作) claude --dangerously-skip-permissions # 在 settings.json 中按工具放行,其余仍需确认: { "permissions": { "allow": [ "Read", "Glob", "Grep", "Edit", "Write", "Bash(git status)", "Bash(git diff)" ] } }
--dangerously-skip-permissions 会跳过所有安全确认,仅建议在个人开发环境中使用。团队共享环境请用 permissions.allow 精细控制。
Hooks 自动化:Claude Code 支持在工具调用前后挂载 hook,把原本需要模型多轮对话才能完成的格式化、lint 等操作交给本地脚本处理。Hook 通过 stdin 接收 JSON 格式的事件信息(包含 tool_input.file_path 等字段),由你的脚本自行解析。
# settings.json 中配置 PostToolUse hook(Edit/Write 后自动 prettier):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs -r prettier --write"
}
]
}
]
}
}
Hook 在本地执行,不消耗 token。把可以自动化的环节交给它,能显著减少模型介入的轮次。具体的事件类型与 JSON 字段以 Anthropic 官方 Claude Code 文档为准。
六、策略汇总
| 策略 | 预估节省 | 实施难度 | 类型 |
|---|---|---|---|
| 选择支持缓存的渠道 | 长对话场景下显著 | 低 | 通用 |
| 及时 /clear 或新开对话 | 显著 | 低 | Claude Code |
| /compact 压缩长对话 | 中等 | 低 | Claude Code |
| 默认使用 Sonnet | ~80%(替代 Opus 时) | 低 | 通用 |
| 精准读取文件(offset + limit) | 50~90% | 低 | 通用 |
| 精简 CLAUDE.md + 分层管理 | 每轮固定开销 | 中 | Claude Code |
| 配置 permissions.allow 减少确认轮次 | 少量 | 中 | Claude Code |
| hooks 自动化 lint/format | 少量 | 中 | Claude Code |
优先级建议:从最容易上手的开始——选对渠道、默认 Sonnet、任务结束 /clear。这三件事不需要改代码、不需要改配置,但能立刻让账单瘦下来。其他细节可以慢慢调。