← 返回全部文章
Analysis · 2026年9月6日 · 9 分钟阅读

复现 Spotify 省下 90% token 的方法:真正重要的数字为什么是 350 行

文件大过摘要,委托读取就开始省 token。我们的数据说,大约 90 行已经过线,但这时动手仍是个坏主意:每次委托要等约 20 秒,而 87 行只省 165 token。下面把这条曲线摊开,看看 Spotify 那个看似保守的 350 行默认值为什么其实定得正好。

30 秒版

2026 年 9 月 4 日,Spotify 工程师 Dimitri Mazmanov 发布了一篇文章,标题里的数字很快传开:Portal 让他的 Claude Code token 用量下降了 90%。文章登上 Hacker News 首页,拿到 267 分和 171 条评论。

这套机制并不复杂,也不需要 Spotify 的内部平台才能照做。Claude Code 的钩子先截住文件读取。文件够大,就交给更便宜的工作模型读取,只把摘要送回。 最终进入上下文的是摘要,不是整个文件。

我们换了一套毫不相关的代码库复现。只看大文件,token 用量下降了 85.7%。这个结果和 90% 足够接近,Spotify 的结论站得住。

不过,那篇文章里最没用的数字恰恰是 90%。真正值得盯住的是 350,也就是工具默认开始委托读取的行数。我们的实测显示,只算 token,盈亏临界点大约在 90 行,足足低了四倍。为什么不能在 90 行就开始委托?答案不在 token 里,而在每次要多等的那 20 秒里。

Portal 到底做了什么

Portal 是 Spotify 的内部平台,没有开源。外部用户真正能复用的部分叫 Shunt,原作者对它的描述很直接:

Claude Code 的钩子会在每次工具调用前触发,Shunt 注册了两个 PreToolUse 钩子(原文:“Claude Code hooks fire before every tool call. Shunt registers two PreToolUse hooks.”)

Claude 准备读文件时,钩子先检查行数。原文写道:文件超过可配置的行数阈值时,钩子会阻止这次读取,默认阈值是 350 行(原文:“If the file exceeds a configurable line threshold (default: 350), the hook blocks the read…”)。随后,读取任务会交给更便宜的工作模型。文中的示例使用 Gemini 2.5 Flash,它读完文件后返回摘要。

真正起作用的几块都不是 Spotify 专属能力。PreToolUse 钩子Claude Code 的公开功能。更便宜的工作模型可以是任何能从命令行调用的模型,摘要也只是普通的工具输出。如果你想过先让子代理消化文件,再把结果交给主模型,这里做的是同一件事,只不过由钩子自动决定什么时候走这条路。

那个 90% 衡量了什么

这个数字传播得比它的适用条件远,所以先把原作者测的东西说清楚:

测试对象是一个 Java 单体仓库(monorepo),覆盖四种场景。比较的是 Claude 直接读取文件会消耗多少 token,以及 Claude 接收批量读取器的摘要或由代码编写器写代码时会消耗多少 token。批量读取平均省下约 90%(原文:“Tested against a Java monorepo across four scenarios, measuring tokens Claude would consume reading files directly vs. consuming the bulk-reader’s summary or writing code via the code-writer. Mean bulk-read savings were around a whopping 90%.”)

也就是说,它测了一个 Java monorepo、四种场景,比较直接读取与摘要进入上下文的成本。90% 是批量读取的平均节省,不是任何人的总账单都会少 90%。这个数字证明了一件事:面对本来就适合委托的大文件,摘要的 token 成本大约只有直接读取的十分之一。

它没有回答另一件更要紧的事:你自己的 token 用量里,大文件读取究竟占多少。只有这个比例,才能决定值不值得把整套机制接起来。

原文没有公布各场景的明细,所以来自 Spotify 的数据只有这个 90%。

我们在另一个代码库上复现了

语言换了,工作模型也换了,曲线没有变。我们从两个互不相关的项目里取了 12 个真实源文件,包括 JavaScript 和 Python,文件长度从 43 行到 678 行。工作模型使用 Claude Haiku 4.5,提示词按批量读取设计。token 数直接采用 Claude Code 报告的用量,不做估算。

方法很简单:用 claude -p --output-format json 让工作模型分别读取每个文件,再减去一次不附带文件的对照组。我们把对照组跑了两次,输入 token 都是 23,624,因此差值就是文件本身带来的用量。

文件名行数直接读取摘要省下
config.js43578644−66
check-articles.py49324610−286
http.js87917752+165
gen-llms.py1021,212799+413
identity.js1141,549983+566
validate.js1311,619858+761
verify.js1712,422938+1,484
health.js1772,625806+1,819
fetch.js2943,7101,096+2,614
views.js4709,9771,319+8,658
index.js6038,5541,384+7,170
store.js6789,0661,236+7,830

