上下文越长越好吗?为什么大模型“看得见”,却不一定“用得好”

5905 字
30 分钟
上下文越长越好吗?为什么大模型“看得见”,却不一定“用得好”

上一篇聊完 Context Window(上下文窗口)之后,我们留下了一个新的问题。

如果上下文窗口就像模型面前的一张桌子:

桌子越大,不就能摆越多资料吗?

那按理来说:

32K 不够就上 128K,128K 不够就上 1M。

一路堆上去不就好了?

事情显然没有这么美好。

不然现在各家模型厂商比的就不是模型能力,而是谁家先造出一张面积堪比地球的桌子了 (0x0)

现实里经常会出现一种很奇怪的现象:

模型明明成功接收了全部资料,答案也确实藏在里面,但最后还是:

  • 漏掉关键信息;

  • 把旧要求当成新要求;

  • 找到正确资料却推错了结论;

  • 被几段看起来很相关的废话带跑偏;

  • 或者单纯开始“顾不过来了”。

所以这一篇,我们就来讨论:

已经塞进去的东西,模型到底是怎么用的?为什么东西一多,就可能开始用不好?

横版省流图:长上下文看得见不等于用得好
横版省流图:长上下文看得见不等于用得好

这就绕不开一个我们天天挂在嘴边的词:

Attention(注意力机制)。


Attention 真的是“注意力”吗?#

我们平常经常说:

模型注意力有限。

这个说法很形象,但也很容易让人产生一种错误想象:

模型拥有:
100 点注意力
10 个 Token:
每个分 10 点
100 个 Token:
每个分 1 点
100 万个 Token:
大家一起喝西北风

实际上不是这么回事。

**Attention(注意力机制)**虽然中文叫“注意力”,但这里并不是人类心理学里那种“我集中精神看这件事”的注意力。

在 Transformer 里,它更接近:

模型在处理当前信息时,计算上下文中的其他信息和它有多大关系,再根据相关程度决定应该重点利用哪些内容。

Transformer 的原始论文《Attention Is All You Need》把 Attention 描述为:根据一个 Query(查询),在一组 Key-Value(键-值)信息中计算匹配程度,再对 Value 进行加权组合。

听起来又开始有点像咒语了。

没关系,我们拆开。


Query、Key、Value:其实可以先想成一次搜索#

Attention 里有三个非常经典的东西:

Query(查询向量,Q)#

Query 字面意思就是:

查询。

在这里可以先理解成:

“我现在想找什么?”

模型内部不是拿自然语言直接比较,而是把信息变成一组数字进行计算。

先不用管这组数字长什么样,只需要知道这些数字统称为向量便足够了。


Key(键向量,K)#

Key 通常直译成:

键。

但这里如果把它想象成“钥匙”,多少有点莫名其妙。

在 Attention 的语境下,它更接近:

一条信息用来告诉别人“我这里有什么”的检索特征。

所以为了帮助理解,我更推荐暂时把它想成:

资料索引。

注意,这只是方便理解的类比,并不是说 Transformer 内部真的建了一个搜索引擎索引库。


Value(值向量,V)#

Value 字面是:

值。

但这里也不是我们写代码时:

name = "可可萝"

里面那个普通变量值。

它表示的是:

如果模型决定参考这条信息,这条信息真正提供给后续计算的内容表示。

所以把三个东西放在一起:

Query:我现在想找什么?
Key: 我这里大概是什么信息?
Value:如果你需要我,我真正提供什么?

举个不怎么严谨,但很好理解的例子#

假设上下文里有这些内容:

小明喜欢苹果。
小红喜欢香蕉。
主人以前喜欢苹果。
主人现在最喜欢草莓。
可可萝今天买了草莓蛋糕。

然后问:

主人现在最喜欢什么?

模型在处理这个问题时,会尝试判断前面的哪些信息和当前问题关系最大。

可以非常粗略地想象成:

小明喜欢苹果 相关度:低
小红喜欢香蕉 相关度:低
主人以前喜欢苹果 相关度:较高
主人现在最喜欢草莓 相关度:很高
可可萝今天买了草莓蛋糕 相关度:也有一点

然后模型重点利用:

主人现在最喜欢草莓。

