跳到主要内容

隐藏的 Token 税:在用户开口之前,你的上下文窗口为何已消失了 30-60%

· 阅读需 10 分钟
Tian Pan
Software Engineer

你在为一个 200K token 的上下文窗口付费。你的用户可能只用到了其中的 80K。剩下的部分在第一条消息到达之前就消失了——被系统提示词(system prompt)、工具定义、安全前言和聊天历史填充所消耗。这就是隐藏的 Token 税,大多数团队直到在生产环境中达到上下文限制时才意识到自己在为此付税。

宣传的上下文窗口与实际可用的上下文窗口之间的差距是生产级 LLM 系统中最昂贵的盲点之一。它在多轮对话中不断累积,通过注意力开销增加延迟,并在有用信息被挤入模型停止关注的“迷失在中间”(lost in the middle)区域时,悄无声息地降低输出质量。

Token 税剖析

每一个 LLM API 调用都带有从未出现在你的应用逻辑中、却总是出现在你的账单上的开销。以下是一个典型的具有工具调用(tool-calling)能力的生产级智能体中 token 去向的明细:

系统提示词 (System prompt):1,000–5,000 token。这包括行为指令、输出格式规则、安全准则、角色定义和特定领域约束。对于一个配置良好的生产级智能体,3,000 token 很常见。Anthropic 的建议是使用“完整勾勒预期行为的最小信息集”,但在实践中,系统提示词像任何其他代码库一样增长——只有累加,没有修剪。

工具定义 (Tool definitions):每个工具 400–550 token。每个函数模式(function schema)——名称、描述、参数类型、枚举值——都会被序列化到上下文中。一个拥有 15 个工具的智能体仅在定义上就会消耗 6,000–8,000 token。无论模型是否调用,每个工具都会按输入 token 计费。

聊天历史 (Chat history):每轮对话 1,500–2,000 token。一个 15 轮的对话会积累 25,000+ token 的历史记录,包括之前的工具调用、其结果以及助手的回答。其中大部分是陈旧的上下文,模型不太可能引用,但仍必须处理。

安全和框架前言 (Safety and framework preambles):500–2,000 token。API 提供商会注入他们自己的系统级指令——内容过滤规则、使用政策、工具调用格式规范——这些你没写也看不见,但都会计入你的预算。

RAG 检索结果:每次查询 2,000–8,000 token。从向量库中检索到的片段带有格式化的元数据、来源归属,有时还包含重叠片段中的冗余内容。

综合计算一个生产级智能体在对话中期的轮次:在模型处理用户实际说的话之前,已经消耗了 40,000–50,000 token。对于 200K 的上下文窗口,基准水平就已经消失了 20–25%。对于 128K 的窗口,这一比例为 30–40%。而且这会随着每一轮对话而增长。

复利问题

Token 税不是静态的——它是复利的。每一轮对话都会增加历史记录。每一次工具调用都会追加请求和响应。每一次 RAG 检索都会塞入更多上下文。到一个复杂智能体交互的第 10 轮时,你可能会看到这样的情况:

  • 系统提示词:3,000 token(固定)
  • 工具定义:6,000 token(固定)
  • 累积历史:30,000 token(增长中)
  • 当前轮次的检索:5,000 token(变量)
  • 框架开销:1,000 token(固定)

总计 45,000 token——而你在当前任务上一个还没用。模型在推理过程中必须关注所有这些 token,这意味着两件事:你的延迟增加(注意力计算随序列长度呈平方级增长),以及模型专注于相关信息的能力下降。

研究一致表明,模型表现出很强的首因效应和近因效应。长上下文中间的信息会被降低优先级——这种被称为“迷失在中间”(lost in the middle)的现象在各代模型中都持续存在。Token 税将你的实际内容推向了正是这个危险区域,夹在沉重的系统提示词前缀和最新的助手响应之间。

让团队措手不及的场景

三个场景经常让团队措手不及:

多智能体乘数效应。在完成同等任务时,多智能体架构消耗的 token 大约是单智能体方法的 15 倍。每个智能体都携带自己的系统提示词、工具定义和对话状态。处理单个用户查询的三智能体流水线成本可能在 0.45–0.60 美元,而单智能体调用仅需 0.03 美元。Token 税不仅是按次调用计算的——它是按“每个智能体每次调用”计算的。

工具定义膨胀。团队会为每次对话注册所有可用工具,即使大多数对话只需要两三个。一个拥有 30 个工具的智能体在每次调用时会在定义上消耗 12,000–16,000 token。在每天数千次的请求中,这变成了一个显著的支出项目——而且对于 90% 仅使用基础工具的调用来说,这完全是浪费。

