# 类似此内容的演变

经典全文搜索中类似此内容的工作原理，嵌入式向量如何改变，以及为什么这种查找方式在搜索引擎内部更便捷。

在许多搜索场景中，用户并非从空查询框开始，而是从现有结果出发。

用户打开一篇文章并希望找到相关内容。买家查看产品卡片并寻找相近替代品。支持工程师调查事件并希望查看具有相同症状的早期案例。在所有这些情况下，用户已经拥有一份相关文档作为起点。

这种场景传统上被称为**类似此内容（MLT）**：一种查找与选定文档相似文档的功能。在本文中，MLT指的是从已知文档开始搜索，而非从新输入的查询开始。

经典MLT方法，或称为相似文档搜索，基于比较文本匹配。现代实现越来越多地使用嵌入式向量：文档的数值表示。搜索索引将嵌入式向量存储为向量，搜索系统可以查找具有相近向量表示的文档。

## 简要术语表

为了避免在全文中重复定义，以下是主要术语：

术语 | 本文中的含义
--- | ---
类似此内容（MLT） | 从已选文档中搜索相似文档
嵌入 | 文本、产品、图像或其他对象的数值表示
嵌入向量 | 对象（如文本或产品）的数值表示，存储在索引中以通过向量接近性查找相似对象
KNN，最近邻搜索 | 寻找最近邻，即向量相近的对象
ANN，近似最近邻 | 近似最近邻搜索；它在大型数据集上加速KNN，而无需扫描每个向量
RAG，检索增强生成 | 一种方法，搜索系统为生成模型检索上下文
混合搜索 | 在一个场景中结合全文搜索和向量搜索
重排序 | 使用更精确的模型或规则对已检索的候选结果进行额外排序

## 经典类似此内容的实现方式

经典MLT是基于词汇的。它回答了一个简单的问题：哪些文档使用了相似的重要词语？

通常流程如下：

1. 搜索系统获取源文档。
2. 它分析其文本。
3. 它选择信息性术语。
4. 它从这些术语构建查询。
5. 它搜索具有相似词语集的文档。
6. 它返回相似文档列表。

内部使用了熟悉的全文搜索机制：TF-IDF或BM25、术语频率、停用词、字段加权和文档频率限制。这就是为什么较早的MLT实现暴露了诸如`min_term_freq`、`min_doc_freq`、`max_doc_freq`和`max_query_terms`等参数。

这不仅仅是一个界面元素，而是一个完整的搜索机制。MLT用于相关文章和产品、重复检测、支持工单匹配、法律搜索、专利研究和内部知识库。

## 词汇方法仍具优势的场景

当特定词语、标识符和稳定表述至关重要的时候，词汇MLT表现良好。

示例：

- 错误代码；
- 产品SKU；
- 零件编号；
- 函数名称；
- 堆栈跟踪；
- 法律措辞；
- 几乎相同的商品或工单描述。

原因在于此处精确匹配至关重要。如果两个事件报告包含相同的错误代码或相同的堆栈跟踪，全文搜索会直接匹配。例如，当搜索代码为`ERR_404`的工单时，词汇MLT会快速找到所有提及该代码的工单，而向量搜索可能会返回描述类似但不完全相同问题的工单。

词汇MLT还有另一个优势：运行成本低廉。倒排索引已经存在于搜索引擎中。分析器已经配置。排序已经生效。无需部署单独的搜索基础设施来支持“查找相似”功能。

限制也很明显。如果两篇文档用不同词语描述相同内容，词汇MLT可能无法将它们关联起来。同义词效果不均。改写更困难。跨语言相似性通常不可用。例如，`内存泄漏`和`无界堆增长`可能描述相同问题，但标准分析器会看到不同的标记。

词汇MLT高效查找具有匹配或相似措辞的文档。语义搜索在含义匹配而非词语匹配时提供帮助。

## 嵌入式向量带来的变化

使用[嵌入式向量](/blog/vector-search-deep-dive/)——文档的数值表示——改变了比较原则：系统不再比较词语，而是比较向量表示。

文档不再需要仅表示为加权术语的集合。它可以存储为密集向量。相近的向量通常对应于在含义上相似的文档，即使它们用不同的词语书写。

词汇方法通过词语和术语寻找匹配，而嵌入式搜索则关注文档向量表示的接近性。第一种方法适用于精确匹配，如错误代码和SKU。第二种方法可以找到语义相近的文档，即使它们的表述方式不同。

这扩展了此类搜索的范围。您不仅可以比较文章，还可以比较产品、图像、代码片段、用户事件或RAG系统中的上下文片段。在RAG中，搜索系统首先检索相关上下文，然后生成模型使用该上下文生成答案。

词法搜索不会消失。精确的错误代码、SKU、名称、法规引用和近似重复项仍然更适合通过词法处理。这就是为什么生产系统通常使用[混合搜索](/blog/hybrid-search/)：全文搜索提供精确匹配，向量搜索通过语义添加结果，过滤器限制搜索空间，重新排序优化最终顺序。

如我们在[词法搜索与向量搜索的对比](/blog/lexical-search-vs-vector-search/)中所示，前者在精确严格匹配上占优，而后者则提升了语义关系的覆盖范围。

## MLT 作为从索引中通过向量查找

如果文档的向量表示已经计算并存储在索引中，现代 MLT 可以无需单独的 API 示例进行描述：

1. 获取源文档。
2. 从索引中检索其预计算的向量表示。
3. 查找最近的向量。
4. 返回这些向量所属的文档。

