RAG 已死?当 200K 上下文遇上向量检索
《AI 时代漫游指南》第 45 章·第一条:语义相似和信息相关之间的距离,近到足以让你误以为找到了答案。
🤔 起因:一个灵魂拷问
最近在做投研助手项目时,我实现了一套完整的 RAG(检索增强生成)系统——文档分块、向量化、余弦相似度检索、用户标记权重……整套流程下来,代码写了上千行。
然后有一天,我把一份 50 页的财报直接丢给 Claude,问了同样的问题。
它答得比我的 RAG 系统还准。
编者注:这种被自己代码打脸的感觉,在 AI 时代会越来越常见。习惯就好。
这让我开始反思:向量化 RAG 是不是被过度使用了?
📊 三种信息检索方案
在 AI 应用中,当你需要让模型基于外部文档回答问题时,主要有三种策略:
| 方案 | 原理 | 代表应用 |
|---|---|---|
| 向量化 RAG | 文档分块 → 向量化 → 语义检索 → 喂给 LLM | LangChain、LlamaIndex |
| 长上下文直喂 | 整个文档直接塞进 200K 上下文窗口 | Claude、Gemini |
| 符号搜索 + 局部阅读 | grep 找关键词 → 读取上下文 → 喂给 LLM | Claude Code |
看起来都能解决问题,但实际效果差异巨大。
⚠️ 向量化 RAG 的四个致命问题
问题 1:语义相似 ≠ 信息相关
向量检索的核心假设是:embedding 距离近的内容,语义上相关。
但这个假设经常失效。
比如你问「茅台 2024 年的净利润是多少」,向量检索可能返回:
- 「2023 年净利润同比增长 19.1%」(高相似度,但不是 2024)
- 「五粮液 2024 年净利润达到…」(高相似度,但不是茅台)
- 「公司盈利能力持续提升」(语义相关,但没有具体数字)
而真正的答案「2024 年净利润 123.4 亿元」可能因为表述太简洁,embedding 分数反而不高。
编者注:向量空间里,「答案」和「看起来像答案」的距离,可能比你想象的要近。
问题 2:分块破坏上下文
为了向量化,你必须把文档切成小块(通常 500-1000 字符)。但这个切法会破坏:
- 表格:财报里的财务数据表被切成碎片
- 代码:一个函数被切成两半
- 跨段落推理:「如上所述…因此…」的逻辑链被打断
我在投研项目里用了 1000 字符分块 + 200 字符重叠,但还是经常遇到检索结果缺少关键上下文的情况。
问题 3:维护成本高
一个完整的 RAG 系统需要:
- 向量数据库(Pinecone/Milvus/Qdrant)
- 分块策略调优
- embedding 模型选择
- 同步机制(文档更新时重新向量化)
- 质量监控
这些都是额外的工程负担。
问题 4:信息腐化与时效性盲区
这是最容易被忽视的问题:向量空间不懂「新旧」。
考虑这个场景:
"特斯拉 CEO 是 Elon Musk" → vector_A
"特斯拉 CEO 是 XXX" → vector_B(假设未来换人了)
两个向量可能高度相似,但信息完全冲突。
向量相似度衡量的是语义距离,不是时效性或正确性。
在投资分析场景,这个问题尤其致命:
| 场景 | 向量化的表现 |
|---|---|
| 同一公司多年财报 | 可能检索到 3 年前的数据回答今年的问题 |
| 政策/法规更新 | 新旧版本混杂,模型不知道该信哪个 |
| 人事变动 | ”CFO 是谁”可能返回已离职的人 |
编者注:向量数据库就像一个不会整理书架的图书馆员——新书旧书混在一起,让读者自己猜哪本是最新版。
为什么向量化难解决这个问题?
- 元数据是外挂的:时间戳只能作为 filter,不参与相似度计算
- 更新成本高:改一个事实要重新 embedding 整个 chunk
- 冲突检测难:系统不知道两条信息是「互相矛盾」还是「互相补充」
- 没有「遗忘」机制:旧信息不会自动失效
🚀 长上下文的逆袭
2024 年以来,大模型的上下文窗口爆炸式增长:
| 模型 | 上下文窗口 | 换算 |
|---|---|---|
| GPT-4 Turbo | 128K | 约 300 页文档 |
| Claude 3.5 Sonnet | 200K | 约 500 页文档 |
| Gemini 1.5 Pro | 1M | 约 2500 页文档 |
这意味着:大部分实际场景,你根本不需要 RAG。
一份 50 页的财报?直接塞进去。一个 5 万行的代码库?Gemini 能吃下。
长上下文的优势:
- 不丢信息:模型自己做 attention,不会遗漏重要细节
- 保持上下文:跨段落推理、表格理解都没问题
- 零维护:没有向量数据库,没有同步问题
编者注:当锤子变成推土机,你可能不再需要把墙拆成砖头再搬运。
但长上下文也有局限
- 成本:200K tokens 的输入 = 一次调用约 6 美元(Claude Opus)
- Lost in the Middle:超长上下文时,模型对中间位置的注意力会下降
- 海量文档:如果有 1000 份财报,还是放不下
所以长上下文不是万能解,但它确实让 RAG 在很多场景下变得多余。
🔍 第三条路:符号搜索 + 局部阅读
有趣的是,最顶尖的代码 AI 工具,反而不用向量化。
Cursor:用了向量化。使用 Merkle tree 做代码分块,用 OpenAI embedding 生成向量。
Claude Code:故意不用。完全依赖 ripgrep 做「智能搜索」——纯字符串匹配,没有语义检索。
Claude 工程师在 Hacker News 公开承认:「Claude Code 不用 RAG」。
为什么?因为在代码场景:
- 精确性就是一切:你要找
getUserById函数,grep 能精准定位,向量可能给你一堆「看起来相关」的函数 - 可预测:grep 的结果你知道是怎么来的,向量检索像个黑盒
- 快:ripgrep 在大型代码库上毫秒级响应
更有意思的是,Sourcegraph 的 AI 助手 Cody,之前用 embeddings,后来从架构中移除了。
这说明向量化在大规模代码场景确实有局限。
💡 我的实践:混合策略
回到我的投研助手项目。实现了完整 RAG 后,我发现了一个更好的策略:
纯向量方案(旧)
用户提问 → 向量检索 Top-5 → 喂给 LLM → 回答
问题:检索结果经常不包含关键数据。
混合方案(新)
用户提问
↓
Step 1: 提取关键词/实体(公司名、指标名、年份)
↓
Step 2: 精确搜索找包含这些关键词的段落
↓
Step 3: 如果精确搜索无结果,再用向量做模糊回退
↓
Step 4: 合并结果 + 扩展上下文 → 喂给 LLM
我还加了一个「用户标记权重」机制:
| 标记类型 | 权重倍数 |
|---|---|
| 默认文本 | 1.0x |
| 黄色高亮 | 1.5x |
| 绿色高亮 | 3.0x |
| 红色高亮 | 3.0x |
| 批注 | 5.0x |
用户在阅读财报时标记的重点,在后续搜索时会被自动提权。
这比纯向量相似度更符合实际需求——人类的判断比 embedding 距离更可靠。
📋 什么时候用什么方案?
根据我的实践,给一个决策树:
文档总量多大?
↓
< 100K tokens(约 250 页)
→ 直接长上下文,不用 RAG
↓
100K - 1M tokens
→ 看场景:
- 精确查找(代码、数据)→ grep + 长上下文
- 模糊探索(不知道找什么)→ 向量检索
↓
> 1M tokens(海量文档)
→ 混合策略:关键词筛选 + 向量排序 + 长上下文
场景对照表
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 单份财报问答 | 长上下文 | 50 页塞得下,不丢信息 |
| 代码库找函数 | grep + 局部阅读 | 精确匹配,不需要语义 |
| 100+ 份研报的知识库 | 混合策略 | 太多塞不下,需要筛选 |
| 用户意图模糊的问答 | 向量检索 | 不知道要搜什么关键词 |
| 「帮我发现相关内容」 | 向量检索 | 探索性需求 |
✨ 结论
向量化 RAG 没有死,但它被过度使用了。
在长上下文模型普及的今天,很多场景根本不需要 RAG——直接喂进去更简单、更准确。
对于需要精确匹配的场景(代码、数据),符号搜索 + 局部阅读往往比向量检索更可靠。
向量化真正的价值在于:
- 海量文档(塞不进上下文)
- 模糊意图(不知道要搜什么)
- 发现性需求(「有没有相关的…」)
编者注:在这个 200K 上下文的时代,最好的 RAG 策略可能是——不用 RAG。
你在用 RAG 吗?遇到过什么坑? 欢迎在评论区聊聊你的实践经验。
觉得有用的话,点个「在看」让更多人看到 👇
相关文章
这篇文章对你有帮助吗?
分享这篇文章
引用此文
讨论
这篇文章让你感觉
喜欢这篇文章?
订阅 RSS,第一时间收到新文章推送
私人笔记
仅保存在本地浏览器讨论
评论加载中...