想象你有200块钱预算去超市采购,但要买的东西一大堆:米面油盐、蔬菜水果、零食饮料。怎么分配才能既吃饱又不超支?如果快没钱了,该舍弃什么?

Claude Code面临的200K token预算也是同样的道理。

预算分配:钱要花在刀刃上

200K token是一笔"巨款",但花钱的地方也多。Claude Code的预算分配大致是这样的:

开销项目占比用途
系统提示词10-20%AI的"入职培训手册"
当前对话30-40%最近几轮你问我答
历史上下文20-30%之前的对话记录(可能被压缩)
预留缓冲10-20%给新消息留出空间

这就像你每月的工资分配:

  • 系统提示词:房租水电(固定开销,省不了)
  • 当前对话:一日三餐(必须花,但可以控制)
  • 历史上下文:存款理财(能存多少存多少,实在不行就取)
  • 预留缓冲:应急资金(以防万一)

三层闸门:防止超支的保险

Claude Code有三道"闸门"防止预算超支,就像水坝的分级泄洪:

第一道闸门:单工具50K限制

想象你让AI读一个10MB的日志文件。如果不加控制,这会把预算吃光。

所以Claude Code规定:单个工具结果超过50K字符,就存到磁盘,只给AI看前2KB的预览

这就像快递送来的包裹太大,门卫不让进小区,只给你看快递单号,需要的话自己去仓库取。

特殊规定:

  • Read工具:永远不会被存盘(它有自己控制大小的方式)
  • 图片:直接放行(算固定2000 token)
  • 空结果:填充占位符(防止某些模型误判)

第二道闸门:单消息200K限制

如果AI同时发起5个搜索,每个返回40K字符,加起来就是200K。这时候第一道闸门管不了(每个都没超50K),但总负荷超标了。

所以第二道闸门规定:一条消息里所有工具结果加起来不能超过200K字符

这就像你点外卖,单份套餐不限量,但一次下单总金额不能超过200块。

怎么处理超支?按大小排序,从最大的开始存盘,直到总额降到200K以下。

有个精妙的设计:状态冻结。一旦AI"看到"了某个工具结果,这个决策就永远不变了——这是为了保证prompt缓存稳定。如果这次给AI看完整内容,下次突然换成预览,缓存就失效了。

这就像你跟服务员说"这道菜给我上",不能等厨师做完了又说"不要了"。

第三道闸门:上下文窗口追踪

前两道是"字符"限制,第三道是"token"限制。Claude Code用两种方式估算token数:

精确计数:API返回的usage字段,包含:

  • input_tokens(本次输入)
  • cache_creation_input_tokens(新写入缓存)
  • cache_read_input_tokens(从缓存读取)
  • output_tokens(AI输出)

粗略估算:字符数 ÷ 4。特殊文件用不同系数:

  • 普通文本:÷ 4
  • JSON:÷ 2(JSON符号多,token密度高)
  • 图片/PDF:固定2000 token

为什么要估算?因为在两次API调用之间,没法精确知道token数。估算偏差可能达±50%,但够用就行——反正还有压缩兜底。

并行工具的计数陷阱

这里有个坑:并行工具调用时的token计数容易算错。

当AI同时发起两个工具调用,内部消息数组是这样的:

[..., AI消息, 工具结果1, AI消息, 工具结果2]

注意两个AI消息共享同一个ID(来自同一次API响应)。如果简单地从后往前找"最后一个有usage的AI消息",可能会漏掉工具结果1

Claude Code的解决方案是:向前回溯到同ID的第一个AI消息,从这个位置开始算所有后续消息

这就像数一排人,不能只数你身边的人,要数整排。

Token预算的实战策略

理解了预算机制,你可以这样优化使用:

1. 控制搜索范围

与其让AI搜索整个代码库,不如限定范围:

# 不好的做法
搜索 "TODO"

# 好的做法
搜索 "TODO",但只在 src/ 目录下

这就像买东西列清单,比漫无目的地逛更有效。

2. 分批次处理

如果需要分析大量文件,分批进行:

先分析核心模块,再处理边缘功能

不要一次性让AI读10个文件——可能触发持久化,AI只能看到预览。

3. 利用Read工具

Read工具有特殊待遇:不会被持久化到磁盘。所以如果某个文件很重要,用Read比用cat命令更可靠。

这就像VIP通道,不用排队。

4. 注意JSON文件

JSON文件的token密度是普通文件的2倍。100KB的JSON实际消耗约50K token,而不是25K。

读大型JSON配置文件时要特别小心。

5. 预估压缩时机

Claude Code会在上下文接近上限时触发自动压缩。但估算可能有偏差:

  • 如果内容以英文为主,估算偏保守(实际token更少)
  • 如果内容有很多代码/JSON,估算可能偏低(实际token更多)

所以压缩可能比预期早到或晚到,要有心理准备。

预算耗尽后怎么办?

当Token真的快用完了,Claude Code会:

  1. 触发自动压缩:把历史对话打包成摘要
  2. 清理旧工具结果:微压缩上场
  3. 提示用户:“上下文快满了,建议开启新会话”

这就像信用卡刷爆了:

  • 先尝试分期还款(压缩)
  • 实在不行冻结部分额度(清理工具结果)
  • 最后提醒你:“该还钱了”(开新会话)

什么时候该开新会话?

  • 对话已经进行了很长时间(几十轮以上)
  • 主题已经切换(从修bug变成讨论架构)
  • AI开始"遗忘"早期内容(被压缩了)

开新会话不是认输,是明智的预算管理。

动态调整:预算不是死的

Claude Code的预算分配是动态的:

  • 工具结果大 → 压缩更多历史
  • 对话短 → 保留更多历史
  • 接近上限 → 激进压缩

这就像你旅游时的花钱策略:

  • 刚到目的地,钱充裕,吃得好住得好
  • halfway了,开始精打细算
  • 快没钱了,住青旅吃泡面

这对构建AI Agent的启示

如果你想设计自己的AI Agent,Token预算管理值得借鉴:

1. 多层防御

不要指望一道闸门解决问题,要分层:

  • 第一层:单结果限制(防止单个炸弹)
  • 第二层:单消息限制(防止累积效应)
  • 第三层:全局追踪(兜底)

2. 宁可高估,不要低估

估算token时,保守一点好:

  • 高估的代价:提前压缩(性能损失)
  • 低估的代价:API调用失败(用户体验崩了)

3. 状态管理很重要

一旦模型"看到"了某个内容,这个决策就要保持一致。这需要状态管理,不能是无状态的纯函数。

4. 考虑缓存影响

prompt缓存的存在改变了很多设计:

  • 不能随意改变已发送的内容
  • 状态要持久化到会话文件
  • 恢复会话时要还原状态

总结

Token预算是Claude Code上下文管理的"守门员":

  • 三层闸门:单工具50K、单消息200K、全局200K token
  • 两种估算:精确计数(API返回)+ 粗略估算(字符÷4)
  • 动态调整:根据使用情况灵活分配
  • 状态冻结:已见内容不再改变,保证缓存稳定

这就像理财:

  • 有预算才有规划
  • 有闸门才不怕超支
  • 有应急方案才能从容应对

理解Token预算,你就能:

  • 预判什么时候可能触发压缩
  • 合理安排工具调用策略
  • 在自己的AI Agent中实现类似机制

下篇咱们聊聊缓存中断——什么情况下会失效?