这仍然是“类似此文档”：用户从一个文档开始，获取相关结果。仅比较方法发生了变化。与提取术语不同，搜索系统使用源文档的向量表示。

在 Manticore Search 中，此操作可以直接在搜索引擎级别执行：查询指定源文档的 ID，Manticore 从索引中获取其嵌入向量并运行 KNN 搜索。应用程序无需单独获取向量、序列化数百或数千个数字，并在第二次请求中发送回来。

一个最小的 SQL 示例如下：

```sql
SELECT id, title, knn_dist()
FROM products
WHERE knn(embedding, 10, 123)
LIMIT 10;
```

此处，`embedding` 是存储预计算嵌入向量的字段，`123` 是源文档的 ID，`10` 是要返回的最近文档数量。`knn_dist()` 函数返回向量之间的距离：较小的值表示与源文档的语义接近度更高。通过 HTTP JSON API 也可以执行相同操作；搜索逻辑不会改变。应用程序传递文档 ID，Manticore 使用该文档的索引向量进行查找。

对于大型数据集，KNN 通常通过 ANN 索引实现。这通过近似计算加速搜索并避免扫描每个向量。对于用户而言，重要的是索引的内部结构，而不是结果：快速找到与源文档在语义上接近的文档。

## 为什么搜索更适合在引擎中处理

你可以在应用程序中实现此场景：首先获取文档，然后提取其向量，然后发送单独的 KNN 查询，最后将结果与过滤器结合。

这种方法使系统架构更加复杂。应用程序需要：

- 在服务之间传递向量；
- 防止意外记录；
- 检查嵌入模型版本；
- 保持数据与主索引同步；
- 应用与正常搜索相同的过滤器。

当搜索系统自行执行查找时，路径更短：

1. 应用程序传递源文档的 ID。
2. 搜索系统在索引中找到预计算的向量表示。
3. 搜索系统运行最近邻搜索（KNN）或其近似变体（ANN）。
4. 搜索系统返回找到的文档，同时应用相同的访问过滤器和元数据。

这种方法的优势：

- 应用程序的跨服务请求更少；
- 大向量无需通过外部 API 传输；
- 过滤器保持靠近搜索；
- 结果更容易复现和调试；
- 应用程序无需额外的相似性计算层——所有操作都在搜索引擎内部完成。

这不会解决嵌入质量差的问题或消除调整排名的需要。但它减少了搜索链中交互组件的数量，使系统更易于维护。

## 实际示例与 MLT 的演变

从现有对象进行搜索在用户已找到相关起点时特别有用。

| 场景 | 源对象 | 要查找的内容 |
|---|---|---|
| 支持 | 包含错误的工单 | 过去具有类似症状和相关修复的工单 |
| 目录 | 产品卡片 | 接近的替代品、类似型号或同一类别的产品 |
| RAG | 已通过首次搜索找到的相关片段 | 上下文扩展：同一文档的相邻部分、相关文档片段或类似讨论 |
| 开发者工具 | 堆栈跟踪、差异或错误描述 | 相关代码更改、讨论和过去事件 |

在这些示例中，无需手动输入新查询。系统使用源对象作为参考点，通过词法、语义或两者标准查找与之相似的文档。

在 RAG 的上下文中，这并非关于用户的主查询搜索，而是后续的上下文选择：系统已找到相关片段，并将其作为参考对象来收集周围上下文。当一个片段过于狭窄时，这很有用：附近内容可能包含术语定义、配置示例、相关讨论或同一指南的相邻部分。

在具有个性化或 AI 代理的系统中，明确定义用于搜索的数据非常重要：系统可能会考虑用户的搜索查询历史、先前交互的上下文或保存的工作笔记。这使参与检索的数据清晰，并解释为什么结果被视为相似。

MLT 的演变可以描述如下：

| 时期 | 变化 |
|---|---|
| 2000 年代 | MLT 主要依赖词法分析、TF-IDF、BM25 和术语重叠。 |
| 2010 年代 | Word2Vec 和 GloVe 出现并广泛使用，使得构建词和文本的语义嵌入成为可能。 |
| 2020 年初 | FAISS 和类似的 ANN 库使得即使在非常大的数据集上也能高效运行向量搜索。 |
| 2020 年中 | RAG、推荐和从现有对象的搜索使通过存储向量查找成为常见的产品场景。 |

MLT 的演变是从词法比较转向匹配文档向量表示。但实际需求保持不变：找到与源结果相关的文档。

## 需注意的要点

语义 MLT 并不会取代所有搜索工程。

生产系统仍然需要：

- 对标识符、错误代码和其他严格匹配项的精确搜索；
- 嵌入模型的元数据和版本控制；
- 访问控制列表过滤器：基于角色或用户的文档访问规则；
- 租户过滤器：客户或工作区之间的数据隔离；
- 混合搜索：当意义和精确匹配都重要时；
- 重排序：当结果顺序至关重要时；
- 搜索质量监控：精确率和召回率指标、误报频率以及由 ANN 索引近似误差导致的遗漏相关文档。

词法 MLT 可能会遗漏使用不同词汇的文档。向量搜索有时会返回过于宽泛的结果或误报，并且由于 ANN 索引的近似特性，可能会遗漏相关文档。因此，这种搜索质量应在真实查询和真实数据上进行评估。

## 结论

More Like This 已从纯粹的词法搜索转向结合词法、向量和过滤机制的混合解决方案。

核心概念保持不变：用户选择一个源文档，系统会找到与之相关的材料，同时考虑词法和语义相似性。
