省 token 不在键盘上:你删的那几个「请」字占账单不到 3%,真正的开关在系统层那 97%
2026-06-14
本文适合:① 每天用 Claude Code、好奇它后台怎么烧 token 的人;② 看着 usage 飙到 90% 想把账单压下来、却只会删字的工程师;③ 想知道「prompt caching / compaction / sub-agent / progressive disclosure」这四招到底各省多少、各坑在哪的开发者。
我做数据架构,平时跟物化视图、定期归档、外部表打交道。所以盯着 Claude Code 的 usage 账单发愁、想砍 token 的时候,我第一反应不是「我哪句话说多了」,而是「这一轮被反复扫描的热数据到底是哪一块」。这篇就用数据架构师 × AI 工程师这个视角,把省 token 这件事拆给你看。
先把结论放最前面:省 token 的真正杠杆根本不在键盘上。S02 把一次真实会话的账单拆开,我自己都愣住了——我亲手敲进去的字,在 usage 里占比不到 3%;剩下 97% 全是系统自动搬运的历史上下文、重复加载的 tool 定义、每轮重塞一遍的 system prompt。你在输入框里抠「请」字、把「详细解释」改成「简述」,省的是小数点后那几个零,真正的开关在那 97% 上。能拧动这 97%、又不靠少打字的办法,统共只有四招,只有一招是无脑省的。
删字党的幻觉:你抠输入框抠了半年,省的全是四舍五入进不去的零
一句话:删字省下的 token,在每轮几万 token 的账单面前连尾差都算不上,系统搬运的成本量级压根不在你这一侧。
写过半年 Claude Code 的人,谁没在 prompt 里删过几个「请」字。这是最直觉、也最没用的优化。把账拆开看就明白:
- 你打的字:一句指令几十到一两百 token,占整轮账单不到 3%。
- 系统搬运的:历史上下文每轮全量重发、tool 定义每轮重新加载、system prompt 每次重塞——动辄几万 token,是账单的绝对主体。
删字省下的那几十 token,丢进每轮几万 token 的盘子里,连四舍五入都进不去。这就是为什么很多人「明明很克制地说话」,usage 还是照样飙到 90%——优化错了对象。
省 token 的真正杠杆不在键盘上,在系统层。usage 飙到 90% 时,你手里握着 4 个不靠少打字的办法。它们各自独立生效,底层逻辑却是同一件事:减少被重复运输的历史的体积或频率。下面一个一个拆清楚。
四招分两类:T1/T4 减频率减常驻,T2/T3 减体积——而只有 T1 是无脑省
一句话:把四招按「动的是频率还是体积」分两对,再记住「除 T1 外其余三招都带 trade-off」,你就拿到了选招的判断框架。
先记结构再看细节:
- T1 Prompt Caching + T4 Progressive Disclosure = 减频率 / 减常驻:不删内容,但让稳定的部分别每轮重算、别一上来就全量塞进去。
- T2 Context Compaction + T3 Sub-agent = 减体积:真的把历史压小、或把过程上下文挪到别处。
S02 末尾我下过一个判断:省 token 说到底只有两个旋钮——命中率和增量大小。这四招就是拧这两个旋钮的四把扳手。还有一个容易被忽略的共同点得先敲在前面:除了 T1,其余三招都带 trade-off,用错场景会反贵。所以下面每一招我都把「代价」和「省」一起写,谁也别想无脑全开。
T1 Prompt Caching:四招里唯一「设完就忘」的性价比之王
这是四招里最像白捡的。Claude 的 prompt caching 很直接:把 system prompt、tools 定义、对话前缀打上 cache_control 标记,API 层在服务端缓存它们。后续请求只要前缀没变,命中的部分只按 0.1× 单价计费。
算一笔账。假设你的 system prompt 加 tools 定义 200K token,不命中按 200K × 1× 收费,命中后按 200K × 0.1× 收费,省 180K 输入成本。典型对话里 input 开销能降 70%,命中率稳定在 70% 以上,前提是你守规则。
代价有两个:
- TTL 只有 5 分钟。你切了话题、改了一行 system prompt、甚至只是重新加载了工具列表,前缀一变就 cache miss,下轮全额收费。
- 长会话窗口不够用。写代码写到一半去查文档,回来缓存已过期。
实操就一条习惯:5 分钟内不切话题。长会话(比如持续 1 小时的代码审查)可以用 1 小时 TTL 的 cache 档位——写入贵一些(2× 单价)换来 12 倍的存活时间,很划算。几乎不用改行为、自动生效,这是四招里唯一一个「设完就忘」的。
体会一下它的脾气。你调一个 bug 连敲 20 分钟、每轮间隔两三分钟,cache 一直热着,30 轮下来大概只付一两轮全价,其余全是 0.1× 折扣价。可中途被叫去开了个 8 分钟的会,回来再敲一句,TTL 已过、前缀整段失效,这一轮要重新写 cache、按 1.25× 全额付一次,前面攒的便宜吐回去一大截。同样 30 轮,「连续敲」和「走走停停」的账单能差三五倍。T1 不用改代码,只改习惯:把同一个任务连续做完,别让它在时间上碎成一段段。
T2 Context Compaction:这是投资不是省钱,回收期不够就纯亏
T1 是纯收益,从 T2 开始有 trade-off。Context compaction 的逻辑很直观:历史上下文体积超过阈值时,调一次 LLM 把历史压成摘要替换原始内容。保留 system prompt、最近几轮对话、加上这段摘要,其余全丢。
效果:30K 历史 → 2K 摘要,后续每轮省约 28K 输入。假设一轮历史涨 5K,本来每轮付 5K 增量 + 30K 历史,现在只付 5K 增量 + 2K 摘要,每轮省 28K。
代价有三:
- cache 失效。压缩后上下文变成新前缀,旧前缀全废,下一轮 cache miss。
- 细节丢失。摘要留不住所有信息——你讨论过的某个变量名、某段报错的具体行号,都可能在压缩时被丢掉。
- 频繁触发反而更贵。每 2 轮就 compact 一次,压缩本身的 LLM 调用加上 cache miss 损失,可能比不压还贵。
实操建议:阈值放高到 75%+。上下文窗口 100K,就等实际占用到 75K 以上再触发,这样一次压缩能喂饱后续 10-15 轮,把压缩成本摊薄。
盈亏账直觉上是这样:触发一次 compaction 先付两笔「开办费」——一笔写摘要的 LLM 调用(读一遍长历史、写一段摘要),一笔 cache 失效(摘要成了新前缀,旧 cache 全废、下轮重写),两笔加起来可能小几万 token。之后每轮历史从 30K 缩到 2K、省约 28K,得靠后面足够多轮把开办费赚回来。你要是刚 compact 完就切话题、或只剩两三轮就收工,开办费根本没摊开,纯亏。一句话:compaction 是投资不是省钱,得有足够长的回收期才划算——这也是阈值要放高的原因,让每次压缩都「压一次管很久」。
T3 Sub-agent:把脏活隔离出去,但 cold 首派会反贵 +108%
Sub-agent 是四招里最有架构感的。思路很简单:把需要大量上下文、多轮探索的任务丢给一个独立 agent 进程去跑。子 agent 有自己的 messages 列表,在里面跑 N 轮,最后只回吐一个 final_result 字符串给父 agent。过程上下文全留在子侧,父 agent 的 context 里只多了一行结果。
省多少?warm 场景下子 agent 重派能省 45%,父 agent 不用再为子任务的上下文付费。但必须如实写一个实测修正:cold 首派反贵 +108%。子 agent 第一次启动要加载全套 system prompt、工具定义、skill 列表,这些全是额外开销。子任务只跑一次就结束的话,用 sub-agent 反而比直接在父 agent 里跑贵一倍。
适合:大量探索性 grep(grep × N 次文件搜索)、长 dump 日志分析、写文档——特点是「过程长但结果短」,子 agent 跑 20 轮搜索最后只输出 3 行结论。不适合:需要持续对话的任务,比如让子 agent 做代码审查再连续追问,每次 fork 都是 cold start,每次多付 108% overhead。
给一个能直接套的口诀:过程重、结果轻、一次性,就派;过程轻、要反复对话,就别派。「过程重结果轻」是子任务内部翻几十个文件、跑一长串命令,你最后只要一句结论——这种最值,那几十个文件的 token 全留在子 agent 里、没污染主上下文。反过来要基于子 agent 产出连续追问五六轮,本质是「需要持续对话」,+108% 叠几轮,比你自己慢慢做还贵。还有个更隐蔽的坑——连续派同类子任务:5 分钟内第二次派同类活,子 agent 的 system 前缀还在 cache 里、是 warm 的 −45%;隔了十分钟才派第二个,又冷了。所以 sub-agent 省不省,跟 T1 一样,也看你连不连续。
T4 Progressive Disclosure:能力的目录与正文分离,SKILL.md 超 2KB 就在收税
这是四招里最需要设计功夫的。Progressive disclosure 的核心是把能力定义拆成「目录」和「正文」两层:所有 skill 常驻在父 agent 上下文里的,只有约 100 字 description,相当于一个目录条目;skill 被触发时才加载完整正文(具体实现、代码示例、reference 文档)。
省多少?假设你有 30 个 skill,每个完整定义约 1.7K token,全量挂载 = 30 × 1.7K = ~51K。用 progressive disclosure 后,常驻只有 30 × 100 = ~3K metadata,省 48K,约 94%。
三阶段:discover(父 agent 按 description 决定是否触发某 skill)→ inject(向子 agent 或当前上下文注入 skill 正文)→ on-demand(按需加载 references,比如某 skill 依赖的 API 文档只在需要时读)。
设计原则:SKILL.md 要短,只写目录和流程,比如「该 skill 用于分析 MySQL 慢查询日志,流程:读日志 → 提取 TOP 10 → 归类 → 输出建议」;references 要重,具体实现、代码模板、文档链接全丢进 references 按需加载。
一个简单自检:写完一个 skill,看它的 SKILL.md 有多大。超过 2KB,基本可以断定你把本该放进 references 的东西塞进了目录——它现在每个 session 都常驻在你的上下文里收税。把代码模板、长示例、API 文档挪到 references,SKILL.md 只留「这个 skill 干嘛、什么时候用、分几步」,常驻体积能砍掉一大半。Anthropic 的工程博客把这套思路叫「无限技能 + 有限上下文」:技能可以无限多,但靠 description 当目录、按需加载正文,才不会撑爆那块有限的上下文。