再按 Spotify 真正采用的策略算一次,只委托 350 行及以上的文件。符合条件的三个文件,直接读取合计需要 27,597 token,摘要合计只要 3,939 token,降幅是 85.7%。代码库与 Spotify 毫无关系,头条数字仍然复现了。

没人公布的那个盈亏临界点

别先看「省下」这一列,先看摘要。原文件从 324 token 增长到 9,977 token,跨度超过三十倍。摘要却始终落在 610–1,384 token 之间。文件大了三十倍,摘要几乎没怎么变长。

后面的结论都从这里开始。摘要有一个地板,也就是下限。不论文件是 40 行还是 700 行,要交代用途、导出内容和异常之处,总得花掉几百 token。委托读取并不会从零开始按比例节省。它只是用一笔大致固定的摘要成本替换原文件,只有文件本身高过这笔成本才会赚钱。

在这组数据里,盈亏临界点位于 49 与 87 行之间。再小就会倒亏。临界点以下的两个文件直接读取合计 902 token,委托后变成 1,254 token,节省率是 −39%

摘要地板由提示词决定,也是读者唯一真正能动的变量。我们的提示只要求简洁(be concise),没有设置硬性 token 上限。给工作模型一个明确的输出预算,摘要地板就会下降,盈亏临界点也会跟着下移。真要实现这套机制,顺序应该是先调摘要提示词的长度上限,再动阈值。

为什么 token 盈亏临界点是错的阈值

到这里,350 行的来由才真正清楚。只盯着 90%,会漏掉另一笔成本。

token 账能打平,不等于这次委托就没有成本。实际耗时也得算。Spotify 的实测是:每次委托都要经历一次网络往返,从 Claude Code 到 Portal 后端,再到工作模型,然后沿原路返回。响应通常需要 10–30 秒,Portal 还把单次调用上限设为 30 秒(原文:“Each delegation is a network round-trip: Claude Code to the Portal backend to the worker model and back. Responses typically take 10–30 seconds, and Portal caps a single invocation at 30 seconds.”)

我们又测了一遍最短链路。让 Claude Code 直接调用 Claude Haiku 4.5,中间没有 Portal 后端,也没有额外服务。读取那个 678 行文件,两次实际耗时分别是 19.0 秒和 20.1 秒。可见这份延迟并不是 Portal 架构独有的开销。只要另一个模型还得读文件、写摘要,这段时间就省不掉。

下面统一把每次往返按 20 秒折算,看看每秒买回了多少 token:

文件大小省下 token每省 1000 token 花的秒数
87 行165121.2
114 行56635.3
171 行1,48413.5
294 行2,6147.7
470 行8,6582.3
678 行7,8302.6

87 行时,省下 1,000 token 要付出 121.2 秒。678 行时只要 2.6 秒,效率相差 47 倍。所以 350 行不是保守估计,它是在按秒定价。走到这个文件大小附近,这笔交易才不再难看。

反直觉的结果也在这里:你越是见文件就委托,平均省下来的反而越少。 12 个文件全部委托,合计只省 73.2%。只委托大文件,反而省 85.7%。小文件不但拉低平均值,还让你白等好几次往返。

仍然不能委托的事

原作者很坦白地划出了边界。编辑和推理都不该交给这条捷径。

先说编辑。工作模型生成的摘要没有可靠行号。如果 Claude 要根据分析结果修改代码,仍然得直接读取对应片段(原文:“The worker model’s summaries don’t include reliable line numbers. If Claude needs to make edits based on the analysis, it still has to read the specific section directly.”)。一次委托读取只要最终导向编辑,这个文件就得付两遍读取成本。

再说推理。工作模型在测试里找到了表层模式,却漏掉一个隐蔽的线程安全缺陷。Claude 拿到正确上下文后,几秒内就发现了问题(原文:“The worker model found surface-level patterns but missed a subtle thread-safety bug in my testing. Claude spotted it in seconds once given the right context.”)。

第二条尤其重要。摘要是由能力更弱的模型决定如何取舍的有损压缩。被它删掉的,可能恰好就是你要找的细节。委托读取优化的只是「东西怎么进上下文」这一段,不是「这事该怎么想明白」。可以靠它判断一个文件是否相关,不能靠它断言文件没有问题。

该怎么做

  • 先确认大文件读取是不是你的成本大头。 运行 /usage,看看 token 究竟花在哪里。如果会话主要是围绕少数文件反复长聊,这套办法帮不上忙。启动开销和缓存抖动才是更大的杠杆。
  • 真要做,先把阈值放高。 350 行是按时间和 token 一起算过的默认值。因为「90 行也能省 token」就把阈值往下调,正是这组数据提醒你别踩的坑。
  • 先调摘要提示词,再动阈值。 本次实测中,最短摘要也有 610 token。这个摘要地板才是你能直接控制的项。给工作模型设置硬性 token 上限,比增加往返更便宜,也能更有效地下移盈亏临界点。
  • 老老实实把延迟算进去。 每次委托读取约 20 秒。这是每个 PreToolUse 钩子都会带来的阻塞代价,而且正好落在你等待代理完成任务的关键路径上。
  • 即将编辑的文件不要委托读取。 反正还得按原价再读一次。