于是回答:

草莓。

这就是 Attention 最基本的直觉。

当然,真实 Transformer 远比这个复杂:

  • 有很多层;

  • 有多个 Attention Head(注意力头);

  • 每个 Token 都会产生自己的 Q、K、V;

  • 这些东西也不是我们刚才列的几个简单“相关度数字”。

但现阶段我们只需要知道:

Attention 做的一个核心工作,就是让模型从大量上下文中判断“当前到底应该参考谁”。

可可萝用 Query 在 Key 中寻找匹配项并取出 Value
可可萝用 Query 在 Key 中寻找匹配项并取出 Value


所以,上下文越长到底发生了什么?#

现在把刚才那个例子扩大。

原来只有:

5 条信息

现在变成:

50000 条信息

里面还有:

主人以前喜欢苹果。
主人曾经说苹果也不错。
主人朋友喜欢草莓。
主人买过苹果。
主人现在喜欢草莓。
主人讨厌草莓味牙膏。
主人昨天吃了苹果派。
……

真正答案还是:

主人现在喜欢草莓。

但模型现在面对的问题已经发生变化。

原来是:

从五句话里找到正确的一句。

现在是:

从五万句话里,区分大量语义相似、主体相似、时间不同、状态不同的信息。

这时候就会出现:

Distractor(干扰项 / 干扰信息)

这里的 Distractor 指:

看起来和当前问题有关系,但实际上并不是我们真正需要的信息。

比如:

主人以前喜欢苹果。

它和“主人”“喜欢”“水果”全部高度相关。

但如果问题问的是:

“现在最喜欢什么?”

它就是一个非常危险的干扰项。


最麻烦的不是废话,而是“很像答案的废话”#

真正完全无关的信息反而不一定最可怕。

比如我突然往上下文里塞一句:

长颈鹿平均睡眠时间很短。

然后继续问:

主人喜欢什么水果?

模型大概率知道:

这东西跟我没关系。

真正麻烦的是:

主人以前喜欢苹果。
主人最近买过苹果。
主人说苹果派很好吃。
主人朋友推荐过苹果。
主人现在最喜欢草莓。

它们每一句都:

看起来有点用。

模型需要进一步区分:

  • 谁说的?

  • 什么时候说的?

  • 描述的是过去还是现在?

  • “买过”是不是等于“最喜欢”?

  • “别人推荐”是不是主人的偏好?

这种现象可以称为:

Distractor Interference(干扰信息干扰 / 干扰项竞争)

这里的 Interference(干扰)不是通信领域的电磁干扰,而是:

大量看似相关的信息同时存在,使模型更难正确判断哪些信息真正应该参与当前任务。

这并不是纯粹的理论担忧。

已有研究发现,在原本能够解决的推理题中加入无关上下文,就可能显著降低部分大模型的正确率。

换句话说:

有时候让模型少看一点,反而比把所有东西一股脑塞进去更好。

是不是开始有点像人了。

老板:

我把项目成立以来三年的全部聊天记录都发给你了,你看一下现在需求是什么。

我:

……你还是杀了我吧。


Retrieval:先别急着推理,能找到就已经不错了#

这时候又需要引入一个很重要的概念:

Retrieval(检索)

Retrieval 通常翻译成:

检索。

在长上下文模型里,它表示:

模型能不能从大量输入中准确找到当前任务需要的信息。

比如我们往 100 万 Token 的文本中藏一句:

暗号是“可可萝今天想吃饭团”。

最后问:

暗号是什么?

模型只需要:

  1. 找到那句话;

  2. 把它回答出来。

这类测试有一个很形象的名字:

Needle in a Haystack(干草堆里找针)

中文一般可以直接理解成:

大海捞针测试。

Needle(针)就是那条目标信息。

Haystack(干草堆)就是周围大量没有直接作用的上下文。


大海捞针成绩很好,代表长上下文很强吗?#

不一定。

这正是长上下文测试里一个特别容易被误解的地方。

假设一个模型可以做到:

在 1M Token 里准确找到一句暗号。

很厉害。

但这只能比较有力地说明:

它在这个场景下的长上下文 Retrieval(检索)能力很好。

却不能直接说明:

