输入和输出令牌
一次请求在GPU上分两个阶段处理,且两阶段的成本不同。
首先,在预填充阶段,模型会读取你的请求和上下文:系统提示、你的CLAUDE.md文件、你的消息,以及自会话开始以来添加的所有内容(Claude读取的文件和它执行命令的输出)。这些都是你的输入令牌。
然后,在解码阶段,模型生成输出令牌:它的思考过程、调用的工具以及你看到的文本。输出是逐个令牌生成的;比如200个令牌的回复就是模型连续运行200次。每个输出令牌的解码阶段会让GPU持续工作更长时间,因此输出令牌的价格大约是输入令牌的5倍。

会话中的许多输出令牌是“思考令牌”,模型每轮思考的深度由“努力等级”控制。你通过/effort命令选择的等级会作为下次会话的默认设置。
提示: 在新会话中运行一次
/model和/effort,查看当前设置。两者都会记住你上次的选择,确保你的决定是有意识的。
提示: 如果你知道某次会话只是简单重复工作,可以设置
MAX_THINKING_TOKENS=0来关闭思考(Fable 5除外),这比设置/effort low更节省资源。
提示缓存
如果请求的开头令牌与服务器刚处理过的请求完全相同,服务器会复用之前的状态,只需预填充新增部分,这就是提示缓存。
从缓存读取的成本是输入价格的0.1倍,因为服务器直接加载状态而非重新计算。写入缓存的成本略高,最多是正常输入的2倍,因为服务器还要保存状态。但写入只发生一次,后续每轮读取都很便宜。
Claude Code会自动管理提示缓存,无需手动开启。但某些操作会破坏缓存,导致成本激增,了解如何避免很重要。
举例说明:
- 当你输入“修复
utils.test.ts中的失败测试”时,Claude Code会将系统提示(含工具定义)、CLAUDE.md和消息组合成请求发送。此时缓存为空,全部内容都要预填充并写入缓存。 - 模型无法修复未见过的测试文件,它会先思考并发出读取
utils.test.ts的请求(输出令牌)。Claude Code读取该文件,追加到对话中,再次发送完整请求。此时请求1的内容从缓存读取,成本仅为十分之一,只有新增的读取请求和文件内容按全价预填充。 - 模型接着请求被测试文件(输出),又一次读取、追加并发送,前两次请求从缓存读取,新增文件全价预填充。
- 模型发出编辑指令(输出),Claude Code应用编辑,追加结果并发送,新增编辑及结果全价预填充,之前内容缓存读取。
- 模型运行
npm test(输出),追加测试输出并发送,只有测试输出是新增内容。 - 测试通过,模型给出简短总结(输出),无工具调用,无需追加,结束。
这五次请求中,每次都包含了之前所有对话内容。通常输入令牌数远大于输出令牌数,但只有本轮新增内容按全价计费。
这同样适用于订阅用户,虽然你看不到具体价格,但这些请求会消耗你的额度。
缓存匹配必须从请求开头开始,且请求顺序固定:工具定义、系统提示、对话(CLAUDE.md在最前)。
任何前缀变化都会导致后续内容重新预填充。理想情况是工具结果追加在对话末尾,不影响缓存。破坏缓存的操作包括:
/model:不同模型有独立缓存,切换模型会导致整段对话重新预填充。/effort:努力等级也是缓存键的一部分,切换时同样会重新预填充。- 快速模式:也是缓存键的一部分,开启时会按快速模式价格重新预填充,建议在会话开始时开启。
/compact:会用简短对话替换当前对话,导致缓存失效。- 时间:订阅缓存1小时过期,API密钥5分钟过期,过期后下次请求需重新预填充全部内容。
这并不意味着你不该切换模型或努力等级,而是要选择合适时机,比如会话开始或刚执行/clear后切换,避免在长对话中途切换。
提示: 如果最近几轮对话不想保留,使用
/rewind回退到之前,而非/compact。回退只删除末尾几轮,缓存仍然有效且无额外成本。/compact会重写整个对话,必然产生费用。
会话发送令牌数量的决定因素
核心是:对话中出现的内容(文件、命令输出等)每轮都会重新发送,持续整个会话。
虽然缓存降低了重复发送的成本,但仍占用上下文空间,影响模型每轮的计算负担。
会话成本主要取决于上下文中令牌数量、它们存在的轮数以及同时运行的上下文数量。
上下文中包含什么
上下文中部分内容在你输入前就存在:工具定义、系统提示、CLAUDE.md和启动时加载的其他内容。
提示: 在新会话中运行
/context查看初始上下文。保持CLAUDE.md只包含具体指令,将工作流相关内容放入技能(skills),仅在使用时加载。如果有不需要的MCP服务器,用/mcp关闭。
会话中大部分新增内容是工具结果:Claude读取的文件和命令输出。
Claude读取多少文件取决于它需要自己查明多少信息。比如你说“测试失败”,它得先找出哪些测试失败,可能需要grep几次,打开几个文件,这些结果会一直保留在上下文中,直到不再有用。
如果你直接说“修复utils.test.ts中的失败测试”,就跳过了搜索,只有一次读取文件操作;如果用@utils.test.ts提及文件,甚至不需要读取调用。