测试环境与生产环境的鸿沟。开发和测试(staging)环境通常使用历史记录极少的短对话。生产环境的对话运行时间更长,累积更多的工具结果,并触发更多的检索。团队在 5,000 token 的开销下进行测试,然后发布到开销超过 40,000 token 的环境中。第一个症状通常是复杂对话中的上下文窗口溢出错误,或者是需要数周才能察觉的细微质量下降。

审计你的 Token 预算

在优化之前,先进行衡量。这是一个实用的审计框架:

步骤 1:对每个组件的 token 计数进行插桩(Instrument)。 将每一次 API 调用分解为系统提示词 token、工具定义 token、历史记录 token、检索 token 和用户内容 token。大多数可观测性平台都支持 span 级的 token 归因。如果你的平台不支持,请在组装前后使用 tiktoken 计数来封装你的 API 调用。

步骤 2:计算你的有效上下文比例。 用用户相关 token 数除以总输入 token 数。一个健康的生产系统应保持 0.4 以上的比例(即 40% 的 token 用于服务当前任务)。低于 0.3 意味着超过三分之二的上下文预算——以及你的推理成本——都消耗在了开销上。

步骤 3:分析不同对话长度下的表现。 绘制有效上下文比例随对话轮次变化的曲线。你可能会发现该比例在第 8-12 轮左右跌至 0.3 以下。这正是你的系统质量开始下降、成本开始飙升的转折点。

步骤 4:识别最大的固定成本。 按 token 数量对开销组件进行排序。前三名就是你的优化目标。在大多数系统中,顺序通常是:聊天历史 > 工具定义 > 系统提示词。

降低“Token 税”

完成衡量后,以下是杠杆率最高的优化手段:

激进地压缩聊天历史。 不要携带超过 5-7 轮的原始对话历史。将较旧的轮次总结为一个紧凑的上下文块。25,000 token 的历史记录通常可以压缩到 2,000-3,000 token,且信息损失极小。当历史记录超过目标预算的 70% 时,触发压缩逻辑。

动态加载工具。 不要预先注册所有工具,而是实现工具路由:先对用户的意图进行分类,然后仅针对该请求加载 2-4 个相关的工具定义。对于拥有大量工具库的智能体(Agent),这可以将工具定义开销降低 80%。

模块化你的系统提示词。 将庞大的系统提示词分解为一个精简的基础提示词(500-800 token),并根据对话状态加载条件模块。一个客户支持智能体在对话真正需要升级之前,并不需要加载其升级流程的指令。

去重 RAG 结果。 从向量数据库检索到的分块(chunks)经常会出现显著重叠,尤其是在分块较小的情况下。在注入上下文之前,应在内容层面而非仅在 ID 层面进行去重。同时,剔除模型不需要的元数据字段——相似度得分、分块索引和嵌入向量(embedding vectors)不应该出现在你的提示词中。

精简工具输出。 工具结果通常是包含模型不需要的字段的原始 API 响应。如果模型只需要 3 列数据,而数据库查询返回了 20 列,那么在后续每一轮对话中,这些存在于历史记录中的冗余数据都会浪费 token。对工具输出进行后处理,仅保留与任务相关的字段。

提示词压缩的权衡

像 LLMLingua 这样的提示词压缩库可以在质量损失有限的情况下,将输入长度缩减 2-5 倍。这听起来很有吸引力,但也引入了自身的复杂性:额外的推理步骤(压缩模型)、压缩输出中潜在的语义漂移,以及需要监控的新失效模式。压缩最适用于 RAG 内容和历史上下文,而不适用于对精确措辞要求极高的系统提示词或工具定义。

更可持续的方法是打从一开始就防止膨胀。将你的上下文窗口视为嵌入式系统中的内存,而不是云服务器上的磁盘空间。每一个 token 在每一次调用中都应该证明其存在的合理性。

更宏观的视角

行业正朝着百万级 token 上下文窗口飞速发展,这产生了一种危险的幻觉:即上下文管理不再重要。但 Chroma 2025 年对 18 个领先模型的评估研究表明,当上下文超过 50,000 token 时,性能会发生灾难性的下降,而非逐渐衰减。百万级 token 窗口并不意味着你可以塞进一百万个 token 并获得良好的结果。它只是意味着你有了更多“吊死自己”的绳子。

交付可靠 AI 系统的团队并不是那些拥有最大上下文窗口的团队。而是那些清楚地知道流水线中每个组件消耗了多少 token、为什么每个 token 会出现在那里,以及移除它会发生什么的团队。在你决定查看账单之前,“隐藏的 Token 税”永远是隐藏的。

References:Let's stay in touch and Follow me for more thoughts and updates