它能够很好地理解 1M Token 里的所有复杂关系。

RULER 是专门用来研究这个问题的一套长上下文 Benchmark(基准测试)。

这里的 Benchmark 指:

用一组标准化任务评价和比较模型能力的方法。

RULER 的研究者就指出,最基础的 Needle in a Haystack 主要测试一种相对简单的检索能力,因此他们进一步加入了:

  • 多个 Needle;

  • 多 Key / 多 Value;

  • Multi-Hop Tracing(多跳追踪);

  • Aggregation(聚合);

等更复杂的任务。

结果发现,一些在简单“大海捞针”上接近满分的模型,随着上下文长度和任务复杂度增加,表现依然会明显下降。

这就像:

能在一本 1000 页的书里找到“凶手叫小明”。

和:

读完这 1000 页以后,根据几十处伏笔推断为什么小明是凶手。

显然不是同一道题。

可可萝对比 Retrieval 找针与 Reasoning 连接线索
可可萝对比 Retrieval 找针与 Reasoning 连接线索


Retrieval 和 Reasoning 是两回事#

于是又到了另一个经常出现的词:

Reasoning(推理 / 逻辑推理)

这里需要特别说明一下。

Reasoning 指的是:

模型根据已有信息建立关系,并推出原文没有直接写出来的结论。

比如:

A 比 B 高。
B 比 C 高。

然后问:

A 和 C 谁更高?

原文没有直接写:

A 比 C 高。

模型需要把两条关系组合起来。

这就是 Reasoning。


Multi-Hop Reasoning:答案需要拐好几个弯#

如果推理不是一步完成,而是必须连续经过多个中间关系,就叫:

Multi-Hop Reasoning(多跳推理)

这里的 Hop 字面意思是:

跳。

但显然不是模型在机房里蹦跶。

它表示:

推理需要从一个信息节点跳到另一个信息节点,经过多个中间步骤才能得到答案。

例如:

A 项目由 B 团队维护。
B 团队负责人是小明。
小明现在属于 C 部门。
C 部门要求所有项目使用 PostgreSQL。

最后问:

A 项目应该使用什么数据库?

模型需要:

A 项目
B 团队
小明
C 部门
PostgreSQL

如果这四条信息都挨在一起,还好。

但如果:

第一条在第 5K Token
第二条在第 80K Token
第三条在第 200K Token
第四条在第 450K Token

事情就开始变麻烦了。


Long-Range Dependency:信息离得太远了#

这种情况下会涉及:

Long-Range Dependency(长距离依赖关系)

这里的“距离”不是物理距离。

而是:

两条需要互相联系的信息,在 Token 序列中相隔很远。

比如:

第 2000 个 Token 定义了一条规则。

到了:

第 150000 个 Token

才出现需要使用这条规则的信息。

模型需要把这两个相隔很远的内容联系起来。

所以长上下文真正难的地方之一就是:

不仅要找到信息,还要维持跨越很长序列的信息关系。

这也是为什么:

找到一句话

和:

理解一整份几十万 Token 的复杂项目历史

不能只看一个“上下文窗口大小”就认为它们难度差不多。

可可萝连接跨越遥远信息节点的 Long-Range 与 Multi-Hop 路径
可可萝连接跨越遥远信息节点的 Long-Range 与 Multi-Hop 路径


Lost in the Middle:东西明明在那里,但模型就是容易漏#

长上下文领域还有一个非常经典的现象:

Lost in the Middle

可以翻译成:

“迷失在中间”现象。

这个名字本身就挺形象。

2023 年的《Lost in the Middle: How Language Models Use Long Contexts》研究发现,在他们测试的模型和任务中,当关键信息出现在长上下文的开头或末尾时,模型通常表现更好;而当相同信息被放到上下文中间位置时,性能可能明显下降。即使是专门支持长上下文的模型,也观察到了这种现象。

也就是说:

上下文开头 中间 上下文结尾
↑ ↑ ↑
比较容易 可能变差 比较容易

当然,这并不是一条:

“所有模型中间第 50% 的内容必定失忆”

这样的宇宙定律。

不同模型、不同任务、不同训练方式都会影响结果。

但可以从中看出一个问题:

信息存在于 Context 中,并不代表模型对上下文每一个位置的利用能力完全均匀。

东西没丢。

模型也不是“看不见”。

但:

看见 ≠ 一定能稳定地用上。

可可萝从长卷轴中段找回仍然存在的关键信息
可可萝从长卷轴中段找回仍然存在的关键信息


所以,是不是只要把无关内容删干净就好了?#

聊到这里,很容易得到一个新的结论:

原来问题就是 Context 里垃圾太多。

那么只要把干扰信息清掉:

长上下文不就彻底解决了吗?

很遗憾,事情又没有这么体贴。

2025 年有一篇研究专门做了一个挺有意思的实验。

研究者测试了数学、问答和代码等任务,并刻意确保模型能够正确获取所有相关信息。

甚至在一些实验里,他们:

  • 用空白等极低干扰内容拉长输入;

  • 对无关 Token 做 Mask(遮蔽,使 Attention 不去关注它们);

  • 或把真正需要的证据直接放到问题旁边。

结果在他们测试的 5 个开源和闭源模型中,仅仅把输入本身拉长,也仍然观察到了不同程度的性能下降。

这个结果挺有意思。

因为它说明:

长上下文能力下降,不一定能够全部归结成“模型找不到那根针”。

至少在这些实验里:

针已经找到了,模型还是可能因为整个输入非常长而表现变差。

当然,这是一篇针对特定模型和任务进行实验的研究,不能简单推广成:

“任何模型只要输入变长就必定变笨。”

但它很好地提醒了一点:

长上下文问题可能不仅是 Retrieval(检索)问题。

长度本身,以及模型如何在长序列中组织和使用信息,也可能影响最终结果。


Context Interference:Agent 为什么特别容易中招?#

到了这里,就可以把话题拉回我们平常真正会遇到的场景了。

比如一个 Agent 连续工作了很久。

上下文里慢慢堆出了:

第一版需求
第一版修改
方案 A
方案 A 被否决
方案 B
方案 B 修改
讨论过方案 C
C 没采用
又回到方案 B
一堆测试日志
一次失败实现
修复失败实现
新的临时要求
临时要求后来又取消

问题是什么?

这些内容很多并不是:

完全没用。

恰恰相反。

它们曾经都有用

于是模型现在必须判断:

哪些还是有效要求?

哪些只是历史记录?

哪些方案已经被推翻?

哪一句是讨论,哪一句才是最终决定?

这种现象可以用:

Context Interference(上下文干扰)

来描述。

这里不是指某一个严格、统一定义的 Transformer 模块名称,而是一个很直观的工程表达:

上下文里的旧信息、冲突信息和无关信息开始影响当前任务。

也就是说:

不是模型没资料。

而是资料多到互相打架了。


Signal-to-Noise Ratio:有时候上下文需要的不是“大”,而是“干净”#

这里可以借用一个通信领域的概念:

Signal-to-Noise Ratio(信噪比,SNR)

原本它描述的是:

有效信号和噪声之间的比例。

我们这里不是突然转行研究无线电。

只是借这个概念来形容 Context:

Signal(信号)

可以理解成:

当前任务真正有价值的信息。

比如:

  • 最终需求;

  • 当前代码;

  • 有效约束;

  • 当前错误信息。

Noise(噪声)

则是:

  • 已废弃方案;

  • 重复日志;

  • 无关聊天;

  • 旧代码;

  • 已经失效的要求;

  • 对当前任务没有帮助的大量工具输出。

于是两个都是 100K Token 的 Context:

Context A
90K 有效信息
10K 噪声

和:

Context B
10K 有效信息
90K 噪声

虽然参数表上都是:

100K Context

但模型面对的任务完全不是一回事。

这也是为什么 Agent 工程里经常需要:

  • 清理工具输出;

  • 压缩历史;

  • 保留最终决策;

  • 移除已经失效的信息;

  • 把真正重要的状态结构化保存。

目的并不仅仅是:

“防止超过上下文窗口。”

更重要的是:

让真正重要的信息不要被淹没。

可可萝归档上下文噪声并保留清晰的 Current State
可可萝归档上下文噪声并保留清晰的 Current State


