上周 Anthropic 官方博客发了一篇很少见的"讲成本机制"的文章 ——《Maximizing the value of your Claude Code sessions》。
不是安利新功能,也不是发布会通稿,而是老老实实地告诉你:同样一个任务,不同的用法,花的钱可能差好几倍。这在过去的开发工具里是不存在的——你的 IDE 不会因为你今天多写了几行代码就多收钱,但 Agentic 编程工具会。
先搞懂一件事:省 token ≠ 少用 token
Anthropic 在文章里提到了一个很重要的观点:
高效使用 token,不意味着减少 token 数量,而是确保每一个 token 都服务于真正的任务。
翻译过来就是:不是让你抠门,而是别让 token 花在你没要求它做的事情上。
同样修复一个失败的测试,Claude 可能三两下就读完对应文件改完了;也可能先满仓库 grep 一遍,顺手读了十几个不相关的文件——这些文件读进去之后,接下来的每一轮对话都要重新带着它们,模型也要多花精力"绕开"这堆无关信息去思考。
结果就是:同一个 bug,同一个修复方案,账单可能差出几倍。
决定单个 token 价格的三件事
1. 模型大小
模型越大,单 token 越贵,这个很好理解。原文的建议很实在:问题真的复杂、含糊不清的时候上大模型,routine 的活儿用小模型。这个系数会乘在下面所有因素上,所以模型选错了,后面怎么优化都事倍功半。
2. 输入 vs 输出
请求分两个阶段:
- Prefill(预填充):模型读你的输入(system prompt、CLAUDE.md、对话历史),这是输入 token。
- Decode(解码):模型一个 token 一个 token 地往外吐,包括 thinking、工具调用、最终文字回复,这是输出 token。
关键点:输出比输入贵大约 5 倍,因为解码是逐 token 串行生成的,占用 GPU 时间更长。而 thinking token 也算输出,它的用量由 /effort 等级控制。
💡 小技巧:如果你确定这一轮是纯体力活,不需要模型"想",可以用
MAX_THINKING_TOKENS=0 claude直接关掉 thinking(比/effort low还低一档,Fable 5 除外)。
3. 有没有命中 Prompt Cache —— 这是最容易被忽视的一项
这是 Claude Code 成本机制里最关键的一点。
如果一个新请求的开头和上一次请求完全一致,服务器就能直接复用之前算好的状态,只需要重新计算"新增的那部分"。这就是 prompt caching。
- 缓存命中(读):只要正常输入价格的 0.1 倍
- 缓存写入:比正常输入贵,最多到 2 倍(但只发生一次)
Claude Code 自动帮你管理缓存,不用手动开。但有些操作会直接打穿缓存,一旦打穿,后面整段对话都要按全价重新预填充一遍:
| 操作 | 是否打破缓存 |
|---|---|
/model 切换模型 |
✅ 打破(每个模型有独立缓存) |
/effort 切换等级 |
✅ 打破(effort 也是缓存 key 的一部分) |
| Fast mode 开启 | ✅ 打破(按 fast mode 价格重新预填充) |
/compact |
✅ 打破(对话被替换,但 system prompt 前缀不受影响) |
| 超过 1 小时无操作(订阅版) | ✅ 打破(API key 默认 5 分钟,可用 ENABLE_PROMPT_CACHING_1H=1 延长到 1 小时) |
| Resume 旧会话 | ✅ 基本必破(缓存早就过期,而且系统提示词会重新构建) |
结论很直接:model 和 effort 要在会话开始或刚 /clear 完的时候定好,不要中途改。
还有一个容易被忽略的细节:如果最近几轮跑偏了,别急着 /compact,先试试 /rewind ——它只是把这几轮从对话末尾切掉,前面的内容依然在缓存里,不产生任何额外费用;而 /compact 是重写整段对话,一定会花钱(只是趁着还在缓存期做会便宜很多)。
决定一次会话总共花多少 token
搞懂了单个 token 的价格,第二个问题是:一次会话到底往上下文里塞了多少东西。
有个容易被忽略的事实:上下文里的任何东西,一旦进去,后面每一轮都要重新带上它——哪怕是缓存读取,便宜是便宜,但也不是零,而且会占用模型"思考"的空间。
实操清单(这部分是重点,建议直接抄作业)
① 用 @文件名 而不是直接打路径
# 不推荐
帮我修一下 utils.test.ts 里失败的测试
# 推荐
帮我修一下 @utils.test.ts 里失败的测试
@ 引用会让文件直接附到你这条消息里,省掉一次 Read 调用(甚至一次搜索)。注意:同一个文件同一次对话里 @ 一次就够了,它会一直留在上下文里,重复 @ 相当于塞进第二份拷贝。
② 给"吵闹"的命令加静音参数
命令输出会像文件一样永久追加进对话。跑测试打印 400 行 PASS,这 400 行会在接下来所有轮次里反复被重新发送。
# CLAUDE.md 里直接写清楚怎么跑
运行单个测试文件用: npx vitest run <file> --reporter=dot
超过 30000 字符的输出,Claude Code 会自动写文件、只留预览(可用 BASH_MAX_OUTPUT_LENGTH 调整阈值),但阈值以下的中等噪音输出没人帮你处理,得自己加 flag 或者交给子代理。
③ 新会话先跑一次 /context
看看开局默认加载了什么(CLAUDE.md、MCP 工具定义等),该砍的砍:
- CLAUDE.md 只留具体指令,workflow 类的东西挪到 skills 里(按需加载,不占常驻上下文)
- 这个会话用不到的 MCP server,
/mcp里直接关掉
④ 任务切换就 /clear,任务内部阶段性完成就 /compact
一次长会话比拆成几次短会话贵得多,因为第 40 轮也要重新"背"前面 39 轮的内容。
# 想保留会话以后再回来?
/rename # 先改个名字方便找
/clear # 再清空
/compact 时记得告诉它要保留什么,或者在 CLAUDE.md 里固定一段 “Compact instructions”。
⑤ 警惕看不见的"隐形轮次"
/loop 每次触发都是一次完整的对话轮次,会拖着整段历史一起跑,如果超过 1 小时还会顺带撞上缓存过期。建议开个新终端单独跑 loop,别塞进主会话。
⑥ 大量输出、用完即丢的活儿,交给子代理
子代理有自己独立的上下文窗口(带 system prompt、工具、CLAUDE.md,但不带你的主对话),跑完只把结论带回来,过程全部丢弃。适合"翻日志"这类会产生大量垃圾输出的任务:
帮我用子代理去翻一下这份日志,找出报错的堆栈
缺点是子代理拿不到主会话已经读过的东西,可能要重新读一遍,小任务用子代理反而是净亏。如果某个吵闹任务你天天在跑,干脆给它建一个专属子代理定义,model: haiku 或 sonnet,别让它跟着主会话用大模型烧钱。
一张图记住优先级
按对成本影响从大到小排:
- 模型选择 —— 系数级影响,选错了后面全白搭
- 会话时长 / 是否及时
/clear—— 上下文越滚越大,每轮都在重复付费 - 中途切换 model / effort —— 直接打穿缓存,全量重新预填充
- 命令输出是否静音 —— 决定了上下文里"垃圾"的密度
写在最后
这篇文章传递了一个更大的信号:Agentic 工具的成本模型,本质上是"上下文经济学"——不是省着用,而是清楚知道什么东西该留在上下文里、留多久、什么时候该换个干净的房间重新开始。
理解这套机制之后,你会发现很多"莫名其妙很贵"的会话,根源往往就是:中途换了模型、开了一堆不必要的 MCP、或者一个长会话从早跑到晚忘了 /clear。
原文附了官方的 5 分钟阅读版,建议直接看一遍原文加深理解: 👉 https://claude.com/blog/maximizing-the-value-of-your-claude-code-sessions
关于
关注我获取更多资讯