RAG 的上限,很多时候不是由模型决定的,而是由检索决定的。
大家好,我是十三!欢迎来到十三Tech。
这两年,向量检索几乎成了所有 AI 应用里的标准配置。只要一提知识库、一提企业问答、一提 RAG,大家的实施路径往往都很一致:切块、embedding、入向量库、相似度召回、拼上下文、交给大模型生成答案。
这条链路看起来很完整,Demo 也通常不难跑通。
但真正到了生产环境,很多团队很快就会遇到一种非常熟悉的挫败感:
- 文档明明已经入库,系统却总是召回不到真正有用的内容
- 用户的问题明明很清楚,返回的上下文却经常似是而非
- 模型明明已经足够强,最终回答却总像“沾了边,但没有答到点上”
这类问题如果只看表面,很容易被归因到模型能力不够、prompt 没写好,或者知识库数据还不够多。
但如果从系统链路往前追,我的判断一直很明确:
绝大多数 RAG 效果差,问题并不首先出在生成层,而是出在检索层。
更准确地说,是出在大家对“向量检索到底在解决什么问题”这件事,理解得还不够深。
所以这篇文章,我想讲的不是一套泛泛的 RAG 入门流程,而是一个更关键的问题:为什么很多系统明明已经接入了向量检索,最终却还是答非所问?
因为只有把这个问题想透,你才会真正理解:向量检索不是一个装上就会自动生效的组件,而是整个 RAG 系统里最容易被低估、也最决定上限的一层。
Part 1:向量检索真正解决的,不是“存文档”,而是“找语义上相近的信息”
先说一个最容易被忽略的事实:
向量检索不是数据库的替代品,也不是全文检索的简单升级版。
它解决的问题非常具体:
当用户的问题和原文没有使用完全相同的词,但表达的是同一件事时,系统能不能仍然把相关内容找出来?
这件事为什么重要?因为自然语言本身就是高度多样化的。
比如一篇内部文档写的是:
“订单确认前需完成客户信用额度校验。”
用户提问时却可能说:
“为什么有时候销售下单会被系统拦住?”
这两个句子从字面上看,重合词并不多。你如果只靠关键词匹配,很可能根本连不上。但从业务语义看,它们讨论的是同一个问题:订单流转为什么会在某个环节被阻断。
向量检索的意义就在这里。
它试图把“这段文本在说什么”压缩成一组高维数值表示,也就是 embedding。然后在向量空间里,不再比较字面词汇,而是比较语义距离。
所以,向量检索最本质的一句话可以概括为:
它不是在找“长得像”的文本,而是在找“意思接近”的文本。
这也是为什么它会成为 RAG 的基础设施。因为大模型要想答得好,前提不是“上下文很多”,而是“上下文相关”。
Part 2:为什么关键词检索不够,而向量检索又不能包打天下?
很多人第一次接触向量检索时,容易走向另一个极端:既然语义检索这么强,那是不是以后关键词检索就没用了?
答案也是否定的。
2.1 关键词检索擅长“精确命中”
关键词检索最擅长的是:
- 专有名词
- 产品型号
- 错误码
- 表名、字段名、接口名
- 法条编号、合同编号、单号
比如你问:
inventory_reserve这个字段是干什么的?- 错误码
E2034是什么意思? - 合同
PO-2025-0912对应哪个流程?
这些问题的关键不在“语义接近”,而在“精确匹配”。这时 BM25、倒排索引、全文检索,往往比纯向量检索更稳。
2.2 向量检索擅长“表达变化下的语义召回”
向量检索的长处恰恰在另一边:
- 同义表达
- 口语化提问
- 问题抽象层级不一致
- 原文与提问词面重叠很少,但语义相关
它更像一种“跨表达方式找同一件事”的能力。
2.3 真正的工程现实,往往是混合检索
所以,从工程实践看,成熟系统通常不会问“关键词检索和向量检索二选一”,而是会问:
哪类问题更适合 lexical recall,哪类问题更适合 semantic recall,如何把两者结合起来?
这也是为什么真正稳定的知识库系统,最后大多都会走向 hybrid search。
原因很简单:
- 关键词检索保证精确性下限
- 向量检索提升语义召回上限
一个负责不漏掉“名字”,一个负责不错过“意思”。
只靠其中一边,通常都不够。
Part 3:向量检索的核心原理,并不复杂,但很容易被用错
如果把技术细节压缩到最小,向量检索可以拆成四步:
- 切分文本:把长文档拆成可以被检索的片段
- 生成向量:用 embedding 模型把每个片段映射到向量空间
- 建立索引:让相似向量的近邻查找足够快
- 查询召回:把用户问题也向量化,然后找最接近的若干片段
听起来并不复杂。真正麻烦的地方,不在“会不会做”,而在“每一步到底该怎么做才不会把效果做坏”。
3.1 文本切块,决定了你究竟在检索什么
很多项目一上来就谈向量库、ANN、索引参数,结果最先出问题的,反而是最朴素的切块策略。
因为你检索的最小单位,不是整篇文档,而是 chunk。
这意味着:
- chunk 太大,语义混杂,召回结果会发散
- chunk 太小,信息不完整,召回结果会碎片化
- chunk 边界切错,关键上下文会被硬生生截断
举个很现实的例子。
如果一份 ERP 设计文档里,把“销售订单校验规则”“信用额度控制”“发货前冻结库存”全切进同一个大块里,那么当用户只问“为什么订单无法确认”时,检索可能把一大坨混杂信息一起召回,最后模型也很难判断哪个才是主因。
反过来,如果你把文档切得过碎,只剩一句“需校验信用额度”,那模型又缺少前后语境,不知道这个规则发生在哪个流程阶段、由哪个角色触发、失败后系统表现是什么。
所以我一直认为:
切块不是预处理细节,而是检索系统的建模动作。
你怎么切,本质上决定了系统以后如何理解知识。
3.2 embedding 不是“编码文本”,而是在定义相似性
很多人把 embedding 理解成“把文本转成数字”,这当然没错,但还不够。
更准确的理解应该是:
embedding 模型在定义,什么叫做“相似”。
不同模型对相似性的刻画方式并不完全一样。有些更擅长通用语义,有些更适合代码,有些对中文业务文本效果更稳,有些在长句或术语密集场景下表现会明显下降。
这意味着一个非常现实的问题:
不是所有 embedding 模型,都适合你的数据分布。
如果你的语料主要是企业制度、流程说明、字段定义、内部 SOP,而你却用一个更偏通用互联网文本的 embedding 模型,检索质量很可能天然受限。
所以 embedding 这一步,不是“选个热门模型就结束了”,而是要看:
- 你的文本类型是什么
- 你的问题类型是什么
- 你希望相似性更多地体现在哪个维度
向量检索效果好不好,很多时候不是因为数据库快不快,而是因为“相似性定义”一开始就偏了。
3.3 向量库不是重点,索引策略才是重点
很多产品介绍喜欢把焦点放在“用了哪个向量数据库”,但从实际落地看,数据库品牌通常不是第一问题。
更关键的是:
- 你用的是精确检索还是近似最近邻检索
- 召回时的 topK 怎么设
- 索引参数如何权衡速度与精度
- 数据更新后索引如何维护
向量检索之所以能在大规模数据上工作,本质上依赖的是 ANN(Approximate Nearest Neighbor)。
它的核心思想不是“绝对找到最相似的”,而是“在可接受时间里,尽量找到足够相似的”。
这句话很重要,因为它意味着:
向量检索天然是一种概率型召回,而不是精确型查询。
一旦你忘了这一点,就很容易对系统抱有错误预期。
Part 4:为什么很多 RAG 项目效果差?问题通常不在“检索不到”,而在“检索错了”
我看过不少团队做 RAG,最常见的误判是:只要能搜出一点相关内容,就觉得检索没问题。可真正影响回答质量的,往往不是有没有结果,而是结果是否对路。
这里面最常见的坑,我总结为四类。
4.1 把“语义相关”误当成“回答充分”
向量检索很容易召回“相关但不够用”的内容。
比如用户问:
“为什么审批通过了还不能付款?”
系统召回一段“付款前需完成发票校验”的片段。这段内容不能说错,确实相关,但它没有直接回答当前问题的关键:审批通过后,还有哪些前置条件没有满足。
于是模型会基于一个“擦边相关”的片段,生成一段看似合理但其实没有击中问题核心的回答。
这类错误最危险,因为它不像完全答非所问那样容易被发现,反而更像“差一点就对了”。
4.2 把切块后的片段,当成独立真相
文档切块之后,每个 chunk 都只是上下文中的一个局部视角。
如果系统召回时不补足邻近片段、不做上下文拼接,那么模型看到的就不是知识,而是知识碎片。碎片当然可以参与推理,但它很难稳定支撑完整回答。
所以一个成熟的 RAG 系统,通常不会只做“召回哪几个 chunk”,还会做:
- 邻接片段扩展
- 文档级聚合
- 标题与结构信息补全
- 段落层与章节层的多粒度拼装
否则你喂给模型的,往往只是“局部正确但整体失真”的证据。
4.3 只做召回,不做重排
很多系统在 topK 召回后,直接把前几个 chunk 塞进 prompt,就结束了。
这是一个非常常见的工程偷懒点。
因为向量召回解决的是“从海量候选里先捞一批大致相关的”,但它不一定擅长在这批候选中排出最适合当前问题的顺序。
这时 rerank 的价值就出来了。
rerank 本质上是在更小候选集上,重新判断:
- 哪段最直接回答问题
- 哪段只是背景材料
- 哪段虽然相似,但噪声更大
在很多场景里,有没有 rerank,往往比 topK 从 5 调到 10 更影响最终答案质量。
4.4 混合语料不分层,最终谁都检不准
还有一种问题在企业场景里特别常见:
你把制度文档、产品手册、会议纪要、聊天记录、接口文档、FAQ 全部塞进同一个向量库,然后期待一个统一检索层搞定一切。
这通常会出问题。
因为不同语料的表达风格、信息密度、权威性和适用范围完全不同。会议纪要里的一个临时讨论,不应该和正式制度拥有同样的话语权;两年前的 FAQ,也不应该和当前版本的产品手册被等量看待。
所以在生产环境里,向量检索往往不是“一个大库 + 一个 topK”这么简单,而是要做:
- 数据源分层
- 时效性控制
- 权威等级排序
- 租户或业务域隔离
如果这些边界不先立住,检索系统就很容易变成一个语义上看似聪明、实际却经常给错依据的混合池。
Part 5:从工程视角看,向量检索真正决定的是 RAG 的上限
很多人做 RAG 时,把更多注意力放在 prompt、模型选择和输出样式上。这些当然重要,但如果从系统链路上看,我的判断一直很明确:
生成层决定回答长什么样,检索层决定回答有没有机会答对。
而向量检索,恰恰位于这个机会的入口处。
你可以把一条典型 RAG 链路理解成下面这样:
原始文档
↓
清洗与切块
↓
embedding 向量化
↓
向量索引 / 混合检索
↓
召回候选集
↓
rerank 与上下文组装
↓
大模型生成答案
在这条链路里,越往后越像“表达层”,越往前越像“事实供给层”。
如果前面的事实供给已经偏了,后面的大模型再聪明,也只是基于错误证据进行高质量表达而已。
这也是为什么很多团队会产生一种错觉:
模型说得很流畅,但总感觉不够对。
本质原因往往不是模型会不会说,而是检索层给它的材料,本来就没有真正击中问题。
所以从工程角度看,向量检索不是一个锦上添花的模块,而是 RAG 可信度的地基。
Part 6:如果让我给团队一套落地建议,我会优先做这几件事
如果你正在做知识库问答、企业搜索或 RAG 系统,我的建议不是先去比哪家向量库更快,而是先把下面几件事做扎实。
6.1 先定义问题类型,再设计检索策略
不要假设所有问题都适合同一套检索方式。
至少先区分:
- 精确问法:字段、编号、接口、错误码
- 语义问法:概念解释、原因追问、流程判断
- 复合问法:既要查事实,又要做归纳
问题类型不同,检索策略就应该不同。
6.2 认真对待切块,而不是随手按字数截断
切块时至少要考虑:
- 是否保留标题层级
- 是否保留段落边界
- 是否保留表格、列表、代码块等结构信息
- 是否需要 overlap
- chunk 长度是为 embedding 服务,还是为回答服务
这一步做得粗糙,后面很难补救。
6.3 让召回、重排、组装成为三段式,而不是一步到位
一个更稳的思路通常是:
- 第一段:广撒网召回候选
- 第二段:重排筛出最相关内容
- 第三段:按问题组织成适合模型阅读的上下文
不要把“搜出来”和“能回答”当成同一件事。
6.4 为检索建立评估集,而不是只看 Demo 手感
很多团队做 RAG,评估方式基本是“我问几个问题,感觉还行”。这在早期探索可以理解,但一旦要进生产环境,这种方式远远不够。
你至少需要一组稳定的评估样本,去衡量:
- 是否能召回正确片段
- 正确片段的排序是否足够靠前
- 不同数据源是否会互相污染
- 某次切块或 embedding 调整后,效果是变好还是变差
RAG 系统一旦没有检索评估,优化过程基本只能靠感觉。
而靠感觉调检索,往往是最慢、也最不稳定的方式。
总结:向量检索不是“把文本塞进库里”,而是在为模型准备证据
最后,把全文压缩成一句最值得记住的话:
向量检索的本质,不是存储知识,而是以语义方式为模型寻找证据。
这句话如果你真正理解了,很多工程判断都会随之清晰:
- 为什么切块这么重要
- 为什么 embedding 不是随便选一个就行
- 为什么 hybrid search 经常比纯向量检索更稳
- 为什么 rerank 往往比盲目加 topK 更有效
- 为什么很多 RAG 失败,看起来像生成问题,实际是检索问题
所以,如果你正在做 RAG,我非常建议把关注点从“模型够不够强”适度往前挪一层,先认真看一眼你的检索链路。
因为很多时候,真正决定系统上限的,不是模型最后说得多漂亮,而是你最开始有没有把对的材料交给它。
写在最后
向量检索并不神秘,它也不是一个装上就会自动生效的银弹。它本质上是一套关于“相似性如何定义、证据如何召回、上下文如何供给”的工程机制。
理解这件事之后,你会发现 RAG 的难点从来不只是大模型,而是如何把知识组织成一个可被机器稳定使用的检索系统。
这,恰恰才是很多 AI 应用真正的护城河。