原文信息
- 原文标题:AI search explained: indexing, retrieval and reranking
- 作者:Dinesh Pandiyan(Thinkmill)
- 发布时间:2026-10-27(文章页面标注,12 min read)
- 原文链接:https://www.thinkmill.com.au/blog/ai-search-explained-indexing-retrieval-and-reranking
- 来源:Hacker News,2026-10-28 北京时间凌晨提交(HN Algolia 当日条目)
这是一篇偏工程实践的解释性文章。作者没有停在“向量数据库很厉害”这种层面,而是用同一份只有十条笔记的小数据集,把文本搜索、嵌入搜索、嵌入搜索加重排三种方案跑了一遍,逐条对照结果,指出各自在哪里失效。这种写法比抽象讲原理更有说服力。
一句话总结
组织知识散落在 Slack、邮件、工单、Wiki、CRM 里,关键词搜索只能匹配“字面相同的词”,嵌入搜索能匹配“意思相近的说法”,但真正决定结果能不能用的,往往是最后一层重排——而重排的前提,是召回阶段没有漏掉关键内容。
文章到底在解决什么问题
文章开头举了一个很具体的例子:一家自行车公司的产品经理想知道“客户为什么要求退款”。答案其实已经在数据里了——工单里写着刹车线断了,邮件里提到电池跑不到标称续航,Slack 里有人说三位客户因为刹车问题要退钱。但这三条信息分散在三个系统、由三个人用不同措辞写下,没有一条完整地出现“refund”这个词。
如果只搜“refund”,你会拿到退款政策、退款操作指南,以及那封确实提到退款的邮件;但刹车线断裂的工单和 Slack 里的讨论会被漏掉。结果看起来完整,实际上没有回答“为什么”。
作者把问题归结为一句话,这也是全文的出发点:
“The problem isn't that the data is missing or incomplete. The problem is that search looks for word matches, and people often describe the same thing using different words.”
中文意思是:问题不在于数据缺失或不完整,而在于搜索是按字面词匹配的,而人们常常用不同的词描述同一件事。
三种检索方式,分别解决了哪一层
1. 文本搜索:快、可解释,但只认字面
文本搜索的写路径是“分析器 + 倒排索引”:文档被切词、转小写、去停用词、做词形处理,然后每个词进入倒排表,指向包含它的文档 id。读路径用同一个分析器处理查询,取出各词的倒排表、合并、排序。生产系统里常见的 BM25 会进一步考虑词稀有度和文档长度。
它的优点是快、稳定、可解释——你能清楚说出“为什么这条结果被召回”。但它只能匹配相同或高度相似的词。文章里的例子很典型:搜 “money back” 只能找到 Slack 那条,搜 “equipment failures” 一条都找不到,尽管三条笔记说的就是设备故障。
同义词表能缓解一部分问题,但作者很直接地指出,那会变成维护一个不断膨胀的词库,而且仍然覆盖不了改写和误配。
2. 嵌入搜索:匹配“意思”,但未必匹配“这个问题”
嵌入搜索把分析器换成嵌入模型,把倒排索引换成向量数据库。每篇文档被压成一个定长向量,语义相近的文本在向量空间里靠得更近;查询也走同一个模型,用余弦相似度找最近的向量。
这一步的效果立竿见影:搜 “equipment failures” 能同时召回刹车故障、断裂的线缆和电池问题,搜 “stock shortages” 能找到缺货的仓库通知。文本搜索漏掉的语义,被补回来了。
但作者没有停在这里,而是指出了嵌入搜索的第二个问题:它衡量的是“这篇文档在讲什么”,不是“它能不能回答这个问题”。 当查询是 “why are customers asking for refunds?” 时,排第一的是“如何办理退款”的操作指南,真正解释原因的两条反而排在后面,甚至一条与退款无关的续约记录也进了前五。
这是很多 RAG 系统会踩的坑:召回看起来“语义相关”,但排序不对,模型拿到的上下文顺序就是错的。
3. 加 reranker:在候选里重新判断相关性
重排的思路很朴素:先让嵌入搜索召回一个较小的候选集(文章里是前五条),再让另一个模型把“查询 + 每条候选”一起读,逐对打相关性分数,按分数重新排序。
效果是明显的:原本排第三的“电池续航不足导致退款”升到第一,原本排第一的“如何退款”降到第三,无关的续约记录掉到最后。同样是五条结果,顺序变了,可行动性完全不同。
但文章特意强调了一个边界,这也是我认为最值得记住的一句:
“It's important to remember that a reranker can only sort the results it's given.”
中文意思是:重排器只能对它拿到的那批结果排序。如果索引阶段漏了重要属性,或者嵌入召回根本没把关键内容捞进来,那么重排之后依然会漏。
换句话说,召回决定上限,重排只决定顺序。 很多团队把效果不好归因于“reranker 不够强”,但真正的问题可能出在切分、索引字段、召回数量,甚至数据本身没被采集进来。
文章给出的落地建议
作者最后给了一个很务实的组合:生产环境里,文本搜索和“嵌入 + 重排”通常是一起跑的。常见做法是混合检索(hybrid search):文本和向量并行召回,用 reciprocal rank fusion 合并两个列表,再对合并后的候选做重排。
这样分工很清楚:
- 文本搜索负责 SKU、订单号、错误码、人名这类“必须精确匹配”的内容;
- 嵌入搜索负责用户用自己的话描述需求、跨系统不同措辞的场景;
- 重排负责把“最相关”的结果顶到前面,尤其在 RAG 只取前几段上下文时,顺序直接影响答案质量。
文章还提醒,重排不是免费的:读路径上每个候选都要过一次模型调用,成本和延迟都会增加,所以候选集不能无限大。
我的评论
这篇文章最打动我的地方,是它没有把三种方案讲成“逐级替代”,而是讲成“逐级补位”。文本搜索不是落后的东西,嵌入搜索也不是万能药,重排更不是效果差的遮羞布。三者解决的是不同层的问题,混在一起谈“哪种搜索更好”没有意义。
几个我会带走的判断:
第一,先看召回,再看排序。 如果关键文档根本没进候选集,调 reranker 的参数是徒劳的。排查顺序应该是:数据有没有被采集 → 切分和索引字段是否合理 → 召回数量够不够 → 最后才是重排模型。
第二,“语义相似”不等于“问题相关”。 嵌入模型擅长判断主题接近,但不擅长判断“这段内容是否回答了用户的疑问”。这正是 reranker 存在的理由,也是为什么 RAG 里不能只做向量召回。
第三,混合检索不是妥协,而是默认解。 精确匹配和语义匹配各自有盲区,RRF 融合再重排,比单押一种方案稳得多。代价是系统复杂度和延迟上升,需要根据场景权衡。
第四,文章的数据集很小,结论要带着这个前提看。 十条笔记的演示很适合讲清机制,但真实环境的噪声、长文档切分、多语言、权限过滤,都会让问题复杂一个量级。尤其是中文场景,分词、同义词和嵌入模型的选择,都会显著影响召回质量,不能直接套用英文示例的结论。
如果要给这篇文章定一个适用边界:它适合正在设计企业知识库、RAG 检索链路,或者困惑于“为什么向量搜索效果不稳定”的工程师。它不适合想找“哪个向量数据库最好”的人——文章刻意回避了产品选型,聚焦的是机制。
版权说明
本文为个人精读笔记,不是原文翻译,也未大段照搬原文。文中引用的英文原句仅用于说明观点,版权归原作者 Dinesh Pandiyan 及 Thinkmill 所有。原文链接见文首,建议阅读原文获取完整图表与交互演示。本文的观点评述部分为个人理解,与原作者及 Thinkmill 无关。

评论