跳到主要内容

长上下文模型 vs. RAG:为什么 1M Token 上下文窗口并非万能

· 阅读需 11 分钟
Tian Pan
Software Engineer

当 Gemini 1.5 Pro 发布并具备 1M token 的上下文窗口时,一波工程师宣布 RAG 已死。这种论点看似无懈可击:既然你可以把整个知识库直接丢进提示词(Prompt)中让模型自己去处理,为什么还要构建一个包含分块器(chunkers)、嵌入(embeddings)、向量数据库和重排序器(re-rankers)的检索流水线呢?

这种论点在生产负载下会分崩离析。Gemini 1.5 Pro 在“大海捞针”(needle in a haystack)基准测试(即隐藏在文档中的单个事实)中实现了 99.7% 的召回率。但在现实的多事实检索场景中,平均召回率在 60% 左右。这 40% 的遗漏率并非基准测试的偏差;而是你的系统在静默状态下未能向用户展示的事实。而且,一个 1M token 请求的延迟比 RAG 流水线慢 30–60 倍,而单次查询成本约为其 1,250 倍。

长上下文模型是强大的工具。它们只是不适合大多数生产环境的检索工作负载。

“迷失在中间”问题是真实且可衡量的

从演示(demo)转向生产环境时,从业者学到的第一件事就是信息在长上下文中的位置至关重要。2024 年 TACL 的论文《迷失在中间》(Lost in the Middle)确立了核心发现:LLM 的性能在整个上下文位置上呈现 U 型曲线。模型对上下文最开始(首因效应)或最末尾(近因效应)的内容关注度最高。在受控测试中,埋藏在中间的相关信息会遭受 20 多个百分点的性能下降。

这并非旧模型的怪癖。Databricks 针对长上下文工作负载对 Llama-3.1-405B 和 GPT-4-0125-preview 进行了基准测试,发现 Llama 在 32K token 后就开始出现明显的性能下降——远低于其宣传的最大值。GPT-4 在准确度开始下降前能坚持到 64K token 左右。“大多数模型在达到其宣传的最大上下文长度之前,准确率就会大幅下降”现在已成为被此坑过的工程师们的共识。

实际后果是:如果你有一个 200K token 的文档,而答案就在中间三分之一的部分,你是在赌博,而基准测试表明这种模型行为是不可靠的。RAG 通过检索相关分块并将其放置在模型真正关注的位置(即更短、更集中的上下文的开头)来规避这一问题。

为什么“大海捞针”测试具有误导性

NIAH 基准测试在长上下文模型的营销中无处不在,它衡量的是真实存在的能力:模型能否定位嵌入在大文档中的特定事实?Gemini 1.5 Pro 得分为 99.7%。令人印象深刻。

问题在于,NIAH 测试的是在干净的草堆中检索单根针。在生产环境中,查询通常需要多个事实。草堆充满了语义噪音——许多内容看起来与查询模糊相关。而且,“针”和问题通常共享词汇,这使得语义相似性在基准测试中起到了利好作用,而现实语料库中并非如此。

NoLiMa 基准变体测试了在针和问题之间词汇重合极小(无字面匹配)情况下的检索。在标准 NIAH 中表现优异的模型在这里通常会失败。NeedleChain 显示,当需要跨多个嵌入事实进行多跳推理时,性能会出现下降。即使是 GPT-4,在这些更难的变体中,当输入超过其宣传容量的 10% 左右时,性能也会出现下降。

结论:如果你的产品演示使用 NIAH 数据来证明放弃 RAG 是合理的,那么你展示的是无法推广的基准性能。请根据你实际的查询分布进行衡量。

成本与延迟的计算

Transformer 的注意力机制随上下文长度呈平方级增长。上下文长度增加一倍,计算量大约增加四倍。缓存 1M token 每个会话需要大约 100GB 的 GPU 显存。这些不是理论上的担忧,而是长上下文缓慢且昂贵背后的数据支撑。

在生产环境的测量中:

  • 一个端到端的 RAG 流水线运行时间约为 1 秒,包括查询编码和向量搜索
  • 处理约 160K token 的长上下文调用大约需要 20 秒;处理约 890K token 时,需要超过 60 秒
  • 长上下文工作负载的生产平均耗时约为 45 秒

在成本方面,GPT-4.1 的输入价格为每百万 token 2.00 美元。一个 100K token 的请求仅输入成本就达 0.20 美元。在 1M token 时,输出前的单次调用成本为 2 美元。RAG 查询的成本约为每次 0.00008 美元。在大规模应用中,单次查询的成本差距约为 1,250 倍。对于处理每天数千次查询的面向客户的应用,这种差异使得长上下文作为主要检索策略在经济上不可行。

有个细节值得注意:如果你反复查询同一个静态文档,KV 缓存(KV cache)复用可以分摊首次调用的成本。但这仅适用于文档和模型会话在多次查询中位于同一位置的部分用例——大多数企业部署并不完全符合这种模式。

长上下文在哪些场景下真正胜出

这并不意味着长上下文模型是个坏主意。对于特定任务集,它们是正确的工具。

全局文档理解。 当任务需要理解横跨整个文档的关系时——例如审查法律合同以查找条款间的不一致,审计大型代码库的安全模式,将完整规范与实现进行对比——分块和检索片段在结构上是错误的。信号存在于各部分之间的交互中,而不是在任何单个分块中。