所以,“模型注意力有限”到底应该怎么理解?#

绕了一大圈,现在终于可以回来重新看这句话:

模型注意力有限。

它作为一句日常表达其实没什么问题。

但如果认真一点,它不应该理解成:

模型只有固定 100 点注意力,Token 越多大家分得越少。

更准确的意思应该是:

当上下文越来越长、信息越来越复杂时,模型需要在更多候选信息之间判断相关性,同时维持更远的信息关系并完成后续推理,而这种利用长上下文的能力并不是无限的。

这里包含了好几种不同能力:

找得到
Retrieval(检索)
分得清
抵抗干扰信息
连得起来
Long-Range Dependency(长距离依赖)
推得出来
Reasoning(推理)
多个关系连续推
Multi-Hop Reasoning(多跳推理)

所以:

“上下文很长”只是告诉我们资料很多。

真正决定模型表现的,是:

它能不能从这些资料里找到正确内容、排除干扰、建立关系,然后把这些信息真正用于回答。


一个模型能在 1M Token 里找到针,并不代表它读懂了整个草堆#

我觉得这句话特别适合作为这一篇最后的记忆点。

模型可能:

在 1M Token 里准确找到一句暗号。

这已经是一项很厉害的能力。

但:

找到一句话,

理解整份文档,

综合几十条规则,

完成跨越几十万 Token 的推理,

本来就是不同难度的事情。

像 RULER 和 LongBench 这类长上下文 Benchmark,也正是因为单一任务无法完整描述“长上下文能力”,才会分别测试检索、问答、总结、多文档理解、代码以及更加复杂的组合任务。

所以以后再看到:

某模型支持 1M Context,并且 Needle in a Haystack 100%!

可以先:

哇,好厉害。

然后再补一句:

然后呢?

它能不能处理中间信息?

能不能抵抗干扰?

多个 Needle 呢?

需要把这些信息组合起来推理呢?

这才开始接近我们真正想知道的:

这个模型到底有多会用长上下文。


不过还有一个问题一直没回答#

到这里,我们已经解释了:

为什么上下文越长,模型可能越难把信息用好。

但是这整篇讲的其实都是:

质量问题。

哪怕模型在 200K、500K 以后已经开始:

  • 找错资料;

  • 推理失误;

  • 胡说八道;

理论上也只是:

“它处理得不好。”

那为什么现实里一个标称:

128K Context

的模型,到了第 128001 个 Token,有时候根本不是“回答质量下降”,而是:

直接不让你塞了?

如果 Attention 只是越来越难处理,那第 128001 个 Token 到底撞上了什么东西?

模型脑子里真的存在一个:

if token == 128001:
拒绝主人()

吗?

这个问题其实和今天讲的 Attention、Retrieval、Reasoning 都不是一回事。

下一篇我们就专门来抠这个有点反直觉的问题:

为什么 128K 模型塞不进第 128001 个 Token?真正拦住它的可能根本不是模型

到那里,我们才会正式碰到:

  • Positional Encoding(位置编码)

  • RoPE(旋转位置嵌入)

  • Inference Engine(推理引擎)

  • GPU Kernel(GPU 计算内核)

以及这次我自己最开始也绕了一会儿才真正拆清楚的区别:

“模型已经用不好了”和“系统根本不让模型看到”到底有什么不同?

前两个章节聊的是桌子有多大,以及桌上的东西多起来以后为什么容易眼花。

下一篇终于可以去看看:

桌子边缘那堵墙,到底是谁砌的。

系列文章#

这是「大模型上下文」系列,四篇按顺序读会更顺:

  1. 128K 上下文到底是什么意思?大模型的“记忆容量”可能和你想的不一样
  2. 上下文越长越好吗?为什么大模型“看得见”,却不一定“用得好”(本文)
  3. 为什么 128K 模型塞不进第 128001 个 Token?真正拦住它的可能根本不是模型
  4. 如果不管模型会不会胡说八道,大模型理论上能拥有无限上下文吗?

