乐于分享
好东西不私藏

我让 OpenClaw 读完了Claude Code的源码后发现了这些省钱的秘密

我让 OpenClaw 读完了Claude Code的源码后发现了这些省钱的秘密

3 月 31 日,Claude Code 源码通过 npm source map 意外泄露。我 fork 了一份,让 OpenClaw 花了一晚上读完 51 万行代码,让他总结出了这些帮你省钱的秘密。

先说结论

Claude Code 不是简单的「套壳 CLI」,它是一个精心设计的 Token 经济系统。

在 512,000 行源码里,我发现了至少 7 个直接帮你省钱的设计,还有一些……嗯,Anthropic 不想让你知道的定价秘密。

01

/compact不是可选功能,是救命稻草

源码位置:src/commands/compact/compact.ts

很多人把 /compact当成「整理对话」的可选功能,错了。

真相:这是防止你 Token 爆炸的最后一道防线。

// compact.ts 核心逻辑export const call: LocalCommandCall = async (args, context) => {  // 先尝试 Session Memory 压缩(免费)  if (!customInstructions) {    const sessionMemoryResult = await trySessionMemoryCompaction(...)    if (sessionMemoryResult) {      return { type: 'compact', ... }    }  }  // 再执行 microcompact(微压缩,几乎不花钱)  const microcompactResult = await microcompactMessages(messages, context)  // 最后才调用完整的 compactConversation(花钱)  const result = await compactConversation(...)}

省钱策略:

  1. 不带参数的 /compact优先用 Session Memory—— 这是免费的本地压缩,不消耗 API 调用

  2. microcompact 先执行—— 它只删除冗余消息,不调用 LLM

  3. 真正的总结压缩只在必要时触发

我的建议:看到上下文超过 100K tokens 就手动 /compact,别等自动触发。自动触发的阈值是 contextWindow - 13,000,那时候你已经花了不少冤枉钱了。

02

Fast Mode 的定价陷阱

源码位置:src/utils/modelCost.tssrc/utils/fastMode.ts

这是最劲爆的发现。

Opus 4.6 有两种价格:

// 普通模式:$5 输入 / $25 输出 per Mtokexport const COST_TIER_5_25 = {  inputTokens5,  outputTokens25,  ...}// Fast Mode:$30 输入 / $150 输出 per Mtokexport const COST_TIER_30_150 = {  inputTokens30,  outputTokens150,  ...}

看到了吗?Fast Mode 贵 6 倍。

但源码里有个细节:

export function getOpus46CostTier(fastMode: boolean): ModelCosts {  if (isFastModeEnabled() && fastMode) {    return COST_TIER_30_150  // 6 倍价格  }  return COST_TIER_5_25  // 正常价格}

省钱策略:

  • 除非你真的需要「实时响应」,否则关掉 Fast Mode

  • 检查你的设置:/config里找 fastMode

  • 源码里有个环境变量可以强制关闭:CLAUDE_CODE_DISABLE_FAST_MODE=1

更劲爆的是:Fast Mode 还有「冷却时间」机制。如果你连续触发 rate limit,系统会自动把你踢回普通模式,但不会通知你——你以为是 Fast Mode,其实已经在用普通模式计费了。

03

Cache是你的朋友,但Claude Code不希望你用太多

源码位置:src/cost-tracker.ts

看这段计价代码:

export const COST_TIER_3_15 = {  inputTokens: 3,      // $3 per Mtok  outputTokens: 15,    // $15 per Mtok  promptCacheWriteTokens: 3.75,   // 写缓存 $3.75  promptCacheReadTokens: 0.3,     // 读缓存 $0.3  webSearchRequests: 0.01,        // 每次搜索 $0.01}

发现没有?

  • 写缓存:$3.75/Mtok(比正常输入贵 25%)

  • 读缓存:$0.3/Mtok(只有正常输入的 10%

省钱策略:

  1. 多用读缓存,少写缓存—— 写一次的钱够读 12 次

  2. 长对话用 /resume恢复会话—— 避免重新写缓存

  3. 避免频繁切换项目—— 每次切换都可能触发新的缓存写入

源码里有个细节:cost-tracker.ts会追踪每个模型的 cacheCreationInputTokens和 cacheReadInputTokens,用 /cost命令可以看到详细账单。

我建议你每次开始工作前先 /cost看看昨天的账单,心里有数。

04

Auto Compact 的「缓冲区间」秘密

源码位置:src/services/compact/autoCompact.ts

这段代码暴露了 Anthropic 的「心理战」:

export const AUTOCOMPACT_BUFFER_TOKENS = 13_000export const WARNING_THRESHOLD_BUFFER_TOKENS = 20_000export const ERROR_THRESHOLD_BUFFER_TOKENS = 20_000export const MANUAL_COMPACT_BUFFER_TOKENS = 3_000export function getAutoCompactThreshold(modelstring): number {  const effectiveContextWindow = getEffectiveContextWindowSize(model)  return effectiveContextWindow - AUTOCOMPACT_BUFFER_TOKENS}

翻译一下:

  • 200K 上下文窗口

  • 自动压缩触发点:187K(200K - 13K)

  • 警告阈值:180K

  • 错误阈值:180K

  • 手动压缩安全线:197K

这意味着什么?

系统在「诱导」你早点压缩。13K 的缓冲区间看似保护你,实则是防止你用到 199K 才压缩——那时候一次 API 调用可能直接失败,钱花了还没结果。

省钱策略:

  • 手动设置更激进的压缩阈值:CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=80(80% 就压缩)

  • 或者用环境变量限制最大上下文:CLAUDE_CODE_MAX_CONTEXT_TOKENS=100000(强制用 100K 而非 200K)

源码里还有个彩蛋:

// 连续自动压缩失败 3 次就放弃const MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3

连续失败 3 次系统就放弃了——这时候你的对话已经处于「半残」状态,继续聊只会浪费钱。看到自动压缩失败 3 次,立刻手动 /compact或者重启会话

05

Web Search 每次 $0.01,但你可能在重复付费

源码位置:src/utils/modelCost.ts

webSearchRequests0.01,  // 每次搜索 $0.01

看起来不贵?看源码里的追踪逻辑:

export function addToTotalSessionCost(...) {  // 追踪 web search 请求数  accumulated.webSearchRequests += usage.webSearchRequests ?? 0  // 每次请求都计费  modelUsage.costUSD += cost}

问题在于:Claude Code 不会缓存搜索结果。

你问「今天天气怎么样」,它搜索一次;5 分钟后你问「刚才说的天气」,它可能又搜索一次

省钱策略:

  1. 用 /context查看当前上下文—— 确认信息已经在对话里

  2. 避免重复问同一类问题—— 每次都可能触发新搜索

  3. 用 @file引用本地文件而不是让 Claude 搜索 —— 文件读取免费

源码里的细节:cost-tracker.ts的 formatModelUsage()会显示 web search次数,用 /cost可以看到。

06

模型选择的「默认陷阱」

源码位置:src/utils/model/model.tssrc/utils/context.ts

源码里有个函数叫 getDefaultMainLoopModelSetting(),它决定了你默认用什么模型。

但更关键的是这个:

export function getModelMaxOutputTokens(modelstring): {  defaultnumber  upperLimitnumber} {  if (m.includes('opus-4-6')) {    defaultTokens = 64_000    upperLimit = 128_000  } else if (m.includes('sonnet-4-6')) {    defaultTokens = 32_000    upperLimit = 128_000  }  // ...}

Opus 4.6 默认输出 64K tokens,Sonnet 4.6 默认 32K。

但看定价:

  • Opus 4.6: $5/$25 per Mtok

  • Sonnet 4.6: $3/$15 per Mtok

Opus 不仅单价贵,默认输出还多一倍。

省钱策略:

  1. 默认用 Sonnet 4.6—— 除非你真的需要 Opus 的推理能力

  2. 手动限制最大输出/config maxOutputTokens 16000

  3. 用 /brief命令—— 这是源码里的「简短模式」,强制模型少说话

源码里的彩蛋命令:/brief.ts存在于 src/commands/,但文档里从来没提过。我猜是内部测试功能,但可以用。

07

Session Memory 是免费的,但 90% 的人不知道

源码位置:src/services/compact/sessionMemoryCompact.ts

这段代码在 compact.ts里被优先调用:

// 先尝试 session memory compaction(免费)if (!customInstructions) {  const sessionMemoryResult = await trySessionMemoryCompaction(    messages,    context.agentId,  )  if (sessionMemoryResult) {    return { type'compact', ... }  // 直接返回,不调用 API  }}

Session Memory 压缩是本地操作,不消耗 API 调用。

但它有个限制:不支持自定义指令。一旦你加了参数(比如 /compact 总结重点),系统就会切换到付费的完整压缩模式。

省钱策略:

  1. 日常压缩直接用 /compact(不加参数)—— 走免费通道

  2. 只在必要时加自定义指令—— 比如「只总结技术决策」

  3. 定期用 /memory查看持久化记忆—— 避免重复信息累积

额外发现:这些命令可能帮你省钱

源码 src/commands/目录里还有一些「隐藏命令」:

命令

作用

省钱指数

/cost

查看当前会话花费

⭐⭐⭐⭐⭐

/compact

压缩上下文

⭐⭐⭐⭐⭐

/brief

简短模式(未文档化)

⭐⭐⭐⭐

/resume

恢复之前会话(复用缓存)

⭐⭐⭐⭐

/context

查看当前上下文状态

⭐⭐⭐

/config

修改配置(限制输出 tokens)

⭐⭐⭐⭐

我建议你每次开始工作前:

/cost          # 看看上次花了多少/context       # 确认当前状态/config maxOutputTokens 16000  # 限制输出

最后的思考

读到这些,让我自己我最大的感受是:

Claude Code 的设计者在「Token 经济」上花了大量心思。每一个功能背后都有成本考量,但大部分用户看不到。

几个核心发现:

  1. 自动压缩是保护机制,但阈值设置偏保守—— 系统在防止你失败,但也在「诱导」你早点付费压缩

  2. Fast Mode 是「奢侈品」—— 6 倍价格,除非你真需要实时性,否则关掉

  3. 缓存是把双刃剑—— 读缓存便宜,写缓存贵,策略很重要

  4. Session Memory 是免费午餐—— 但需要你用对方式