真正的教训

90% 是真的。它在一套毫不相干的代码库上复现出了 85.7%,却仍是原文里最没用的数字。它衡量的,只是同一个大文件以两种方式进入上下文时的成本比。测试场景本来就挑在委托读取有效的地方。

决定这套办法对你有没有用的是阈值,而阈值根本不是一道 token 题。真正的问题是:省下来的 token,值不值得让代理停在那里等 20 秒?只算 token,约 90 行就该委托。把这 20 秒也算进去,实用阈值变成 350 行,足足高了四倍。

任何优化,只要用「被优化的那一小块省了百分之多少」来报成绩,数字都会很好看。更诚实也更有用的说法应该是:对 350 行以上的文件,先让更便宜的工作模型读取,会让你多等约 20 秒,同时省下原本要进入上下文的大部分 token。

延伸阅读

来源

  1. Spotify Engineering:Dimitri MazmanovPortal by Spotify cut my Claude Code token usage by 90%(2026 年 9 月 4 日)。关于工作机制、90%、默认 350 行阈值,以及延迟和能力边界引语的一手来源。
  2. Hacker News讨论帖(267 分,171 条评论)。
  3. Anthropic:Claude Code 钩子文档。介绍 Shunt 注册的钩子类型 PreToolUse
  4. Anthropic:Claude Code 成本与用量文档。可用 /usage 检查 token 究竟花在哪里。
  5. Anthropic:Claude Code 子代理文档。不用自定义委托钩子时的原生方案。
  6. Anthropic:模型概览。介绍我们复现实验中使用的工作模型 Claude Haiku 4.5

我们自己的测量方法已在上文完整说明:12 个文件,以 Claude Haiku 4.5 为工作模型,通过 claude -p --output-format json 取得 token 数。对照组基准为 23,624 token,两次运行结果一致。

常见问题

Spotify 的 Portal 是什么,它如何让 Claude Code 的 token 用量下降 90%? Portal 是 Spotify 的内部平台工具。与这套方法直接相关的 Shunt 会在 Claude Code 中注册两个 PreToolUse 钩子。Claude 准备读取超过可配置阈值的文件时,钩子会拦下直接读取,再把任务委托给更便宜的工作模型。默认阈值是 350 行,文中示例使用 Gemini 2.5 Flash,最终返回摘要。Portal 没有开源,但钩子加工作模型这套机制可以复用。

换一个代码库,90% 的 token 节省还能成立吗? 大体成立。我们用 Claude Haiku 4.5 作为工作模型,在一套毫不相关的 JavaScript 和 Python 代码库上复现了同样的趋势。按照 Spotify 的默认策略,只委托 350 行及以上的文件,原本的 27,597 个文件 token 变成 3,939 个摘要 token,降幅为 85.7%。这个结果足以作为对约 90% 的独立佐证。

文件多大时,委托读取才开始节省 token? 本次数据的盈亏临界点在 49 与 87 行之间。43 行的文件直接读取需要 578 token,摘要却用了 644 token,反而亏损。87 行的文件首次转为盈利,省下 165 token。原文件横跨 324–9,977 token,摘要却只在 610–1,384 token 之间,几乎不随文件一起增长。

为什么默认阈值是 350 行,而不是 token 盈亏临界点? 因为延迟也是成本。Spotify 测得每次委托需要 10–30 秒。我们在没有 Portal 后端的链路上实测是 19.0 秒和 20.1 秒。87 行时,约 20 秒只省 165 token,折合每省 1,000 token 要 121.2 秒。到了 470–678 行,同样的等待能省 7,830–8,658 token,每省 1,000 token 只花 2.3–2.6 秒,效率相差约 47 倍。

哪些事不能委托? 编辑和推理。摘要没有可靠行号,所以真正修改代码前还得直接读取对应片段。工作模型也可能只看到表层模式,漏掉 Claude 在完整上下文里能找到的隐蔽线程安全缺陷。委托读取适合判断文件是否相关,不适合拿来断言文件没有问题。

为了省下更多 token,我该降低阈值吗? 不该。12 个文件全部委托,合计降幅只有 73.2%。只委托大文件则是 85.7%。小文件会拉低平均值,其中两个甚至直接亏掉 token。先给摘要提示词设置硬性 token 上限,压低摘要地板,再考虑调整阈值。这样才能移动盈亏临界点,而不用增加一连串缓慢的往返。

这篇对你有帮助吗?

相关阅读


文章独立产出 · 编辑政策

继续阅读 →