参考资料#

  1. Vaswani, A. et al. (2017), Attention Is All You Need Transformer 架构的经典原始论文,也是理解 Attention、Query、Key、Value 和 Multi-Head Attention 的基础资料。

  2. Liu, N. F. et al. (2023), Lost in the Middle: How Language Models Use Long Contexts 研究长上下文中关键信息所处位置与模型表现之间的关系,也是 “Lost in the Middle” 这一现象最经典的来源之一。

  3. Bai, Y. et al. (2023), LongBench: A Bilingual, Multitask Benchmark for Long Context Understanding 面向长上下文理解的中英双语、多任务 Benchmark,覆盖单文档、多文档、总结、代码等任务。

  4. Hsieh, C. P. et al. (2024), RULER: What’s the Real Context Size of Your Long-Context Language Models? 在简单 Needle in a Haystack 之外,进一步通过多 Needle、多跳追踪和信息聚合等任务测试模型真正能够利用多长的上下文。

  5. Shi, F. et al. (2023), Large Language Models Can Be Easily Distracted by Irrelevant Context 研究无关上下文如何干扰大语言模型的问题求解过程,很适合用来理解本文提到的 Distractor Interference(干扰信息干扰)。

  6. Du, Y. et al. (2025), Context Length Alone Hurts LLM Performance Despite Perfect Retrieval 研究在相关信息已经能够被正确检索的情况下,仅增加输入长度仍可能造成模型表现下降的现象。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
上下文越长越好吗?为什么大模型“看得见”,却不一定“用得好”
https://kokkoro.me/posts/long-context-why-harder/
作者
Kokkoro
发布于
2026-09-02
许可协议
CC BY-NC-SA 4.0
相关文章智能推荐
1
128K 上下文到底是什么意思?大模型的“记忆容量”可能和你想的不一样
AI日常32K、128K、1M 这些数字常被直觉地当成大模型的「脑容量」,但 Context Window 描述的其实是另一件事。本文从 Context、Token 一路拆到 Context Window 与 Effective Context:它决定的是有多少资料能摆到模型面前,而不是模型有多聪明、或者永久能记住多少东西。
2
如果不管模型会不会胡说八道,大模型理论上能拥有无限上下文吗?
AI日常显存、算力、框架、API 全部不设限,大模型能不能一直往下吃 Token?本文从 O(N²) Attention、KV Cache、Prefill / Decode、FlashAttention 与 PagedAttention 讲到 RoPE 长度外推,最后给出一个更值得追问的方向:长期 AI 需要的也许不是更大的桌子,而是书架和记忆系统。
3
为什么 128K 模型塞不进第 128001 个 Token?真正拦住它的可能根本不是模型
AI日常标称 128K 的模型到了第 128001 个 Token 常常不是「开始胡说」,而是直接拒绝。本文区分 Effective Context Limit 与 Hard Context Limit,从位置编码、RoPE、模型配置、vLLM 的 max_model_len 一路看到 KV Cache 与 GPU Kernel——拦住那个 Token 的通常是整套推理系统。
4
Codex Microsoft Store版启动失败:三个同名 codex 和一个被忽略的 codex.exe
AI日常记录一次 Codex Microsoft Store 桌面版启动失败(Unable to locate the Codex CLI binary)的真实排查:同名 codex.cmd / codex.ps1 / codex.exe 的启动方式差异,如何用显式 CODEX_CLI_PATH 直连已验证的原生 codex.exe 恢复启动,以及 NVM 在其中扮演的角色。
5
Codex 的「调整方向」为什么让我惊为天人:从 Steer 看懂 Agent 是怎么工作的
AI日常从 Codex 的「调整方向(Steer)」按钮出发,扒开 Agent Runtime 源码,讲清楚 Agent Loop、pending input、turn/steer 与 turn/interrupt 的区别,以及 Steer/Queue/Interrupt 三种控制如何重塑人和长任务 Agent 的协作方式。
随机文章随机推荐
Kokkoro
就让身为引导者的我,全力支持主人吧(OxO)
公告
欢迎来到我的博客!希望这里的内容能够帮助到你~
分类
标签
最新动态
站点统计
文章
44
分类
5
标签
110
总字数
121,250
运行时长
0
最后活动
0 天前
站点信息
构建平台
ESA Pages
博客版本
Firefly v6.15.6
文章许可
CC BY-NC-SA 4.0