K1.1 从「对字」到「对意思」
老式搜索的两个死穴
想想你平时怎么用搜索框:输入「退货」,系统去找所有含「退货」二字的文档。这叫关键词检索(经典算法是 BM25,几十年来搜索引擎的主力)。它简单、快、可解释——但拿来做 RAG,有两个致命死穴。
死穴一:换个说法就找不到。 用户不会照着你文档里的用词提问。你的手册写「七天无理由退换」,用户却说「买的东西不想要了怎么办」——两句话意思完全一样,却一个共同的字都没有。关键词检索对着字面死磕,直接漏掉。这就是「同义不同字」问题,中文里尤其严重(一个意思有无数种说法)。
死穴二:一词多义分不清。 用户搜「苹果」,他到底想要水果,还是手机配件?关键词检索只认「苹果」这两个字,会把两类文档一股脑全捞上来,分不清语境。
这两个死穴,根子是同一个:关键词检索只会对字,不会对意思。
核心思想:把意思变成坐标
RAG 需要的是语义检索——按「意思」找,而不是按「字」找。怎么做到?答案你在上篇其实已经见过了。
上篇 1.4 节讲过一个神奇的事实:把词变成向量之后,意思相近的词,坐标也相近(「猫」和「狗」离得近,和「汽车」离得远)。语义检索把这个思想放大到整段话:
用同一个模型,把用户的查询和知识库里的每段资料都变成向量(一串坐标)。于是「找意思最相近的资料」,就变成了一道几何题——「找坐标离查询最近的那个点」。
「买的东西不想要了」和「七天无理由退换」,字面毫无重合,但它们的意思几乎一样,所以变成向量后坐标也几乎重合——语义检索一下就能对上。
上手玩:语义 vs 关键词
下面这个「语义搜索台」,把一个小知识库的每段资料摆成了地图上的点(真实向量有几百上千维,这里降到二维好让你看见)。⭐ 是你的查询,它会去找最近的点:
请务必做两个对比实验:
实验一:同义不同字。 默认查询就是「买的东西不想要了」。先切到「🔤 关键词检索」 ——你会看到它一个词都没命中「退货政策」那段(字面零重合),只能瞎排。再切回「🧭 语义检索」——它精准命中了。这一正一反,就是语义检索存在的全部理由。
实验二:一词多义。 选查询「我想买苹果」。关键词检索会把冰糖心苹果(水果)和苹果手机充电线(配件)都捞上来——都含「苹果」二字,它分不清。切回语义检索,它能根据「想买」的语境,把水果排到前面。
面板上那个「相似度」百分比,衡量的就是查询和资料「意思有多近」。它背后的正式指标叫余弦相似度——衡量两个向量方向有多接近的标尺,越接近 1 越像(数学细节见深入层)。
不是。它有一个和关键词检索正好相反的短板:遇到「必须精确匹配」的东西会犯迷糊。用户查产品型号「X9-2000」、订单号、身份证号、某个专有名词——这些要的是一字不差,而语义检索追求「意思相近」,反而可能把「X9-2000」和「X9-3000」当成差不多的东西混起来。这种场景,老实的关键词检索反而更准。所以现实中最好的做法往往不是二选一,而是两个一起用——这就是 K3 混合检索要讲的。另外提醒:实验里的二维坐标是手工构造的概念示意,真实向量有几百上千维,没法直接画出来。
小结
- 关键词检索(BM25)只会「对字」,两个死穴:同义不同字找不到、一词多义分不清。
- 语义检索把查询和资料都变成向量,「找意思最近的」= 「找坐标最近的点」——回扣上篇「意思相近→向量相近」。
- 衡量「意思有多近」用余弦相似度:只看方向不看长度,越接近 1 越像。
- 语义检索也有短板:精确匹配(型号、订单号)反而是关键词的主场——所以现 实常两者并用(K3)。
延伸阅读
- 上篇 1.4 词向量——语义检索的地基,「意思相近→向量相近」的来处。
- Sentence-BERT(2019)——双编码器句向量的奠基工作,语义检索能规模化的关键。
- 下一节 K1.2 向量数据库:知识库有上千万段,怎么在毫秒内找到最近的那几个。