
“RAG 是不是已经被长上下文淘汰了”——这个问题我最近几乎每周都要回答一遍。社区里风向变得很快新一代模型把上下文窗口从 128K 拉到 1M、甚至 2M 之后很多人觉得“既然模型能记住这么多那还要 RAG 干嘛直接把文档全塞进去不就行了”我的结论先放在这里RAG 没有被长上下文淘汰而且远没有到被淘汰的临界点。长上下文确实解决了一部分问题但与此同时换来了新的麻烦。这几年做 AI 应用落地我见过太多“百万上下文一出、RAG 必亡”的论调说这些话的人要么是被演示效果惊艳到要么没经历过生产环境里延迟、成本、权限控制同时爆雷的现实。这篇文章想把这笔账算清楚长上下文解决了什么、它牺牲了什么、RAG 在其中扮演什么角色以及我自己在 Mac 上搭 RAG 知识库的真实操作复盘。1. 长上下文真有那么神先把瓶颈聊清楚1.1 为什么大家会认为“长上下文能取代RAG”这个念头很自然既然模型输入窗口大了理论上可以把企业内部文档、聊天记录、代码仓库全部塞进提示词让它直接“读”不需要再搞一套切分、向量化、检索的复杂链路。我完全理解这种冲动。在 demo 里长上下文确实很惊艳丢一本几百页的手册进去让模型回答任意细节上下文足够的情况下它基本都能答上来而且不需要你提前想好“该检索哪个片段”。这种体验和 RAG 那种“先检索、再拼装、再回答”的流程比起来确实是降维打击。但做实际系统的人都知道演示和生产的差距从来不在“能不能跑通”而在“能不能持续跑通”。长上下文能取代 RAG 的前提是三个第一你的数据规模真的能塞进上下文窗口第二你有足够的预算支付每轮请求的高昂成本第三你不需要实时更新数据、也不需要控制模型对某些信息的访问权限。这三个前提放到真实企业环境里几乎同时崩塌。另外一个更隐蔽的原因是思维惯性。很多人以为 RAG 就等于是“给模型装外挂硬盘”而长上下文是“把硬盘直接变成内存”所以觉得后者碾压前者。这个类比其实误导性很强。如果你只用“内存大小”来衡量一套系统那长上下文确实赢了但现实系统从来不是只看内存还要看索引、缓存、权限、并发、更新频率。数据库不因为内存变大就消失这个道理放在 RAG 上也是一样的。1.2 当上下文拉到百万级钱和效果都在什么地方吃亏先算一笔最朴素的经济账。当前主流大模型 API 的定价里输入 token 和输出 token 是分别计费的百万级上下文意味着你每轮请求的输入 token 都会非常夸张。比如一位用户在一次对话里就需要消耗 50 万 token 的输入这还只是一个人、一轮对话。如果系统有几百个活跃用户每天产生几十万轮请求这个费用不是线性增长而是爆炸式增长。相比之下RAG 通常每轮只需要把检索出来的几千 token 拼进上下文成本差距可能是两三个数量级。再说效果。长上下文窗口的“有效长度”和“标称长度”之间差距比很多人想象中大得多。业界常说“Lost in the Middle”——模型对长文本中间位置的注意力明显弱于开头和结尾。你或许能把 1000 页 PDF 塞进去但模型更倾向于关注前 50 页和后 50 页中间的关键事实被“淹没”的概率相当高。测试类任务比如大海捞针确实能做得不错但真实业务问题往往不是精确找一句话而是要求把分散在文档不同章节的约束条件组合起来推理这时候长上下文的优势会被严重稀释。响应速度同样是个问题。上下文越长prefill 耗时越长首 token 延迟会变得非常难受。做在线客服、实时问答这类场景用户等不了十秒才看到第一个字。RAG 把输入控制在一个稳定的小规模内延迟相对可控。所以我把两套方案放在同一张表里对比看得更直观维度纯长上下文方案RAG 方案每轮输入成本随上下文长度线性膨胀通常只有检索结果的几千 token数据更新需要维护大量系统提示词或频繁重发重新切分、重新索引即可权限控制很难做到按片段隔离检索层即可控制可见范围响应延迟长输入导致首 token 明显变慢稳定且可预期知识准确度过长内容容易丢失中间关键信息靠检索精度和重排保证引用溯源很难验证来源检索结果自带源文档片段这张表的结论其实很清楚长上下文适合“低频、高预算、不需要实时更新的深度推理”场景而 RAG 适合“高频、低成本、数据频繁变化、需要权限隔离”的业务系统。两者不是同一个生态位谈淘汰根本无从谈起。2. RAG没被淘汰只是换了副面孔2.1 RAG解决的不只是“记不住”更是“最新”和“可控”先明确一点RAG 从来不是为了解决“模型记不住”这一个问题。它的核心价值有三个最新、可控、可溯源。“最新”很好理解。大模型的训练数据有截止时间你不可能为了一个刚发布的政策条文去重新训练模型但 RAG 可以做到当天更新当天生效。比如电商平台的售后政策、金融产品的费率说明这些内容经常变用 RAG 只需要更新知识库里的文档检索链路自动把新版内容带进回答。“可控”指的是权限和数据边界。企业内部场景里不是所有员工都能看到所有资料。直接把全部文档塞进上下文等于把权限问题全部抛给了模型本身这非常危险。而 RAG 的检索层天然可以做权限隔离文档打标签、按用户权限过滤候选片段、再进入生成环节。这些控制在纯长上下文方案里实现起来非常别扭。“可溯源”往往是被低估的。做企业级应用用户不仅要答案还要知道答案依据是什么。RAG 的整个流程里检索回来的片段就是天然的证据链可以在回答里附上“资料来源xxx 文档第几页”。长上下文方案很难做到这一点因为模型是从几百万 token 里的未知位置提取信息你要么自己重新去翻文档要么让模型额外生成一堆解释既不可靠又多花钱。我实际落地时还有一个感受RAG 带来的可干预性更强。如果模型回答错了我可以去查检索链路是不是返回了错误切片可以调整切分策略、换 embedding 模型、改重排逻辑每一步都有明确抓手。而对一个塞满长上下文的黑盒你很难定位问题出在“上下文太长导致注意不集中”还是“文档本身信息有冲突”。2.2 别把RAG等同于向量检索它其实是个系统工程很多人对 RAG 的理解停留在“向量数据库 相似度检索”这其实把 RAG 看小了。一套健壮的 RAG 系统至少包含这些环节文档解析与清洗、切片策略、Embedding 选择、索引构建、查询改写、召回、重排、上下文拼装、生成约束、评估反馈。每个环节都有独立调优空间。文档解析经常被忽略但实际上是翻车率最高的地方。PDF 里的表格、流程图、页眉页脚扫描件的 OCR 结果这些不处理干净后面再怎么调检索都白搭。我自己在 Mac 上做本地知识库时就踩过不少解析的坑后面专门写一节展开。查询改写也很有意思。用户提的问题和知识库里的文档表述往往对不上比如文档里写的是“支持内存扩展”用户问的是“能不能加内存条”。字面相似度不高但语义上又是同一件事。好一点的 RAG 系统会先让一个小模型把用户问题改写成多个检索表达式甚至生成一个假设性答案再用这个答案做向量召回这就是所谓的 HyDE 思路。召回后的重排同样关键。很多人的误区是“Top-K 取最大的几个就完事”实际上向量相似度不能完全代表相关性尤其在中文环境下同义词、嵌套表达、多义实体都会影响排序质量。简单方案是混合召回向量检索跑一路BM25 关键词检索跑一路再把两路结果合并用交叉编码器做重排。这一步的收益往往比换一个大模型更明显。所以你看RAG 不是一个函数而是一条流水线。长上下文是一条“暴力读取”的捷径RAG 是一套精细管理的体系。捷径省事但体系才能长期稳定运转。3. 知识库不是只有一种RAG和图谱各管一摊3.1 向量库、图谱库和结构化表各管什么什么时候用谁聊到 RAG 知识库就必须把“知识库”这个概念拆开。互联网上现在流行的说法太笼统好像所有知识库都能用同一套向量检索搞定。但实际上知识有三种很不一样的形态非结构化文本、结构化关系、半结构化实体。对应的存储和检索手段也完全不同。向量库适合处理非结构化的自然语言片段比如合同条款、岗位说明、客服对话记录。不知道用户会怎么问但知道“意思相近”的内容要多。它的问题在于缺乏逻辑约束纯靠语义向量把几个片段拉出来片段之间是什么关系、谁是谁的上位概念向量库不关心。知识图谱KG处理的是实体和关系比如“A公司是B公司的子公司”“张三在2023年入职C部门”“D产品依赖E组件”。这类问题如果把整段文档切成文本块去检索效率很低因为答案分散在多条关系里需要跨多个片段做推理。图谱用节点和边把结构提前固化下来检索时可以走图遍历比如“找出和 D 产品有依赖关系的所有组件”。结构化表关系数据库/表格处理的是强规则数据比如库存数量、人员名单、订单状态。它和向量检索完全不搭边直接用 SQL 查更快更准。现在有些 RAG 方案会做 Text-to-SQL把自然语言问题转成 SQL 查询再执行查询并把结果返回给模型生成答案。这个思路就是把“知识检索”和“结构化查询”合起来的典型例子。我把三者的适用场景列一下类型核心建模最适合的场景典型产品/方案向量知识库文本块语义向量文档问答、语义搜索、客服辅助Chroma、Milvus、Qdrant知识图谱实体-关系三元组多跳问答、关系推理、风控分析Neo4j、Graph RAG结构化表格行/列/主键精确查询、统计汇总、业务报表数据库 Text-to-SQL顺带把网上特别热的一个问题也回答一下RAG知识库能存储图片吗能但分两种思路。一种是存图片本身的向量表示也就是用多模态模型把图片转成向量检索时按语义召回图片再交还给多模态大模型做理解另一种是只对图片里的内容做结构化提取比如 OCR 表格、图表中的关键数值把这些文本内容存入向量库图片本身并不参与检索。绝大多数实际场景用的是第二种因为图片语义检索在中文环境下准确率还不够稳而且图片素材体积大、索引慢。如果你只是想让模型“看图说话”那要走多模态路线如果你是想让模型“读图里的数据”提取文本进知识库更落地。3.2 从“ontology RAG”看知识库的下一步热词里有个“ontology RAG”很有意思。ontology 就是本体指用形式化的方式定义领域内的概念、属性、关系约束。传统 RAG 只有向量相当于“字面意思聚类”加上 ontology 之后检索系统就知道“客户”和“潜在客户”不只是字面相似而是存在分类和转化关系“订单”有状态字段“退款”触发后必须满足某些条件。把 ontology 引入 RAG本质上就是在给向量检索加约束。好处有两个。第一召回结果会更一致不会出现模型把“短期借款利率”和“长期借款利率”当成一回事这种低级错误因为 ontology 里明确定义了这两个概念是不同的实体且关联不同的数值属性。第二多跳推理能力增强检索可以从一个实体出发沿着 ontology 定义的边走到相关联的实体找到向量检索发现不了的间接关系。不过也别把 ontology 想得太神秘。它落到实践里无非是三步先定义领域实体和关系再对现有文档做实体抽取和链接最后构建一个支持图谱查询的索引层。Mac 本地环境也可以做轻量版比如用 Neo4j Desktop 建一个小图谱或者用更轻的 RDF 库快速搭建原型。我的观点是下一代 RAG 知识库不应该是“向量库”单兵作战而是“向量 图谱 结构化表”混合检索。用户问题来了先判断属于哪一类走不同的检索通道再把多路结果合并重排。这个判断可以交给一个小的路由模型也可以写规则。总之单一模态的 RAG 天花板已经很明显混合检索才是真正能打的方向。4. 实战经验复盘在Mac上搭一个能用的RAG知识库4.1 选型与架构不要迷信框架先定链路说到实操很多人在 Mac 上搭 RAG 知识库第一步就卡在选型上。LangChain、LlamaIndex、Haystack、Embedding 模型、向量数据库五花八门的选项足以让人当场放弃。我的建议是不要先选框架先选链路。你想清楚四个组件就好大模型、Embedding 模型、向量数据库、编排逻辑。Mac 本地环境有个天然优势Apple Silicon 的统一内存架构跑 7B~14B 的量化模型比较舒服。大模型推荐走 Ollama一条命令就能拉起本地接口比如qwen2.5:7b或者llama3.1:8b对中文任务支持都还可以。Embedding 模型可以用nomic-embed-text或bge-m3前者轻量、速度快后者中文效果更好但占用内存多。向量数据库的选择我建议先看“部署复杂度”而不是“功能丰富度”。Mac 本地做原型Chroma 是个非常好的切入点它是嵌入式数据库不需要单独起服务代码里直接调用。等到数据量上来了、多人并发了再切到 Milvus Lite 或者 Qdrant 也顺理成章。FAISS 也很轻但它只是一个索引库没有自带元数据过滤和持久化管理新手容易踩坑。编排逻辑我这里直接略过 LangChain因为它对新手来说过度抽象报错信息也不友好。先写原生 Python 代码更合适逻辑直观排查问题也快。跑通了主流程再考虑要不要用框架封装。4.2 关键环节实现细节切分、嵌入、召回、生成我自己搭的链路非常简单总结成四个环节。切分这是 RAG 系统里性价比最高的一步。很多教程会让新手用固定字符长度切块比如 500 个字符一刀切。这种方式做 demo 没问题但真实文档很容易把一句话从中间砍断。我用的方案是“递归字符切分 段落感知”优先按 Markdown 标题、空行、句号分层先粗切成段落再对超长段落按句子边界二次切分。块大小设置成 400~600 个字符重叠度 10%~20%既保证语义完整又不至于块太多、检索太散。嵌入把切好的块向量化。代码大概长这样import chromadb from chromadb.utils import embedding_functions client chromadb.PersistentClient(path./kb_store) collection client.get_or_create_collection( nameproject_docs, embedding_functionembedding_functions.DefaultEmbeddingFunction() ) collection.upsert( ids[item[id] for item in chunks], documents[item[text] for item in chunks], metadatas[{source: item[source], page: item[page]} for item in chunks] )这里要注意Mac 上如果你选的 embedding 模型很大第一次跑会很慢因为本地 CPU/GPU 推理本来就不如云端的 GPU 集群快。可以把文档分批 upsert加个进度条几百页文档分几次导入每次间隔释放内存。召回对用户问题做向量查询取 Top-K。但别只依赖向量最好加一路 BM25 关键词召回混合。Chroma 自带where元数据过滤可以先把符合权限的文档范围定死再在范围内做相似度查询。召回数量先用 Top-K10重排后再取前 3~5 段进上下文。生成把召回的片段拼进提示词强制要求“只基于提供的资料回答如果资料里没有直接说明不知道”。我看到很多踩坑贴都是没加这句话结果模型过度发挥一本正经地编造知识。提示词的约束比想象中重要这是在生成环节兜住 RAG 下限的关键。prompt f请严格基于以下资料回答问题。 资料中没有的信息请直接回答“资料中未提及”。 资料 {context} 问题{question} 跑通这四个环节一个能用的本地 RAG 就已经成型。整个过程不需要云服务不需要 GPU 服务器一台 Mac 足够。4.3 踩过的坑与排查实录Mac 上搭 RAG我遇到的坑大概能列一屏幕挑几个典型的分享。现象根因处理方法回答看起来与检索内容无关召回质量太差模型只回答了“自由发挥”部分检查切片是否合理调大 Top-K增加重排中文问题匹配不到对应资料Embedding 模型对中文支持不足换 bge-m3 或 m3e对比效果几百页文档导入时内存暴涨一次性向量化全部文本分批 upsert控制每批规模答案经常提到“未提供的资料”提示词缺少强约束提示词中强制限定回答来源同一问题不同人问答案不一致缺少查询改写问题粒度不一致加一层 query rewrite标准化问题表述PDF 表格内容答得乱七八糟解析器把表格拆散了先做表格结构化提取再进切分有两个坑想重点展开。第一个是 PDF 解析。macOS 自带的预览工具能看 PDF但它不会帮你把 PDF 的表格结构保留成文本。我一开始用PyPDF2直接抽取结果表格变成一行行无规律的文本检索回来几乎不可用。后来改成pdfplumber做了表格区域提取效果立刻不一样。如果你的文档大部分是扫描件那还得先接一层 OCR。第二个坑是“能存图片吗”的实践答案。我在知识库里放过产品截图做法是先用 OCR 把截图里的文字提取出来再把文字作为文档内容入库。这样用户问“图上写了什么”时能搜到文字但看不到图本身。如果需要模型分析图片结构就得换成多模态大模型链路那已经不是传统 RAG 的范畴了。这个取舍一定要在项目初期想清楚不然到后期改架构成本极高。5. RAG的瓶颈与长上下文的长板谁都不是谁的终点5.1 现在RAG的真正瓶颈在哪下一步怎么补我不避讳说现在的 RAG 问题也很多。最直接的痛点是“召回决定上限”如果检索环节没找到关键信息后续生成再强也无力回天。而检索质量受制于切分粒度、Embedding 模型、查询表达这三者的匹配程度调优是典型的高投入、非线性回报过程。第二个痛点是“评估困难”。RAG 不像传统软件有明确的输入输出你很难说清楚“这次回答差是因为检索差还是因为生成差”。市面上的评估框架也不少但很多要么过于学术化要么只适合跑分不适合业务。我自己现在的做法是建一个标注集真值问题集每个问题标注期望引用片段上线前跑一轮自动化评估主要看“召回引用是否包含标准片段”和“回答是否忠实于片段”。第三个痛点是“多跳问题弱”。用户问“跟 A 公司合作过的、又出现在我们供应商名单里的企业有哪些”传统 RAG 要么找不到、要么只找到一半。这其实就回到了第 3 节说的知识图谱方案。所以我在做方案选型时会先看问题类型分布如果多跳占比高那就必须往 Graph RAG 走而不是死磕向量检索。下一步的补法我认为是“Agentic RAG”。让系统不只做一次检索而是能根据当前答案决定“是否需要追查更多证据”自动发起第二轮、第三轮检索而且每一步都有中间结果记录可审计可回滚。Mac 本地跑轻量 agent 也是可行的只是要控制好工具调用的轮次和 token 预算。5.2 我的判断长上下文是RAG的补充不是掘墓人最后说一点感性的判断。我在实际项目中验证过“长上下文 RAG”混合用法。最高效的模式是第一轮先用 RAG 召回到少量片段把片段和用户问题一起交给模型得到初步答案同时把当前问题的检索结果作为“轮次上下文”缓存下来。同一会话内如果用户追问细节把缓存历史加进上下文就不需要重新检索。这里长上下文的作用不是替代 RAG而是充当一轮会话的“工作记忆”让模型在追问时保持连贯同时不至于每次都把整库文档塞回来。这个配合用下来成本、延迟、准确率三个指标都明显优于纯 RAG 或纯长上下文。我还想提醒一点关心“替代”不如关心“适配”。如果知识量就几千字、对话频率也低那长上下文确实省事你完全可以直接塞文本。如果知识规模是几百个文档、每天都在更新、还有用户权限差异RAG 仍然是成本更低、更可靠、更符合工程约束的路线。一句话总结我这几年的经验别被“更大窗口”的新鲜感带跑先算清楚你的数据新鲜度、预算和权限约束这三样东西会替你做出正确选择。能把这个三角账算明白的人根本不会被“RAG 是不是被淘汰”这种问题困住。