长上下文不是免费的:为什么塞满2M token反而更笨,以及该怎么用

📅 2026/4/26 ✍️ 小文 📖 约 1 分钟

上下文窗口越做越大,但把你所有资料都塞进去通常不是最优解。本文从有效上下文、检索精度、延迟成本与并发支持四个角度拆解长上下文的真实代价,并给出一套分配与压缩策略。

“窗口够大”是一个诱人的陷阱

厂商不断把窗口推到百万级,于是自然产生一个想法:把所有文档、整个代码库、全部聊天历史都塞进去,让模型自己找。省掉了检索工程,还避免了”检索漏掉关键段落”的问题。

但实测下来,这个做法在很多任务上不如小窗口+精准检索。原因不是营销话术,而是几个可测量的机制。

四个真实代价

一、有效上下文远小于标称窗口。 “支持1M token”和”在1M token上都可靠”是两件事。信息在超长输入中间被忽略(俗称lost in the middle)是普遍现象,位置敏感、任务相关。常见做法是把关键指令放在开头和结尾,中间部分放辅助材料。

二、多给了会稀释注意力。 输入里90%是无关内容时,模型要么漏检,要么被无关内容带偏。一部长文档里翻两页找到答案,比把全书丢进去更准。这与人类阅读其实一致。

三、延迟和成本是超线性的。 长上下文意味着更大的prefill计算和更高的单次成本,首token延迟显著上升。对于交互式产品,这直接决定体验是否可用。

四、并发被吃掉。 长请求占用显存,批次变小,吞吐下降。在高峰时段,长上下文的实际可用性远低于标称值。

此外还有一个隐性成本:你无法验证它的注意力。短上下文出错时你能定位到具体段落;长上下文出错时,你不知道它到底看了哪里。

什么时候该用长上下文

并非全盘否定。以下场景它是明确更优解:

  • 需要全局一致性:跨章节的引用对齐、整份合同的条款交叉冲突检查、整个代码库的架构一致性
  • 检索难以切分:表格密集、图文混排、逻辑依赖跨段落的文档
  • 一次性任务:成本不敏感,且不复用上下文
  • 调试与探索:不确定答案在哪,先让模型粗定位

而在高频、延迟敏感、内容相对稳定的场景(知识库问答、客服、日常助手),混合检索往往更划算。

一套可执行的分配策略

把上下文预算当作资源来分配,而不是”越大越好”:

系统指令 + 关键约束         ≈ 5%
当前任务与对话近况           ≈ 15%
高相关检索结果(前N条全文)  ≈ 40%
次相关结果(摘要/片段)      ≈ 25%
少量示例(few-shot)        ≈ 10%
留白缓冲                    ≈ 5%

四条实践原则:

  1. 先精排再扩窗:全文塞入前先做一次精排,把最相关的10-20段提到前面,其余只给摘要。
  2. 分层压缩:把历史对话做成”滚动摘要+最近原文”,而不是全量拼接。摘要负责事实,原文负责细节。
  3. 关键信息两端放:任务要求、输出格式放在最前和最后。中间的中段内容容易被忽略。
  4. 打标引用:给每个片段加ID,要求模型在输出中引用来源。这既提高准确性,也让错误可归因。

一个判断”该不该扩窗”的小实验

同一个任务,跑两次:一次用”全部塞入”,一次用”检索前k条”。比较三项:准确率、P90延迟、单次成本。

如果全量模式的准确率提升不到5%,而成本上升3倍,就不必扩窗。在多数知识问答场景,这个实验的结果都非常一致。

结论

上下文窗口是一个上限,不是一个策略。真正的能力在于:把对的15%放进窗口,并让模型知道该看哪里。省下来的token、延迟和显存,会以并发量和用户体验的形式还给你。

📤 分享到