100 万(1M) token,够塞下整个《三体》三部曲还有剩。当模型能一口吞下你整个知识库,RAG 还站得住吗?
DeepSeek V4 发布了。这次不是参数量的军备竞赛,而是一个更根本的变化:100 万 token 上下文窗口,KV Cache 内存降至上一代的 10%,推理计算量降至 27%。
1M token 什么概念?约 75 万英文单词,或者 50 万中文汉字。《三体》三部曲 1M 上下文窗口差不多也能塞进去。你公司的全部产品文档、你过去一年的 Slack 聊天记录、整个 GitHub 仓库 —— 一次全吞进去。
这让我想起一个尴尬的问题:RAG(检索增强生成)是不是要被埋了?
过去两年 RAG 是解决上下文限制的"标准答案"。现在限制被打破了,那 RAG 存在的意义还剩什么?我的答案是:RAG 不会死,但 RAG 的定义会彻底改变。
01
—
RAG 为什么存在?不只是因为上下文不够
表面上看,RAG 存在的理由很简单:模型一次只能读 N 个 token,而你的文档有 100N 个 token,所以需要先检索再喂。
但实际上,RAG 解决的不只是“能不能”的问题,还有:
成本问题。1M 窗口的注意力计算虽然 V4 用 CSA/HCA(压缩稀疏注意力 / 重度压缩注意力)将推理 FLOPs 压缩到上一代的 27%、KV Cache 压缩到 10%,但这不是免费午餐。把整个知识库每次请求都灌一遍到上下文窗口里?钱包会哭。RAG 本质上是一种 token 预算优化策略——只花成本在真正相关的文档上。
注意力稀释问题。即使模型"能读"100 万 token,它"读得好"吗?DeepSeek V4 论文自己的 MRCR (多轮上下文检索)评测显示,在 128K 以上检索性能就开始下降了。100 万 token 里找一根针,就算能找到,那根针周围的信号也会被海量的噪声稀释。RAG 本质上是一种 信噪比优化策略。
幻觉控制。把全部文档放进上下文,模型自己决定读什么、信什么。但如果你只有 3 篇最相关的文档,模型被“框定”在一个可信范围内。越大的上下文,越难控制模型的注意力走向。RAG 本质上也是一种 回答质量约束策略。
上下文窗口大小的突破,解决的是“能不能”的问题,但“划不划算”、“好不好用”的问题依然存在。
02
—
但 RAG 确实要变了
V3 时代(128K),RAG 的设计逻辑分两个阶段,分别是离线构建阶段与在线查询阶段,如图:
这两个阶段里,每一环的决策都是被上下文限制逼出来的。离线阶段:Chunk 切多长?太小丢上下文,太大塞不下,必须精确调参。在线阶段:top-k 取多少?因为模型只能看 128K,检索结果总量必须严格控制。
到了 V4时代(1M),这个约束松绑了。你可以:
- 不切 chunk 了(或切得很少)。现在可以一次检索返回整篇文档、整个章节,而不是几个指定长度比如 500字长的片段
- 多路召回不纠结了。关键词+向量+图谱,三种策略各自返回 20 条?现在可以把检索结果全塞进去,反正塞得下
- 把检索结果当“索引”而不当“全部内容”。检索到的 chunk 给你指个路,现在可以模型自己去原文里找细节
这意味着 RAG 从“检索+拼接”变成了“检索+导航”。
以前 RAG 是给模型递纸条:这是你要的答案,挑着看。以后 RAG 是给模型递地图:答案在这个区域,自己进去翻。
03
—
新的架构:RAG + 长上下文混合策略
我画一下我认为接下来会出现的标准架构:
架构图说明:
1. 多路检索,系统不再依赖单一的检索方式
- 向量语义检索:搜“意思”相关的(即使字面上没对上)。
- 关键词词频检索:搜“字面”精确匹配的(对专有名词、编号特别有效)。
- 知识图谱检索:搜“逻辑”关系的(比如:A 是 B 的子公司)。
多路检索最大程度保证“召回率”,确保有用的信息不被漏掉。
2. 宽松粗排,而传统 RAG 依赖昂贵的“精排”模型
模型有 1M(百万级)的上下文能力,就没必要在前面把信息过滤得太死,可以把更多疑似相关的资料塞进去,让模型去判断。
3. 给模型带有导航信息的“地图”
- 相关文档全文:提供最完整的背景,避免“断章取义”。
- 相关章节索引:告诉模型哪块信息在哪,方便它快速定位。
- 关键事实摘要:让模型先通过“大纲”扫视全局,建立认知。
4. DeepSeek V4 的1M 上下文
模型像是一个拥有惊人记忆力的研究员,可以一次性读完几本书的内容。它不仅是被动接受投喂,还会自己去原文里找。
5. 自反思闭环
当 DeepSeek 读完现有的“地图”后,发现证据链缺了一环(比如:资料提到了合同,但没写合同的具体金额),模型会通过 Tool Calling(工具调用)主动发信号,系统根据模型提出的新线索,重新回到“多路检索模块”进行二次查询。
以上关键变化在于:
- 给模型的是“地图”而不是“纸条”。检索不再追求精确到“这一段就是答案”,而是给模型标注“可能相关的区域”。
- 传统 RAG 的检索质量完全依赖 embedding 模型和检索策略的好坏。但在长上下文范式下,甚至可以让 deepseek 自己来做二次检索:把所有候选文档的摘要先灌进去,让模型自己判断哪些值得深读。
以下为 128K 上下文情况下 RAG 的示意伪代码:
# ══════════════════════════════════════════════════════════════ # RAG 1.0:V3 时代(128K 上下文) # ══════════════════════════════════════════════════════════════ # ── 阶段一:离线构建(提前做好,只做一次)───────────────────── def build_index_v1(raw_docs: list[Document]) -> VectorStore: # 切块:大小要精心调参,太小丢上下文,太大塞不下 chunks = split_into_chunks(raw_docs, chunk_size=512, overlap=64) # 向量化并存入数据库 vectors = [embed(chunk) for chunk in chunks] return vector_store.save(chunks, vectors) # 构建完成,等待查询 # ── 阶段二:在线查询(每次用户提问时触发)───────────────────── def query_v1(query: str, index: VectorStore) -> str: # 向量检索,top-k 要严格控制(上下文预算有限,不敢开大) query_vec = embed(query) top_chunks = index.search(query_vec, top_k=5) # k 不敢开大,漏了只能认 # 拼接 prompt,小心翼翼地塞进 128K 窗口 prompt = build_prompt(query, context=top_chunks) assert token_count(prompt) < 128000 # 超了就崩 # 一次性生成,结果好不好全靠检索质量 return llm.generate(prompt)
以下为 1M 上下文情况下 RAG 的示意伪代码:
# ══════════════════════════════════════════════════════════════ # RAG 2.0:V4 时代(1M 上下文) # ══════════════════════════════════════════════════════════════ # ── 阶段一:离线构建(提前做好,只做一次)───────────────────── def build_index_v2(raw_docs: list[Document]) -> MultiIndex: # 不再强制切块,保留原始全文结构 documents = [] for doc in raw_docs: text = convert_to_markdown(doc) # 统一转成 Markdown,保留结构 # 预处理目标变了:不是"切成块",而是"加导航信息" documents.append({ "full_text": text, # 原文全文 "title": extract_title(doc), # 标题:帮模型定位 "timestamp": doc.last_modified, # 时间戳:帮模型判断新旧 "source": doc.origin, # 来源:帮模型判断可信度 "summary": llm.summarize(text), # 摘要:帮模型快速扫视 }) # 三路索引并行构建 return MultiIndex( vector=vector_store.build(documents), # 语义检索索引 keyword=bm25_store.build(documents), # 关键词检索索引 graph=graph_store.build(documents), # 知识图谱索引 ) # ── 阶段二:在线查询(每次用户提问时触发)───────────────────── def query_v2(query: str, index: MultiIndex) -> str: # 三路宽松召回,不再纠结 top-k,反正 1M 塞得下 candidates = ( index.vector.search(embed(query), top_k=30) # 语义 + index.keyword.search(query, top_k=30) # 关键词 + index.graph.search(query, top_k=20) # 知识图谱 ) # 粗排去重,标准放宽——构建"地图"而不是"纸条" context_map = deduplicate_and_merge(candidates) # context_map 包含:全文 + 章节索引 + 关键摘要 # 把"地图"交给模型,让它自己导航 prompt = build_map_prompt(query, context=context_map) assert token_count(prompt) < 1000000 # 宽裕得多 # 模型自主推理,必要时 tool call 再查一轮 return llm.generate(prompt, tools=[retriever_tool])
04
—
RAG 2.0:重新定义检索的目的
如果让我用一个比喻:
RAG 1.0(128K 上下文时代):给一个近视的图书管理员递纸条。他只能看清你递过来的那几行字,你必须精准地告诉他:“答案在这一页第三段”。
RAG 2.0(1M 上下文时代):给一个过目不忘的教授指方向。“资料在那个书架上,你自己翻。”教授会自己翻、自己对比、自己关联,甚至发现你都不知道的联系。
这带来了几个新的能力:
- 跨文档推理不再靠运气。RAG 1.0 很难做“文档 A 说 X,文档 B 说 Y,综合判断是 Z”这种跨文档的关联推理。因为 X 和 Y 在不同 chunk 里,被检索到的概率不一样。而在 RAG 2.0 的 1M 上下文 + 宽松检索,X 和 Y 大概率都在上下文里,可以关联后进行跨文档推理。
- 矛盾的发现。当你把所有可能相关的文档都放进上下文,模型能发现“法务部说可以这么做,但合规部说不行”这种冲突。RAG 1.0 只会返回 top-k,很可能只返回了法务部的文档,无法发现这些矛盾结果。
- Agent 的自主探索。DeepSeek V4 这种长上下文模型配合工具调用,可以自己决定“这部分我还需要更多信息,再查一下 XX 文件”。检索从一次性操作变成了智能体化的迭代行为。
05
—
RAG 会往哪走?三个方向
方向一:数据侧,从“精排版”到“灌原文”
现在做 RAG,一半的工作量花在数据预处理上。PDF 解析、表格识别、层级切分、元数据标注……大家卷 chunk 策略卷得飞起。
有了 1M 上下文后,很多文档甚至可以不切了。给模型原始的 Markdown 全文,让它自己去理解结构。预处理从“我怎么切成模型能消化的块”变成“我提供什么元数据帮模型导航”——给文档加标题、加时间戳、加来源标注,让模型自己判断相关性。
方向二:检索侧,从“一锤子买卖”到“多轮检索”
工具调用不再是可选项。模型在回答过程中可以多次调用检索模块:
- 第一轮:用户说“产品定价有问题”,模型检索最近的定价文档
- 第二轮:发现定价改了三次,模型主动问:“查一下这三次修改分别是什么时候?”
- 第三轮:发现最后一次改价对应一场竞品分析会议,模型又去获取会议纪要
以下为多轮检索的示意伪代码:
# ── Multi-step RAG:模型驱动的迭代检索 ─────────────────────── def multi_step_rag(user_query: str, knowledge_base: list[Document]) -> str: context = [] # 累积上下文,随迭代逐步扩大 max_rounds = 5 # 防止无限循环 for round_i in range(max_rounds): # 模型判断:当前上下文够不够回答问题? decision = llm.decide( query=user_query, context=context, # 模型可以选择:ANSWER(直接回答)或 RETRIEVE(再查一次) choices=["ANSWER", "RETRIEVE"] ) if decision.action == "ANSWER": # 上下文已充分,直接生成最终回答 return llm.generate(user_query, context=context) elif decision.action == "RETRIEVE": # 模型自己生成下一轮检索 query(不是用户原始问题) sub_query = decision.next_query # 示例:round 0 → "最新定价文档" # round 1 → "定价三次修改的时间节点" # round 2 → "2024-Q3 竞品分析会会议纪要" new_docs = retriever.search(sub_query, knowledge_base) context.extend(new_docs) # 上下文滚动扩大 # 超出最大轮次,用现有上下文强制回答 return llm.generate(user_query, context=context)
这本质上是把 RAG 从“数据注入模型”变成了“模型驱动检索”——模型是主导者,检索是它的工具。
方向三:成本侧,RAG 是成本决策,不是架构决策
最深刻的变化可能在这里。以前 RAG 是不得不做的,因为在模型上下文里你根本塞不下太长的知识库内容。现在你可以塞下了,但你愿不愿意付这个成本?
通过计算 1M 上下文的推理成本和“多轮检索+迭代”的成本,判断“在把信息喂给模型之前要不要先做一次(或多次)检索过滤”,现在是一个成本优化问题。以下是常见场景及其决策逻辑:
场景 |
推荐策略 |
决策逻辑 |
简单问答 + 少量文档 |
直接使用模型,全塞进模型上下文,一次解决 |
文档量小,灌满 1M 的成本可接受,检索反而多此一举 |
海量文档 + 精确查找 |
先检索,再把相关文档放大 |
全灌成本太高,检索先过滤掉无关内容,再精读 |
Agent 长任务 |
多轮调用检索 + 逐步扩大上下文 |
任务复杂,信息需求随模型推理过程动态变化,一次性灌满既贵又不精准 |
RAG 从架构决策下沉成了成本决策。你不再问“要不要 RAG”,你问的是“这个地方用 RAG 省多少钱”。
06
—
最后
DeepSeek V4 的 1M 上下文不是来杀 RAG 的,是来救 RAG 的。
RAG 被压抑了两年,一直活在 128K 的紧箍咒下。所有的设计都在让步:chunk 大小在让步、top-k 在让步、rerank 策略在让步。不是因为这些设计最优,是因为上下文不够。
现在约束松开了。RAG 真正该做的事情——帮模型在海量信息中找到方向——终于可以好好做了。
所以我的判断:RAG 不会死。但做 RAG 的方式,从 2026 年开始会完全不同。那些还在卷 chunk 分割策略的公司,该抬头看看窗外了。
如果你在做 AI 应用架构,欢迎留言聊聊:你的 RAG 系统里,最被上下文限制拖累的是哪一步?