(图 3.1)四招的机制、省多少、代价一览。记一个结论:除了 T1,其余三招都带红色「代价」标签——不是无脑省,是看场景省。
数据架构师视角:四招都是数仓老把式,先找热数据再下手
一句话:把 T1-T4 映射回数仓优化,会发现它们是同四个你早就用熟的动作——真正可迁移的,是「先定位每轮被重扫的热数据,再选扳手」这个习惯。
我做数据架构,看这套东西眼熟得很,几乎一一对应:
- T1 Prompt Caching = 物化视图。算过一次的大查询,物化视图把结果存起来、相同查询直接读缓存。system prompt 和 tools 定义就是一次写入、多次读取的热数据,缓存它天经地义。
- T2 Context Compaction = 定期归档汇总。每天把明细聚合成日汇总、丢弃原始明细;T2 把历史对话压成摘要、丢弃原始轮次。都是拿一次聚合成本换后续查询的低成本。
- T3 Sub-agent = 把大查询丢给独立作业进程。复杂 ETL 不在主查询线程里做,而是起一个独立作业进程跑完写回表。Sub-agent 一样:脏活隔离出去,父进程只关心结果。
- T4 Progressive Disclosure = 外部表按需加载。数仓不把所有表都加载进内存,而是用外部表、查询命中时才读底层文件。T4 的 skill 目录与正文分离,就是外部表的 lazy load。
四招共同的底层动作是同一个:控制「热数据」的体积。热数据是每次查询都要扫描的部分——cache 的前缀、compaction 后的摘要、sub-agent 的 final_result、skill 的 description。热数据越小,每轮对话的固定开销越低。这跟数仓优化的核心原则一样:减少每次查询扫描的数据量,比优化单次查询效率更值得投入。
这个映射不只是类比好玩,它给你一个能搬走的判断框架:想省 token,先问「现在每轮被反复扫描的热数据是哪一块」,再问「这一招是把它缓存住、压小、挪走、还是延迟加载」。做过数仓调优的人对这套特别熟——你不会去抠某条 SQL 的写法,而是先看哪张大表被全表扫了,再建物化视图、做分区、上列存。省 token 同理。工具会换、机制会变,但「先找热数据再下手」这个习惯能一直用下去。
收口 + 下集钩子
回到 One Big Idea:这四招看着各管各的,本质都在动同一件事——减少被重复运输的历史的体积或频率。T1 缓存前缀减重复运输次数,T2 压缩历史减体积,T3 隔离脏活减父 context 体积,T4 按需加载减常驻体积。四招叠加,理论上能把一个长任务的 input 开销压掉一大截。
但要泼一盆冷水:四招里只有 T1 是「装了就一直省」,其余三招都得挑场景,用错了全是反向收费——T2 在短会话里纯亏,T3 在一次性任务上 +108%,T4 你把 SKILL.md 写成 5KB 反而更占。别想着「全开 = 省最多」,那恰恰是下一篇要专门拆的一次真实翻车:四个工具一起开,实测只省了 1%。省 token 的功夫从来不是堆招式,是看准瓶颈在哪、用对那一两招。
撂一个可以打脸、带时间窗的判断:未来 12 个月,Claude Code 这类 Agent 工具会把 T1/T4 这种「无脑省 / 设计期一次性配好」的能力做成默认开箱即用,而把 T2/T3 这种带 trade-off 的招式越来越多地交给运行时自动判断场景。需要你手动「挑场景用对扳手」的空间会持续收窄。这事我赌得挺死:就像当年数据库从手动建索引走到查询优化器自动选执行计划,带副作用的优化最终都会被沉到引擎里。
下集预告:S04 讲剩下三招——grep > read(用 grep 替代全量 read 减少文件加载)、模型路由(简单任务走小模型、复杂任务走大模型)、/clear(手动清理历史上下文),再加一张 usage 90% 决策树,帮你决定什么时候该用哪一招。
互动题:这 4 招里,哪个你已经在用却不知道它在省钱?我猜多半是 T1——它自动生效,你根本意识不到自己在用,直到某次走神回来发现这一轮突然贵了一截。评论区说说你的实测命中率,还有你踩过哪一招的反贵坑,我挑几个典型的下一篇回应。
本系列每周两更,跟着拆完,你会对每一次回车背后的开销心里有数。卡在哪,评论区告诉我。
我是做数据架构的,在公众号「炼丹炉手记」用工程师的较真劲儿实测 AI 工具的真实 ROI——真省钱、真赚钱,还是智商税。工程拆解之外的,都在那边。
本文为 AI 辅助创作。
本文首发于知乎:阅读知乎原文 →