隐式查询。 RAG 以你能编写查询为前提。当用户问“这份协议中最令人担忧的部分是什么?”时,他们并不知道哪一部分是相关的。长上下文可以发现意想不到的发现;而检索需要知道要寻找什么。

静态小规模语料库。 100K token 以下且不经常变动的数据集是最佳切入点。公司的风格指南、产品的完整规格、一套固定的参考文档——这些可以舒适地放入长上下文中,并从模型原生的注意力机制中受益,而不是依靠分块检索。

一次性分析任务。 法律审查、尽职调查、研究综合——在这些任务中,用户接受 30-60 秒的等待,且成本是次要的。长上下文在延迟 SLO 较宽松的异步批处理工作流中表现出色。

跨单一语料库的多跳推理。 当答案需要连接同一文档不同部分的事实时,基于分块的检索可能会将相关事实分离到不同的检索片段中,从而无法同时呈现。

决定生产环境方案的五个因素

当团队在争论长上下文(Long-context)与 RAG 时,他们通常争论错了重点。真正的问题在于,以下五个主导因素是否倾向于其中一种方案:

语料库规模。 你的总数据量是否能放入上下文窗口中?如果你的知识库有 50GB 的文档,这就没什么好争论的——RAG 是唯一可行的路径。长上下文是上限,而不是下限。

相关性比例。 你的语料库中有多大比例与典型查询相关?如果 90% 的数据与任何给定问题都无关,那么将所有数据全部输入是极其浪费且有害的(会产生干扰效应)。当相关性比例降至约 20% 以下时,RAG 的表现始终优于全上下文堆砌(Context Stuffing)。

延迟 SLO。 这是一个交互式的面向用户的功能(要求 2 秒以内),还是一个批处理/异步工作流?长上下文平均 45 秒的响应时间使其无法胜任对话类应用,无论其准确性如何。

数据新鲜度。 实时和近实时的更新更倾向于使用带有增量索引的 RAG。每当数据变化时就重新加载整个上下文窗口是无法扩展的。静态语料库则更适合长上下文。

查询量。 当每月只有几百次查询时,成本差异只是噪音。而当每天有数万次查询时,1,250 倍的成本差异将成为主导架构设计的核心约束。

新兴的最佳实践:智能路由

在 2025 年,进步最快的团队并没有在这两个方案中二选一,而是在两者之间进行路由。来自 EMNLP 2024 关于 “Self-Route” 的研究表明,让模型反思自己是否需要完整上下文还是针对性的检索,可以在显著降低计算成本的同时提高整体准确性。简单的查询交给 RAG;需要全局理解的复杂多跳(Multi-hop)问题则交给长上下文。

实际实现看起来是这样的:按类型(事实查找、综合、对比、隐性探索)对传入的查询进行分类,估算可能相关的语料库比例,并据此进行路由。维基百科式的事实性问题通常受益于 RAG。需要跨文档综合的任务通常受益于长上下文——前提是文档足够小,能够装得下。

LlamaIndex 的 “Small-to-Big Retrieval”(由小到大检索)模式是一个非常有用的折中方案:为精确检索索引细粒度的分块,然后在推理时扩展到更大的周边上下文窗口。这既能获得 RAG 的检索精度,又能提供比原始分块更多的推理上下文。

上下文过度填充本身就是一种失败模式

有一个值得明确指出的反模式:转向长上下文模型的团队往往会通过检索过度抓取(Over-fetching)来进行补偿。他们不再检索前 3 个分块,而是检索 30 个,理由是“上下文窗口够大”。这是在检索层应用的上下文堆砌反模式。

在上下文中充斥部分相关的内容并无帮助,反而有害。模型的注意力会被无关材料分散,并且对于任何最终处于大型填充上下文中间的内容,都会触发“迷失在中间”(Lost-in-the-middle)效应。在标准基准测试中,采用保持顺序的 RAG 方法处理 4.8 万个精选 Token,其表现比 11.7 万个 Token 的全上下文检索高出 13 个 F1 分数,而 Token 预算仅为后者的约七分之一。

无论你使用 RAG 还是长上下文,这一原则都适用:精选进入 Prompt 的内容。模型的有效注意力是一种有限资源。将其浪费在不太可能对查询有帮助的内容上,从来都不是没有代价的。

这对架构决策意味着什么

对于任何知识检索工作负载,从 RAG 开始。它成本效益高、延迟低、支持在检索层进行访问控制,并提供合规团队可以使用的可审计查询轨迹。为重复或语义相似的查询添加语义缓存——研究表明,对于高重复率的查询模式,这可以降低高达 73% 的成本。

将长上下文留给那些真正需要全局文档理解、延迟和成本处于次要地位、且语料库处于模型可靠性能范围(而非宣传的最大值)内的任务。对于大多数模型来说,实际的上限是 3.2 万至 6.4 万个 Token,而不是新闻稿里的那个数字。

当你在同一个系统中同时拥有这两种用例时,添加智能路由。分类器不需要很复杂——通常针对查询类型和语料库规模的简单基于规则的方法,就足以在 90% 以上的情况下正确路由。

百万级的 Token 上下文窗口确实是令人惊叹的工程成就。但它也是针对特定类别问题的专用工具。将其视为 RAG 的通用替代品,正是导致团队最终面临 40% 的事实遗漏率、45 秒的延迟以及除了构建系统的人以外没人感到意外的 AWS 巨额账单的原因。

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