上下文窗口与长上下文问题
理解长上下文最关键是区分 prefill 和 decode。Prefill模型先把整段已有上下文都读一遍为每一层生成 K/V 状态。上下文越长prefill 通常越重TTFT首 token 延迟越高。Decode之后每生成一个新 token只需要基于历史缓存继续算新增部分。这个阶段 KV Cache 会极大降低重复计算。为什么超长 prompt 首 token 慢就从 prefill 讲为什么 KV Cache 能提速你就从 decode 阶段避免重复计算讲起一、什么是上下文窗口为什么它不是一个单纯的数字1. 定义一次请求中模型可处理的总 token 预算上下文窗口context window通常指模型在一次请求中能处理的 token 总预算。这个预算一般同时覆盖输入和输出某些平台还会受到 reasoning token、工具消息、系统提示等隐性成本影响。很多初学者只记住某模型是 128k/400k/1M但真正做系统时你要问的是系统提示词占了多少历史对话占了多少检索资料占了多少工具 schema 和工具结果占了多少还要给输出预留多少。也就是说context window 不是你能塞进去的文档大小而是整个会话状态的预算上限。2. Token 预算是系统资源不是无成本便利OpenAI、Anthropic、Gemini 等平台都在文档里强调 token 成本Gemini 与 Anthropic 还分别提供 context/prompt caching 机制OpenAI 则在新文档里强调 prompt caching 与 compaction。为什么大家都在做这些事因为长上下文太贵了而且越来越成为真实应用的主要瓶颈之一。最好能明确指出两个成本显性成本token 计费隐性成本显存占用、并发下降、首 token 延迟增加。只会说会更贵是不够的更好的表达是更长输入不仅提高计费还增加 prefill 计算与 KV Cache 占用影响 首 Token 延迟和吞吐因此长上下文设计一定是质量与性能的平衡问题。二、KV Cache 到底是什么1. 直觉解释在自回归生成中如果每生成一个新 token 都把前面全部上下文从头算一遍那代价会极大。KV Cache 的核心思想就是在 previous tokens 已经算过的情况下把各层 attention 需要的 Key 和 Value 状态缓存起来。下一步只需要为新 token 计算 Query并与历史的 K/V 交互就能继续生成。你可以把它理解成历史读过的书页先做成索引下次不再整本重读只增量读新的一页。2. 为什么它重要KV Cache 直接决定解码速度显存占用最大并发可支持的有效上下文长度。Google 关于 tiered KV cache 的工程文章直接指出KV Cache 的 GPU 显存占用会成为上下文长度、并发度和总体吞吐的关键瓶颈。Hugging Face 的缓存文档也把动态缓存、静态缓存、量化缓存、offloading 等策略作为生成性能优化的重要主题。也就是说今天的推理服务优化很多时候已经不是算力够不够而是KV Cache 怎么放、怎么复用、怎么迁移的问题。3. KV Cache 与 Prompt Caching 不是一回事KV Cache通常指单次生成或持续会话中的模型内部状态缓存主要优化 decode 过程。Prefix / Prompt Caching通常指当不同请求共享相同前缀时服务端或框架复用已算过的前缀结果避免重复 prefill。三、长上下文为什么不一定真的有用1. Lost in the Middle中间位置的信息最容易被忽略《Lost in the Middle》是长上下文讨论里最经典的论文之一。它指出很多长上下文模型在需要从很长输入中找到关键信息时效果对位置信息非常敏感开头和结尾的内容往往更容易被利用而中间部分可能被显著忽略。这个现象对应用设计的启发非常直接不要把最关键证据埋在长 prompt 正中间长文档问答不要只靠整篇塞入最好结合检索和重排最重要的信息应该尽量靠前、靠后或被显式标记单纯扩大窗口不能替代检索质量。为什么 1M context 还要做 RAG这就是最标准的回答素材。2. 上下文污染与注意力稀释上下文太长会带来另一个问题噪声变多。无关历史对话、重复片段、失效工具结果、多个版本冲突的业务规则都可能污染模型判断。很多线上系统不是上下文不够而是上下文太脏。这时候真正需要的不是更大窗口而是更好的上下文治理。3. 长上下文与多轮会话并不等价有些同学以为模型有百万窗口就可以无限聊。但多轮会话除了窗口上限还有状态漂移、历史冲突、旧指令污染、缓存失效、工具结果过时等问题。到 2025–2026 年OpenAI 的 Responses compaction、Anthropic 的 context management、Gemini Live 的 session summary 等新能力都在说明长会话要靠摘要、压缩、状态管理不是简单无限堆历史消息。四、长上下文的常见优化思路1. 检索优先而不是全量塞入如果任务是从几十万字文档中找特定证据最优策略往往是先检索、再精选片段、再按顺序组织而不是把整本文件直接塞给模型。大窗口降低了必须极致裁剪的压力但并没有消灭检索与重排的必要性。2. 结构化组织比原文堆叠更重要把上下文分成任务目标关键事实规则约束few-shot 示例工具列表候选证据输出 schema通常比把十段文档原文依次贴上去效果更好。这其实已经进入 context engineering 的范畴不是喂更多而是喂得更有结构。3. 显式压缩与会话总结对于多轮对话保留全部历史往往既贵又脏。更常见做法是只保留最近若干轮原文早期历史压缩成 summary/state把已完成的步骤用户偏好待办约束提取成结构化状态必要时做 compaction。4. 让前缀稳定提高缓存命中率这是一条非常工程化、也非常容易在面试中脱颖而出的经验。很多系统 prompt、权限说明、工具 schema、产品规则明明是稳定的却每轮都加时间戳、随机 request id、无意义换行或顺序扰动导致 prompt cache 很难命中。真正懂系统的人会主动把稳定前缀和动态后缀拆开设计。