[转载+总结] Claude Code最大化使用量+避免Token浪费的最佳实践
- 内容介绍
- 文章标签
- 相关推荐
转载自Reddit:https://www.reddit.com/r/ClaudeCode/comments/1sd8t5u/anthropic_isnt_the_only_reason_youre_hitting/ . 一般来说我不倾向于直接转载Reddit帖子,但这篇的洞察很全面,也做了对应的实验探索,感觉对佬友们会很有帮助。
原贴英文,下面会把翻译版贴出来。在贴翻译版之前先自己放一些Claude Code计费的背景,在文章最后会有我总结的最佳实践。
背景
上下文拼接
像CC/Codex/Open Code/龙虾这样的智能体harness实际上是自动化了输入/输出构建的流水线。在实际发送到模型的上下文里不仅会包含你看到的那些输入输出,还会有很多额外的自动拼接的token:
- 第一轮对话之前,CC会拼接一系列的文件到上下文里作为输入的一部分。其中包括系统级设置
/etc/claude-code/CLAUDE.md,全局个人设置~/.claude/CLAUDE.md,全局个人规则~/.claude/rules/*.md,以及从当前目录一路往上到root目录的CLAUDE.md和规则,外加2.5K token的默认系统指令、~15K token的默认工具定义,和你加载的所有MCP定义和skill定义。 - 后续的每一轮对话给模型的请求都包含在同一个窗口内发生过的所有输入输出历史,再拼接上自己最新一轮的输入,而并非只给模型发送最后一轮输入。这里面实际拼接的内容比看到的要长,这是因为CC为了反蒸馏会隐藏思维链和工具调用细节,但被隐藏的思维链和工具调用也在给模型发送的上下文请求内。
- 总而言之,随着对话轮次增多,发送给模型的请求会越来越长,其中靠前的部分(比如第一轮对话之前的那一堆工具定义)会被CC重复发送很多次请求,因为每一轮请求里都有这一段。
Cache 机制
大模型有KV Cache可以复用部分已经处理过的上下文的token。KV Cache可以让模型在上下文里有一部分已经被处理过的情况下不再重复处理。用CC时,当你完全从第一个token开始到某一个token都和之前的某次请求一样,这个完全一样的部分可以以低价格计费。
Cache 机制举例
- 如果你在一两分钟内开了两个CC窗口分别聊不同的东西,第二个CC窗口的“第一轮输入前的文件拼接”会以Cache命中价格计费,你的输入会以未命中价格计费。
- 如果你在一轮对话里短时间内就接上了上一次请求(这里请求包括你自己的输入和CC自动的工具调用),那么直到你当前输入之前的所有部分都会以Cache命中价格计费,你的输入会以未命中价格计费。
- 如果你的任务中有一轮请求在上一轮请求之后很久(5分钟或1小时,后续会分析),那么下一轮请求(无论是用户自己输入还是CC自动工具调用)都会把从第一轮第一个token到目前为止的所有token都以未命中价格计费。
Claude Cache 的计费规则
以下信息来自Pricing - Claude API Docs。所有价格是每百万token价格。
| 模型 | 基础输入 | Cache 写 (5m) | Cache 写 (1h) | Cache 命中 | 输出 |
|---|---|---|---|---|---|
| Claude Opus 4.6 | $5 | $6.25 | $10 | $0.50 | $25 |
| Claude Sonnet 4.6 | $3 | $3.75 | $6 | $0.30 | $15 |
| Claude Haiku 4.5 | $1 | $1.25 | $2 | $0.10 | $5 |
其中,使用5m还是1h Cache是由服务器端决定的。Claude Max订阅默认使用1h Cache。Claude Pro订阅和API默认使用5m Cache。
Cache的写入和更新规则
每一轮请求中(例如新开一轮对话、用户输入续上了先前的对话、或者CC自动工具调用),截止到当前用户的新输入、模型的新调用之前的部分会被查询Cache。
- 如果有Cache,先前部分会以“Cache命中”计费。
- 如果没有Cache,先前部分会以“Cache写”计费并重新计算Cache时间。
- 新输入、新调用的部分以“基础输入”计费。
好了,背景知识到此结束,以下是搬运内容。
Reddit:人为因素并不是你达到 Claude 代码限制的唯一原因。我审核了 926 个会话,发现很多浪费都出在我这边。
过去十天,X 和 Reddit 上到处都是对 Anthropic 更改流量限制的愤怒之声。我突然发现,两天之内就用完了一周的流量,但我做的还是同样的项目,工作流程也没有任何改变。社交媒体上有人反映,200 美元的 Max 套餐几个小时就用完了,还有人报告说出现了无法解释的“幽灵Token”使用情况。一些人甚至对 Claude Code 的二进制文件进行了逆向工程,发现缓存漏洞导致流量消耗翻了 10 到 20 倍。Anthropic 对此问题置之不理,他们只是在后台偷偷地调整参数。
和大多数人一样,我的工作完全停滞了。我每天要在 Claude Code 里待 8 到 10 个小时,结果到了周二,半周的时间就过去了。
但生气解决不了任何问题。我意识到,人工智能正在商品化。订阅只是入门门槛。真正的定价模式是Token,就像电力一样。你是在按单位租用智能。所以,作为一个每天都依赖这个工具,而且将来可能还会依赖类似工具的人,我希望我支付的每一个Token都能发挥最大的价值。
我从一个基本问题开始调查:在我输入任何内容之前,系统会加载多少上下文?如果你懂的话,每个 Claude Code 会话都会以一个基础上下文开始(系统提示、工具定义、代理描述、记忆文件、技能描述、MCP 架构)。你可以在对话的任何阶段运行/context来查看已加载的内容。我在会话开始时运行了该命令,结果是 45,000 个Token。当时我打开的是 100 万个Token的上下文窗口,状态栏里有一个百分比条,所以 45,000 个Token显示为大约 5%。我根本没仔细看,也没在心里算过绝对数量。同样的 45,000 个Token,如果放在标准的 20 万个Token的窗口里,在你开口说话之前就已经消耗了超过 20%。而且你每回合都要付出这 45,000 个Token的代价。
Claude Code(以及所有 AI 助手)并不维护持久对话。它是一个无状态循环。每一回合,整个历史记录都会从头开始重建并发送给模型:系统提示、工具模式、所有之前的消息以及你的新消息。每次都是如此。提示缓存是服务提供商降低成本的关键。他们不会重新加载回合间通用的部分,从而节省了 90%的Token。但缓存也需要成本,Anthropic 公司认为 5 分钟是最佳时长(译者注:实际上Max订阅是1小时Cache)。之后,缓存就会过期。他们的激励机制是鼓励你消耗更多Token,而不是更少。因此,在典型的使用中,你只需为缓存的前缀支付 0.50 美元每百万Token,而最后只需为新内容支付 5 美元每百万Token。缓存过期后,你的下一回合将以全价重新处理所有内容。成本瞬间飙升 10 倍,而你却浑然不觉。
于是我开始疯狂优化。我精简并重做了CLAUDE.md和记忆文件,合并了技能描述,关闭了不使用的 MCP 服务器,并优化了会话开始时记忆hook注入的模式。大概节省了 4000-5000 个Token,减少了 10%。这种感觉持续了一个小时。
我又开始好奇,于是查看了另外 4 万个Token的来源。原来其中 2 万个是系统工具的模式定义。默认情况下,Claude Code 会在会话开始时加载每个可用工具的完整 JSON 模式到上下文中,无论你是否使用该工具。他们确实希望你消耗比实际需要更多的Token。大多数用户甚至不知道这是可以配置的。我之前也不知道。
该设置名为enable_tool_search,用于启用工具搜索延迟加载。以下是在 settings.json 文件中进行设置的方法:
"env": {
"ENABLE_TOOL_SEARCH": "true"
}
此设置仅加载 6 个主要工具,其余工具按需延迟加载,而不是一次性全部加载。初始上下文大小从 45k 降至 20k,系统工具开销从 20k 降至 6k。仅需在配置文件中添加一行代码,即可在每个会话的每个回合中节省 14,000 个Token。
我粗略计算了一下这个设置给我造成的损失。我的Claude Code平均每个会话 22 轮。每轮额外消耗 14,000 个Token,也就是说每个会话额外消耗了 308,000 个Token。858 个会话总共消耗了 2.64 亿个Token。按缓存读取价格(0.50 美元/百万Token)计算,这相当于 132 美元。但超过一半的回合我都访问了过期的缓存,支付了全额输入价格(5 美元/百万Token),所以实际成本在 132 美元到 1,300 美元之间。这仅仅是一个默认设置。而且对于订阅用户来说,这些Token还会计入你们的速率限制配额。
这个数字让我大吃一惊。我从未听说过的一个设置竟然消耗了这么多资源。还有哪些隐藏的资源浪费?Anthropic 内置了/insights命令,但我运行了一次后发现它对于诊断资源浪费的真正来源并没有什么帮助。Claude Code 会将每次对话以 JSONL 文件的形式存储在本地的~/.claude/projects/目录下,但它并没有内置方法来按会话、每个项目的成本或哪些类型的工作成本较高等方式进行详细分析。
所以我构建了一个Token使用审计器工具。它会遍历每个 JSONL 文件,解析每一回合,并将所有数据(Token计数、缓存命中率、工具调用次数、空闲间隙、编辑失败次数、技能调用次数)加载到 SQLite 数据库中,然后通过一个洞察引擎,根据预估金额对浪费类别进行排名。它还会生成一个包含 19 个图表的交互式仪表板:每个会话的缓存轨迹、按项目和模型划分的成本细分、工具效率指标、行为模式以及技能使用情况分析。
我的统计数据:858 次会话,18,903 次请求,预计 33 天内花费 1,619 美元。仪表盘帮我发现了以下信息:
- 缓存过期是最大的浪费类别
在我的会话中,有 54%(11357 回合中的 6152 回合)发生在超过 5 分钟的空闲时间之后。这些轮次都支付了全额输入价格,而不是缓存价格。超过一半的时间,整个对话上下文都应用了 10 倍的倍率。
工具特别标记了“缓存断崖”(“Cache Cliffs”):即连续两轮请求之间缓存读取率下降超过 50% 的情况。在 858 个会话中,共出现了 232 次这样的情况,这些情况集中在我耗时最长、成本最高的项目中。
这就是订阅用户感受到的速率限制和 API 用户感受到的账单所反映出的浪费模式。你正在进行长时间的操作,然后去喝杯咖啡或者被拉进一个 Slack 讨论串,五分钟后回来输入下一条消息。所有数据都会被重新处理。上下文没有改变,你也没有改变,只是缓存过期了。
预计浪费:1230 万个Token,这些Token没有计入我的使用量,却没有任何价值。按 API 收费,根据缓存状态的不同,这相当于 55 到 600 美元,但对于订阅用户来说,真正造成损失的是速率限制。这 1230 万个Token约占我总投入预算的 7.5%,白白浪费掉了。
- 你的上下文中有 20% 是你永远不会调用的工具模式。
前面已经介绍过了,但数据让情况更加清晰。工具会跟踪所有会话中的技能(Skill)使用情况。我的设置中加载了 42 个技能。其中 19 个技能在整个 858 个会话数据集中调用次数不超过 2 次。这些技能模式在每个会话的每个回合都存在于上下文中,消耗输入Token。
工具中有一个名为“考虑禁用的技能”的表格,它会自动标记使用率低的技能,并附上原因列(从未使用、使用频率低、每次运行都出错)。您可以立即采取行动:禁用不使用的技能,释放上下文资源。
结合启用工具搜索 (ENABLE_TOOL_SEARCH) 设置,上下文清理是我发现的最有效的优化手段。无需更改任何行为,只需进行配置即可。
3.
4. 冗余文件读取化合物静默运行
在所有会话中,同一个文件被读取3次或以上的情况共计1122次。最坏情况:一个会话对同一个文件读取了33次。另一个会话对同一个文件读取了28次。
每次重读本身成本并不高。但每次读取的输出都会保留在后续的对话上下文中。在长时间会话中,如果Cache已经不堪重负,冗余的读取会不断填充上下文,导致每次缓存过期时都需要以全价重新处理。预计所有会话共浪费约 56.1 万个Token,API 成本约为 2.80 至 28 美元。虽然每次浪费的金额不大,但与缓存过期机制的交互会造成累积效应。
审计器还标记了 bash 反模式(antipattern)(在662 次调用中 Claude 使用了 bash 的 cat 、 grep 和 find 命令,而不是使用原生的 Read/Grep/Glob 工具)和编辑重试链(31 个编辑失败后重试的序列)。两者都以相同的方式加剧了上下文膨胀。我还安装了RTK(一个 CLI 代理,可以在命令输出到达 LLM 上下文之前对其进行过滤和汇总),以减少冗长 shell 命令的输出标记膨胀。我在 Twitter 上发现了它,如果您运行大量 bash 相关的工作流程,值得一试。
在看到缓存过期数据后,我构建了三个钩子(hook),以便在产生任何成本之前使其可见:
-
停止钩子:记录每轮对话后的确切时间戳,以便系统知道何时进入空闲状态。
-
UserPromptSubmit钩子:检查自 Claude 上次响应以来已空闲了多长时间。如果超过 5 分钟,则会阻塞您的消息一次并发出警告:“缓存已过期,此回合将从头开始重新处理完整上下文。请先运行/compact以降低成本,或重新发送以继续。” -
SessionStart钩子:用于恢复的会话,读取上次的会话记录,估算需要重新创建多少缓存Token,并在第一次收到提示之前发出警告。
在这些钩子出现之前,缓存过期是看不到的。现在,我可以在执行高成本操作之前看到它。我可以使用 /compact 命令来缩小上下文,或者直接在知道开销的情况下继续操作。这些钩子目前还没有集成到插件中(屏蔽用户提示的用户体验还需要进一步考虑),但如果有需求,我会发布它们。
为了保持对话的连续性,我并不倾向于使用/compact命令(会丢失上下文)或恢复过期的会话(这需要重新构建完整的缓存)。相反,我直接使用/clear命令并创建一个新会话。这个审计器技能所属的内存插件会在启动时自动注入上一个会话的上下文,因此新会话无需携带 20 万个会话历史记录即可获得所需的信息。清除会话时,它会保留清除会话的状态。这意味着,如果您在同一个项目中同时处理两个线程,每次清除操作都会为下一个会话提供您在上一个会话中执行的操作的上下文。此外,Claude还可以使用一个技能来搜索和回忆任何过去的对话。我上个月详细撰写了关于内存系统的文章。Token审计器是这个插件的最新功能,因为我经常遇到限制,并且想要了解原因。
该插件名为claude-memory,托管于我的开源 Claude 代码市场claudest。审计器工具是其中一项技能(/get-token-insights)。该插件包含启动时自动注入会话上下文、清晰完整的会话历史记录搜索,以及一项学习提取技能(灵感来自未发布但已泄露的“dream”功能),该技能可将过去会话的洞察整合到持久内存文件中。首次运行审计器处理数千个会话文件大约需要 100 秒,之后每次运行耗时不到 5 秒。
仓库链接:GitHub - gupsammy/Claudest: A highly opinionated plugin marketplace for augmenting your Claude Code. Battle-tested skills and tools that actually work. · GitHub
Token洞察技能为/get-token-insights, 作为claude-memory插件的一部分,安装只需要:
/plugin marketplace add gupsammy/claudest
/plugin install claude-memory@claudest
首次运行大约需要 100 秒,之后递增运行。会在浏览器中打开一个交互式仪表板。
我提到的内存帖子: https://www.reddit.com/r/ClaudeCode/comments/1r1w397/comment/odt85ev/
缓存警告钩子是我个人配置的,尚未发布。如果有人需要,我会把它们添加到插件里。我很乐意回答关于数据或实现方面的问题。
值得注意的是以下局限性:
-
JSONL 解析依赖于 Claude Code 的本地文件格式,而该格式并未正式记录。目前该解析方法在当前格式下可以正常工作,但如果 Anthropic 更改了格式,则可能会失效。
-
美元估算采用已公布的 API 定价(Opus 4.6:输入 5 美元/MTok,输出 25 美元/MTok,缓存读取 0.50 美元/MTok)。订阅计划与 API 成本并非一一对应。重要的是相对浪费排名,而不是绝对的美元数字。
-
“浪费”是因人而异的。有些缓存重建是不可避免的(比如你得吃午饭)。关键在于让浪费可见,而不是完全消除。
还有一点。这个审计工具并非只对 Claude Code 用户有用。如果您使用 Claude Code SDK 进行开发,这项技能可以直接对代理会话进行可观测性分析。其底层方法(解析 JSONL 转录、加载到 SQLite、提取模式)也适用于大多数 CLI 编码代理。它们的底层工作原理大致相同。只要代理写入原始会话文件,您就可以观察到相同的冗余模式。我为 Claude Code 开发了这个工具,因为我自己也在使用它,但其架构可以移植。
如果你发现自己的极限消耗速度比预期更快,却不知道原因,那么这些数据可以让你了解实际情况。
译者总结的最佳实践
为了避免Claude的token浪费,以下是根据这篇reddit帖子和我个人使用经历总结的一些方法:
- 在后续对话几乎不会用到先前对话内容时,不要继续对话,而是用
/clear开启新对话。 - 一劳永逸地让Claude对每一轮都一定会被加入上下文的
CLAUDE.md和规则文件进行简化。很多时候自己写的CLAUDE.md规则都很冗余,但模型可能能用50%的Token表达同样的意思。 - 卸载掉不会用到的Skill/MCP/Plugin。对于只会在某个项目里用到的Skill/MCP/Plugin,把它们安装在项目目录下,不要安装在根目录下。
- 采用lazy load。对于很繁杂的记忆文件和规则/skill定义,把具体记忆/定义内容拆散在不同文件里,而在Claude一定会读的文件里只包含拆散的文件路径字符串,让CC只在需要使用某个记忆/某项技能的时候再去读对应文件。同时,在
settings.json里设置"ENABLE_TOOL_SEARCH": "true"环境变量。 - 尽可能不要复用超长又Cache过期的对话。在对这种对话新增输入之前,要掂量清楚自己这一轮对话重写Cache的开销。
- 当模型某项操作失败(比如没能达成目标或者对输入理解有误的时候),尤其是在Cache已过期或者模型上一轮做了大量输出的时候,不要新开一轮对话纠正,而是按两次esc回退到上一轮对话的状态修改自己上一轮的输入,这样能在纠正模型行为的同时省去一整轮输入输出的上下文请求。
- 在能用子agent的时候就用子agent。子agent会fork先前上下文做并行操作,这样不仅能最大程度复用Cache,持续刷新Cache TTL时间,还不会大幅影响主agent的上下文。这样主agent的后续操作就能更加节省。
- 采用适当的记忆机制。当之前轮次的某个操作会在未来节省token(比如庞大目录的文件树,debug频繁踩的坑,或者分析出某个文件反复读取背后的原因),让claude第一时间把它们记在记忆文件里供后续会话参考。
- 在
CLAUDE.md里鼓励模型使用能节省token的工具。例如,能用内置的Read/Grep/Glob就不要用命令行,以及如果配置了serena的话,能用serena就不要完整读取文件。 - 利用git历史作为记忆的一部分。在每次做完一件事之后,都在
git commit里写清楚修改了什么,这样当CC读取git历史的时候自然就知道每个文件都做了什么。 - 在一开始的输入里包含尽可能清晰的计划,或者让Claude自己用planning mode/superpowers做好计划再执行。对于不清晰的请求做反复修改是最耗费token的。
这篇帖子用来抛砖引玉,求各位佬友批评指正,也欢迎大家分享自己的心得
网友解答:--【壹】--:
总结的内容就不少啊,我记得有些 github 项目可以实现 token 节省
--【贰】--:
不要怕,做个备份改了试试,如果变差了再改回来
--【叁】--:
这个文章看了,但是还是没提为何之前token消耗没事,现在token消耗突然变大了,以前这些加载,命中什么的也是这样啊,现在突然变高了
--【肆】--:
问题是max默认是1H缓存,但是我max消耗也是异常快。而且说是2.1.87(具体忘了)版本已经改过来了,我升级了版本但是消耗还是快。所以缓存感觉不治本。
上下文窗口我也调到200K了,目前试验也还是快。
--【伍】--:
如果是跟cache有关的就不会有任何效果的影响,其他的得在自己的使用场景里实验验证了。不过我自己这边体感倒是前后没什么效果影响
--【陆】--:
是的,其实我体感也是这样,所以就更显得省token重要了,能省一点是一点…
--【柒】--:
感谢分享。对于我来说,最重要的就是
绪里:很多时候自己写的
CLAUDE.md规则都很冗余,但模型可能能用50%的Token表达同样的意思。
有点好奇,这么多措施,有没有可能,为了节省 token 导致模型效果变差?
--【捌】--:
在此,也推荐下 opencode+DCP 的组合,个人觉得是 agent 工程化的一个很好示例。
--【玖】--:
佬 max 不一定是1h缓存,之前用cc读过代码,有个变量受a控制,这个变量决定了是否启用1h,不同账号可能不同。我通过解析json得到我的号默认是5m。我的版本是1.77。(当然用patch可以硬开1h)
--【拾】--: 利陆都2253:
感谢分享。
感谢分享。
--【拾壹】--:
这个有人说是前几次更新的缓存机制出bug了,最新的改了,也有人说是因为前一段时间有2x活动现在没了,但确实不知道是咋回事
--【拾贰】--:
学习一下,感谢大佬
--【拾叁】--:
你真棒
--【拾肆】--:
是啊,很多东西现在都很好改,就怕给 AI 这个黑盒引入更多变量,效果反而变差
--【拾伍】--:
学到了,分享下我自己在使用中,一般会 分析 存文档 clear 优化文档 clear 优化文档 clear 优化文档 clear Coding。。 这样反复优化文档,可以优化轮数10次以上,0用opus来不断反复。然后coding用sonnet。
优化文档就是文opus:有什么建议可以改进这种设计吗?
--【拾陆】--: 绪里:
对于不清晰的请求做反复修改是最耗费token的
写好prompt确实很重要
--【拾柒】--:
前阵子对 Clauce Code 的请求做过一下抓包,确实,他每次请求都会携带大量 System Prompt 和 Tools Description ,这东西还是停费token的。
--【拾捌】--:
这样。。。细说,怎么看自己是不是5m还是1h,还真有可能,我是max5,不是20
--【拾玖】--:
省token好文,今天就让CC按这个文章,帮我自动配置
转载自Reddit:https://www.reddit.com/r/ClaudeCode/comments/1sd8t5u/anthropic_isnt_the_only_reason_youre_hitting/ . 一般来说我不倾向于直接转载Reddit帖子,但这篇的洞察很全面,也做了对应的实验探索,感觉对佬友们会很有帮助。
原贴英文,下面会把翻译版贴出来。在贴翻译版之前先自己放一些Claude Code计费的背景,在文章最后会有我总结的最佳实践。
背景
上下文拼接
像CC/Codex/Open Code/龙虾这样的智能体harness实际上是自动化了输入/输出构建的流水线。在实际发送到模型的上下文里不仅会包含你看到的那些输入输出,还会有很多额外的自动拼接的token:
- 第一轮对话之前,CC会拼接一系列的文件到上下文里作为输入的一部分。其中包括系统级设置
/etc/claude-code/CLAUDE.md,全局个人设置~/.claude/CLAUDE.md,全局个人规则~/.claude/rules/*.md,以及从当前目录一路往上到root目录的CLAUDE.md和规则,外加2.5K token的默认系统指令、~15K token的默认工具定义,和你加载的所有MCP定义和skill定义。 - 后续的每一轮对话给模型的请求都包含在同一个窗口内发生过的所有输入输出历史,再拼接上自己最新一轮的输入,而并非只给模型发送最后一轮输入。这里面实际拼接的内容比看到的要长,这是因为CC为了反蒸馏会隐藏思维链和工具调用细节,但被隐藏的思维链和工具调用也在给模型发送的上下文请求内。
- 总而言之,随着对话轮次增多,发送给模型的请求会越来越长,其中靠前的部分(比如第一轮对话之前的那一堆工具定义)会被CC重复发送很多次请求,因为每一轮请求里都有这一段。
Cache 机制
大模型有KV Cache可以复用部分已经处理过的上下文的token。KV Cache可以让模型在上下文里有一部分已经被处理过的情况下不再重复处理。用CC时,当你完全从第一个token开始到某一个token都和之前的某次请求一样,这个完全一样的部分可以以低价格计费。
Cache 机制举例
- 如果你在一两分钟内开了两个CC窗口分别聊不同的东西,第二个CC窗口的“第一轮输入前的文件拼接”会以Cache命中价格计费,你的输入会以未命中价格计费。
- 如果你在一轮对话里短时间内就接上了上一次请求(这里请求包括你自己的输入和CC自动的工具调用),那么直到你当前输入之前的所有部分都会以Cache命中价格计费,你的输入会以未命中价格计费。
- 如果你的任务中有一轮请求在上一轮请求之后很久(5分钟或1小时,后续会分析),那么下一轮请求(无论是用户自己输入还是CC自动工具调用)都会把从第一轮第一个token到目前为止的所有token都以未命中价格计费。
Claude Cache 的计费规则
以下信息来自Pricing - Claude API Docs。所有价格是每百万token价格。
| 模型 | 基础输入 | Cache 写 (5m) | Cache 写 (1h) | Cache 命中 | 输出 |
|---|---|---|---|---|---|
| Claude Opus 4.6 | $5 | $6.25 | $10 | $0.50 | $25 |
| Claude Sonnet 4.6 | $3 | $3.75 | $6 | $0.30 | $15 |
| Claude Haiku 4.5 | $1 | $1.25 | $2 | $0.10 | $5 |
其中,使用5m还是1h Cache是由服务器端决定的。Claude Max订阅默认使用1h Cache。Claude Pro订阅和API默认使用5m Cache。
Cache的写入和更新规则
每一轮请求中(例如新开一轮对话、用户输入续上了先前的对话、或者CC自动工具调用),截止到当前用户的新输入、模型的新调用之前的部分会被查询Cache。
- 如果有Cache,先前部分会以“Cache命中”计费。
- 如果没有Cache,先前部分会以“Cache写”计费并重新计算Cache时间。
- 新输入、新调用的部分以“基础输入”计费。
好了,背景知识到此结束,以下是搬运内容。
Reddit:人为因素并不是你达到 Claude 代码限制的唯一原因。我审核了 926 个会话,发现很多浪费都出在我这边。
过去十天,X 和 Reddit 上到处都是对 Anthropic 更改流量限制的愤怒之声。我突然发现,两天之内就用完了一周的流量,但我做的还是同样的项目,工作流程也没有任何改变。社交媒体上有人反映,200 美元的 Max 套餐几个小时就用完了,还有人报告说出现了无法解释的“幽灵Token”使用情况。一些人甚至对 Claude Code 的二进制文件进行了逆向工程,发现缓存漏洞导致流量消耗翻了 10 到 20 倍。Anthropic 对此问题置之不理,他们只是在后台偷偷地调整参数。
和大多数人一样,我的工作完全停滞了。我每天要在 Claude Code 里待 8 到 10 个小时,结果到了周二,半周的时间就过去了。
但生气解决不了任何问题。我意识到,人工智能正在商品化。订阅只是入门门槛。真正的定价模式是Token,就像电力一样。你是在按单位租用智能。所以,作为一个每天都依赖这个工具,而且将来可能还会依赖类似工具的人,我希望我支付的每一个Token都能发挥最大的价值。
我从一个基本问题开始调查:在我输入任何内容之前,系统会加载多少上下文?如果你懂的话,每个 Claude Code 会话都会以一个基础上下文开始(系统提示、工具定义、代理描述、记忆文件、技能描述、MCP 架构)。你可以在对话的任何阶段运行/context来查看已加载的内容。我在会话开始时运行了该命令,结果是 45,000 个Token。当时我打开的是 100 万个Token的上下文窗口,状态栏里有一个百分比条,所以 45,000 个Token显示为大约 5%。我根本没仔细看,也没在心里算过绝对数量。同样的 45,000 个Token,如果放在标准的 20 万个Token的窗口里,在你开口说话之前就已经消耗了超过 20%。而且你每回合都要付出这 45,000 个Token的代价。
Claude Code(以及所有 AI 助手)并不维护持久对话。它是一个无状态循环。每一回合,整个历史记录都会从头开始重建并发送给模型:系统提示、工具模式、所有之前的消息以及你的新消息。每次都是如此。提示缓存是服务提供商降低成本的关键。他们不会重新加载回合间通用的部分,从而节省了 90%的Token。但缓存也需要成本,Anthropic 公司认为 5 分钟是最佳时长(译者注:实际上Max订阅是1小时Cache)。之后,缓存就会过期。他们的激励机制是鼓励你消耗更多Token,而不是更少。因此,在典型的使用中,你只需为缓存的前缀支付 0.50 美元每百万Token,而最后只需为新内容支付 5 美元每百万Token。缓存过期后,你的下一回合将以全价重新处理所有内容。成本瞬间飙升 10 倍,而你却浑然不觉。
于是我开始疯狂优化。我精简并重做了CLAUDE.md和记忆文件,合并了技能描述,关闭了不使用的 MCP 服务器,并优化了会话开始时记忆hook注入的模式。大概节省了 4000-5000 个Token,减少了 10%。这种感觉持续了一个小时。
我又开始好奇,于是查看了另外 4 万个Token的来源。原来其中 2 万个是系统工具的模式定义。默认情况下,Claude Code 会在会话开始时加载每个可用工具的完整 JSON 模式到上下文中,无论你是否使用该工具。他们确实希望你消耗比实际需要更多的Token。大多数用户甚至不知道这是可以配置的。我之前也不知道。
该设置名为enable_tool_search,用于启用工具搜索延迟加载。以下是在 settings.json 文件中进行设置的方法:
"env": {
"ENABLE_TOOL_SEARCH": "true"
}
此设置仅加载 6 个主要工具,其余工具按需延迟加载,而不是一次性全部加载。初始上下文大小从 45k 降至 20k,系统工具开销从 20k 降至 6k。仅需在配置文件中添加一行代码,即可在每个会话的每个回合中节省 14,000 个Token。
我粗略计算了一下这个设置给我造成的损失。我的Claude Code平均每个会话 22 轮。每轮额外消耗 14,000 个Token,也就是说每个会话额外消耗了 308,000 个Token。858 个会话总共消耗了 2.64 亿个Token。按缓存读取价格(0.50 美元/百万Token)计算,这相当于 132 美元。但超过一半的回合我都访问了过期的缓存,支付了全额输入价格(5 美元/百万Token),所以实际成本在 132 美元到 1,300 美元之间。这仅仅是一个默认设置。而且对于订阅用户来说,这些Token还会计入你们的速率限制配额。
这个数字让我大吃一惊。我从未听说过的一个设置竟然消耗了这么多资源。还有哪些隐藏的资源浪费?Anthropic 内置了/insights命令,但我运行了一次后发现它对于诊断资源浪费的真正来源并没有什么帮助。Claude Code 会将每次对话以 JSONL 文件的形式存储在本地的~/.claude/projects/目录下,但它并没有内置方法来按会话、每个项目的成本或哪些类型的工作成本较高等方式进行详细分析。
所以我构建了一个Token使用审计器工具。它会遍历每个 JSONL 文件,解析每一回合,并将所有数据(Token计数、缓存命中率、工具调用次数、空闲间隙、编辑失败次数、技能调用次数)加载到 SQLite 数据库中,然后通过一个洞察引擎,根据预估金额对浪费类别进行排名。它还会生成一个包含 19 个图表的交互式仪表板:每个会话的缓存轨迹、按项目和模型划分的成本细分、工具效率指标、行为模式以及技能使用情况分析。
我的统计数据:858 次会话,18,903 次请求,预计 33 天内花费 1,619 美元。仪表盘帮我发现了以下信息:
- 缓存过期是最大的浪费类别
在我的会话中,有 54%(11357 回合中的 6152 回合)发生在超过 5 分钟的空闲时间之后。这些轮次都支付了全额输入价格,而不是缓存价格。超过一半的时间,整个对话上下文都应用了 10 倍的倍率。
工具特别标记了“缓存断崖”(“Cache Cliffs”):即连续两轮请求之间缓存读取率下降超过 50% 的情况。在 858 个会话中,共出现了 232 次这样的情况,这些情况集中在我耗时最长、成本最高的项目中。
这就是订阅用户感受到的速率限制和 API 用户感受到的账单所反映出的浪费模式。你正在进行长时间的操作,然后去喝杯咖啡或者被拉进一个 Slack 讨论串,五分钟后回来输入下一条消息。所有数据都会被重新处理。上下文没有改变,你也没有改变,只是缓存过期了。
预计浪费:1230 万个Token,这些Token没有计入我的使用量,却没有任何价值。按 API 收费,根据缓存状态的不同,这相当于 55 到 600 美元,但对于订阅用户来说,真正造成损失的是速率限制。这 1230 万个Token约占我总投入预算的 7.5%,白白浪费掉了。
- 你的上下文中有 20% 是你永远不会调用的工具模式。
前面已经介绍过了,但数据让情况更加清晰。工具会跟踪所有会话中的技能(Skill)使用情况。我的设置中加载了 42 个技能。其中 19 个技能在整个 858 个会话数据集中调用次数不超过 2 次。这些技能模式在每个会话的每个回合都存在于上下文中,消耗输入Token。
工具中有一个名为“考虑禁用的技能”的表格,它会自动标记使用率低的技能,并附上原因列(从未使用、使用频率低、每次运行都出错)。您可以立即采取行动:禁用不使用的技能,释放上下文资源。
结合启用工具搜索 (ENABLE_TOOL_SEARCH) 设置,上下文清理是我发现的最有效的优化手段。无需更改任何行为,只需进行配置即可。
3.
4. 冗余文件读取化合物静默运行
在所有会话中,同一个文件被读取3次或以上的情况共计1122次。最坏情况:一个会话对同一个文件读取了33次。另一个会话对同一个文件读取了28次。
每次重读本身成本并不高。但每次读取的输出都会保留在后续的对话上下文中。在长时间会话中,如果Cache已经不堪重负,冗余的读取会不断填充上下文,导致每次缓存过期时都需要以全价重新处理。预计所有会话共浪费约 56.1 万个Token,API 成本约为 2.80 至 28 美元。虽然每次浪费的金额不大,但与缓存过期机制的交互会造成累积效应。
审计器还标记了 bash 反模式(antipattern)(在662 次调用中 Claude 使用了 bash 的 cat 、 grep 和 find 命令,而不是使用原生的 Read/Grep/Glob 工具)和编辑重试链(31 个编辑失败后重试的序列)。两者都以相同的方式加剧了上下文膨胀。我还安装了RTK(一个 CLI 代理,可以在命令输出到达 LLM 上下文之前对其进行过滤和汇总),以减少冗长 shell 命令的输出标记膨胀。我在 Twitter 上发现了它,如果您运行大量 bash 相关的工作流程,值得一试。
在看到缓存过期数据后,我构建了三个钩子(hook),以便在产生任何成本之前使其可见:
-
停止钩子:记录每轮对话后的确切时间戳,以便系统知道何时进入空闲状态。
-
UserPromptSubmit钩子:检查自 Claude 上次响应以来已空闲了多长时间。如果超过 5 分钟,则会阻塞您的消息一次并发出警告:“缓存已过期,此回合将从头开始重新处理完整上下文。请先运行/compact以降低成本,或重新发送以继续。” -
SessionStart钩子:用于恢复的会话,读取上次的会话记录,估算需要重新创建多少缓存Token,并在第一次收到提示之前发出警告。
在这些钩子出现之前,缓存过期是看不到的。现在,我可以在执行高成本操作之前看到它。我可以使用 /compact 命令来缩小上下文,或者直接在知道开销的情况下继续操作。这些钩子目前还没有集成到插件中(屏蔽用户提示的用户体验还需要进一步考虑),但如果有需求,我会发布它们。
为了保持对话的连续性,我并不倾向于使用/compact命令(会丢失上下文)或恢复过期的会话(这需要重新构建完整的缓存)。相反,我直接使用/clear命令并创建一个新会话。这个审计器技能所属的内存插件会在启动时自动注入上一个会话的上下文,因此新会话无需携带 20 万个会话历史记录即可获得所需的信息。清除会话时,它会保留清除会话的状态。这意味着,如果您在同一个项目中同时处理两个线程,每次清除操作都会为下一个会话提供您在上一个会话中执行的操作的上下文。此外,Claude还可以使用一个技能来搜索和回忆任何过去的对话。我上个月详细撰写了关于内存系统的文章。Token审计器是这个插件的最新功能,因为我经常遇到限制,并且想要了解原因。
该插件名为claude-memory,托管于我的开源 Claude 代码市场claudest。审计器工具是其中一项技能(/get-token-insights)。该插件包含启动时自动注入会话上下文、清晰完整的会话历史记录搜索,以及一项学习提取技能(灵感来自未发布但已泄露的“dream”功能),该技能可将过去会话的洞察整合到持久内存文件中。首次运行审计器处理数千个会话文件大约需要 100 秒,之后每次运行耗时不到 5 秒。
仓库链接:GitHub - gupsammy/Claudest: A highly opinionated plugin marketplace for augmenting your Claude Code. Battle-tested skills and tools that actually work. · GitHub
Token洞察技能为/get-token-insights, 作为claude-memory插件的一部分,安装只需要:
/plugin marketplace add gupsammy/claudest
/plugin install claude-memory@claudest
首次运行大约需要 100 秒,之后递增运行。会在浏览器中打开一个交互式仪表板。
我提到的内存帖子: https://www.reddit.com/r/ClaudeCode/comments/1r1w397/comment/odt85ev/
缓存警告钩子是我个人配置的,尚未发布。如果有人需要,我会把它们添加到插件里。我很乐意回答关于数据或实现方面的问题。
值得注意的是以下局限性:
-
JSONL 解析依赖于 Claude Code 的本地文件格式,而该格式并未正式记录。目前该解析方法在当前格式下可以正常工作,但如果 Anthropic 更改了格式,则可能会失效。
-
美元估算采用已公布的 API 定价(Opus 4.6:输入 5 美元/MTok,输出 25 美元/MTok,缓存读取 0.50 美元/MTok)。订阅计划与 API 成本并非一一对应。重要的是相对浪费排名,而不是绝对的美元数字。
-
“浪费”是因人而异的。有些缓存重建是不可避免的(比如你得吃午饭)。关键在于让浪费可见,而不是完全消除。
还有一点。这个审计工具并非只对 Claude Code 用户有用。如果您使用 Claude Code SDK 进行开发,这项技能可以直接对代理会话进行可观测性分析。其底层方法(解析 JSONL 转录、加载到 SQLite、提取模式)也适用于大多数 CLI 编码代理。它们的底层工作原理大致相同。只要代理写入原始会话文件,您就可以观察到相同的冗余模式。我为 Claude Code 开发了这个工具,因为我自己也在使用它,但其架构可以移植。
如果你发现自己的极限消耗速度比预期更快,却不知道原因,那么这些数据可以让你了解实际情况。
译者总结的最佳实践
为了避免Claude的token浪费,以下是根据这篇reddit帖子和我个人使用经历总结的一些方法:
- 在后续对话几乎不会用到先前对话内容时,不要继续对话,而是用
/clear开启新对话。 - 一劳永逸地让Claude对每一轮都一定会被加入上下文的
CLAUDE.md和规则文件进行简化。很多时候自己写的CLAUDE.md规则都很冗余,但模型可能能用50%的Token表达同样的意思。 - 卸载掉不会用到的Skill/MCP/Plugin。对于只会在某个项目里用到的Skill/MCP/Plugin,把它们安装在项目目录下,不要安装在根目录下。
- 采用lazy load。对于很繁杂的记忆文件和规则/skill定义,把具体记忆/定义内容拆散在不同文件里,而在Claude一定会读的文件里只包含拆散的文件路径字符串,让CC只在需要使用某个记忆/某项技能的时候再去读对应文件。同时,在
settings.json里设置"ENABLE_TOOL_SEARCH": "true"环境变量。 - 尽可能不要复用超长又Cache过期的对话。在对这种对话新增输入之前,要掂量清楚自己这一轮对话重写Cache的开销。
- 当模型某项操作失败(比如没能达成目标或者对输入理解有误的时候),尤其是在Cache已过期或者模型上一轮做了大量输出的时候,不要新开一轮对话纠正,而是按两次esc回退到上一轮对话的状态修改自己上一轮的输入,这样能在纠正模型行为的同时省去一整轮输入输出的上下文请求。
- 在能用子agent的时候就用子agent。子agent会fork先前上下文做并行操作,这样不仅能最大程度复用Cache,持续刷新Cache TTL时间,还不会大幅影响主agent的上下文。这样主agent的后续操作就能更加节省。
- 采用适当的记忆机制。当之前轮次的某个操作会在未来节省token(比如庞大目录的文件树,debug频繁踩的坑,或者分析出某个文件反复读取背后的原因),让claude第一时间把它们记在记忆文件里供后续会话参考。
- 在
CLAUDE.md里鼓励模型使用能节省token的工具。例如,能用内置的Read/Grep/Glob就不要用命令行,以及如果配置了serena的话,能用serena就不要完整读取文件。 - 利用git历史作为记忆的一部分。在每次做完一件事之后,都在
git commit里写清楚修改了什么,这样当CC读取git历史的时候自然就知道每个文件都做了什么。 - 在一开始的输入里包含尽可能清晰的计划,或者让Claude自己用planning mode/superpowers做好计划再执行。对于不清晰的请求做反复修改是最耗费token的。
这篇帖子用来抛砖引玉,求各位佬友批评指正,也欢迎大家分享自己的心得
网友解答:--【壹】--:
总结的内容就不少啊,我记得有些 github 项目可以实现 token 节省
--【贰】--:
不要怕,做个备份改了试试,如果变差了再改回来
--【叁】--:
这个文章看了,但是还是没提为何之前token消耗没事,现在token消耗突然变大了,以前这些加载,命中什么的也是这样啊,现在突然变高了
--【肆】--:
问题是max默认是1H缓存,但是我max消耗也是异常快。而且说是2.1.87(具体忘了)版本已经改过来了,我升级了版本但是消耗还是快。所以缓存感觉不治本。
上下文窗口我也调到200K了,目前试验也还是快。
--【伍】--:
如果是跟cache有关的就不会有任何效果的影响,其他的得在自己的使用场景里实验验证了。不过我自己这边体感倒是前后没什么效果影响
--【陆】--:
是的,其实我体感也是这样,所以就更显得省token重要了,能省一点是一点…
--【柒】--:
感谢分享。对于我来说,最重要的就是
绪里:很多时候自己写的
CLAUDE.md规则都很冗余,但模型可能能用50%的Token表达同样的意思。
有点好奇,这么多措施,有没有可能,为了节省 token 导致模型效果变差?
--【捌】--:
在此,也推荐下 opencode+DCP 的组合,个人觉得是 agent 工程化的一个很好示例。
--【玖】--:
佬 max 不一定是1h缓存,之前用cc读过代码,有个变量受a控制,这个变量决定了是否启用1h,不同账号可能不同。我通过解析json得到我的号默认是5m。我的版本是1.77。(当然用patch可以硬开1h)
--【拾】--: 利陆都2253:
感谢分享。
感谢分享。
--【拾壹】--:
这个有人说是前几次更新的缓存机制出bug了,最新的改了,也有人说是因为前一段时间有2x活动现在没了,但确实不知道是咋回事
--【拾贰】--:
学习一下,感谢大佬
--【拾叁】--:
你真棒
--【拾肆】--:
是啊,很多东西现在都很好改,就怕给 AI 这个黑盒引入更多变量,效果反而变差
--【拾伍】--:
学到了,分享下我自己在使用中,一般会 分析 存文档 clear 优化文档 clear 优化文档 clear 优化文档 clear Coding。。 这样反复优化文档,可以优化轮数10次以上,0用opus来不断反复。然后coding用sonnet。
优化文档就是文opus:有什么建议可以改进这种设计吗?
--【拾陆】--: 绪里:
对于不清晰的请求做反复修改是最耗费token的
写好prompt确实很重要
--【拾柒】--:
前阵子对 Clauce Code 的请求做过一下抓包,确实,他每次请求都会携带大量 System Prompt 和 Tools Description ,这东西还是停费token的。
--【拾捌】--:
这样。。。细说,怎么看自己是不是5m还是1h,还真有可能,我是max5,不是20
--【拾玖】--:
省token好文,今天就让CC按这个文章,帮我自动配置

![[转载+总结] Claude Code最大化使用量+避免Token浪费的最佳实践](/imgrand/WkGf5hN8.webp)