提示: 提及文件时用@符号而非手动输入路径。Claude Code会在发送前自动附加文件,确保它在首个请求中出现,无需额外读取调用。文件内容占用上下文空间相同,@提及只需一次,重复提及会附加副本。
命令输出也是上下文的重要组成部分。每次运行测试、构建或git日志,输出都会追加到对话中,持续存在相同轮数。
超大输出会被写入文件,只在对话中保留简短预览和路径(可通过BASH_MAX_OUTPUT_LENGTH调整)。
问题是中等大小输出,比如400行测试通过的日志,会一直占据上下文,增加成本。
Claude通常会用参数和tail命令帮你过滤输出,如果不想依赖它,可以在文档中设置钩子,预先重写命令,只返回重要行。
提示: 把你常用的两三条命令(含静默参数)写进
CLAUDE.md,例如“用npx vitest run --reporter=dot运行单个测试文件”。这小小的改动能节省每次会话几百行输出和一次请求。
上下文保留时间
一次长会话比多个短会话成本高得多,因为第40轮还要重新读取前39轮内容。保持上下文简短且相关,避免将一个任务的上下文带入下一个任务:开始新任务时用/clear,任务早期完成时用/compact。

提示: 如果想保留会话,先用
/rename改名再/clear。/compact时告诉它保留哪些内容,或者在CLAUDE.md里写“Compact instructions”部分。如果你用的是1M模型,想恢复自动压缩保护,运行/autocompact 200k(需要Claude Code v2.1.221+)。
注意自动执行的轮次,比如/loop命令会在设置的会话中持续执行,每次都带着整个上下文。如果超过一小时没操作,缓存失效,成本更高。建议在新终端开启新会话运行循环。
子代理(Subagents)
另一种减少上下文负担的方法是使用子代理。子代理拥有独立上下文窗口,包括系统提示、工具和CLAUDE.md,但不包含主会话对话内容。它独立运行轮次,完成后只返回答案,其他内容丢弃。
缺点是子代理可能需要重新读取主会话已有内容,且自己承担轮次成本。对于小任务是额外开销。
但处理大量不需保留的输出时很划算,比如分析日志。Claude通常会自动调用子代理,你也可以直接请求(“用子代理分析这个日志”)。主会话只收到子代理选择报告的结果。

提示: 如果有重复交给子代理处理的嘈杂任务,给它单独定义一个子代理,使用
model: haiku或sonnet,否则它会用主会话模型。
优先关注的四个方面
以上内容中,以下四点最值得关注,按成本大小排序:



