推荐系统“猜你喜欢”功能的演进之路
速览
本文探讨了推荐系统中“More Like This”功能的技术发展史。从最初的基于规则的简单匹配,到协同过滤,再到如今基于深度学习的复杂模型,技术不断迭代。这一演变显著提升了用户个性化体验和内容分发的精准度。
AI 深度解读
“More Like This” 的演进:从词法匹配到向量语义搜索
背景
在许多搜索场景中,用户的起点并非一个空白的查询框,而是一个已有的结果。
- 用户打开一篇文章,希望找到相关的补充材料。
- 买家浏览产品卡片,寻找相似的替代品。
- 支持工程师调查故障事件,希望查看具有相同症状的早期案例。
在所有这些情况下,用户已经拥有一个相关的文档作为起点。这种场景在传统上被称为 “More Like This” (MLT),即根据选定的文档查找相似文档的功能。在本文中,MLT 特指基于已知文档发起的搜索,而非基于新输入的查询词。
随着技术的发展,MLT 的实现方式正在经历从传统的词法匹配向基于嵌入向量(Embeddings)的语义搜索的转变。
核心内容
经典 MLT 的实现机制
经典的 MLT 方法是基于**词法(Lexical)**的。它回答的核心问题是:“哪些文档使用了相似的关键词?”
其内部流程通常如下:
- 搜索系统获取源文档。
- 分析其文本内容。
- 提取信息量大的术语(Terms)。
- 基于这些术语构建查询语句。
- 搜索包含相似词集的文档。
- 返回相似文档列表。
这一过程依赖于熟悉的全文本搜索机制,如 TF-IDF 或 BM25 算法,涉及词频、停用词过滤、字段权重提升以及文档频率限制等。因此,早期的 MLT 实现通常会暴露 min_term_freq、min_doc_freq、max_doc_freq 和 max_query_terms 等参数。这不仅仅是一个界面元素,而是一套完整的搜索机制,广泛应用于相关文章推荐、产品去重、工单匹配、法律检索、专利研究及内部知识库中。
词法方法的局限与优势
优势场景: 词法 MLT 在特定词汇、标识符和稳定表述至关重要的场景中表现优异。例如:
- 错误代码(Error codes)
- 产品 SKU
- 零件编号
- 函数名称
- 堆栈跟踪(Stack traces)
- 法律条文措辞
- 几乎完全相同的产品或工单描述
原因在于精确匹配至关重要。如果两份故障报告包含相同的错误代码或堆栈跟踪,全文本搜索能直接命中。例如,搜索包含代码 ERR_404 的工单时,词法 MLT 能迅速找到所有提及该代码的记录,而向量搜索可能会返回描述相似但并非完全相同问题的工单。
此外,词法 MLT 还有一个显著优势:成本低廉。倒排索引已存在于搜索引擎中,分析器和排序机制已配置完毕,无需为了支持“查找相似”功能而部署额外的搜索基础设施。
局限性: 如果两个文档用不同的词语描述同一件事,词法 MLT 可能无法建立关联。同义词的处理往往不均匀, paraphrase(改写)更难处理,跨语言相似性通常不可用。例如,“memory leak”(内存泄漏)和“unbounded heap growth”(无限制的堆增长)可能描述的是同一个问题,但标准分析器会将其视为不同的 Token。
嵌入向量(Embeddings)带来的变革
使用嵌入向量——即文档的数值表示——改变了比较原则:系统不再比较单词,而是比较向量表示。
- 词法方法:通过单词和术语查找匹配,适用于精确匹配(如错误代码、SKU)。
- 向量搜索:通过文档向量表示的邻近度进行查找,即使措辞不同,也能找到语义上接近的文档。
这极大地扩展了此类搜索的范围。现在不仅可以比较文章,还可以比较产品、图像、代码片段、用户事件,或在 RAG(检索增强生成)系统中比较上下文片段。在 RAG 中,搜索系统首先检索相关上下文,然后由生成模型利用该上下文生成答案。
现代 MLT 的实现:基于索引向量的查找
如果文档的向量表示已预先计算并存储在索引中,现代 MLT 可以简化为以下操作:
- 获取源文档。
- 从索引中检索其预计算的向量表示。
- 查找最近的向量。
- 返回这些向量所属的文档。
这仍然是“More Like This”:用户从一个文档开始,获得相关结果,只是比较方法发生了变化。
以 Manticore Search 为例: 该操作可以直接在搜索引擎层面执行。查询指定源文档的 ID,Manticore 从索引中获取其嵌入向量并执行 KNN(K-Nearest Neighbors,K近邻)搜索。应用程序无需单独获取向量、序列化数百或数千个数字并在第二个请求中发送回来。
最小化的 SQL 示例如下:
SELECT id, title, knn_dist()
FROM products
WHERE knn(embedding, 10, 123)
LIMIT 10;
embedding:存储预计算嵌入向量的字段。123:源文档的 ID。10:要返回的最近文档数量。knn_dist():返回向量之间的距离,值越小表示语义上越接近源文档。
对于大型数据集,KNN 通常通过 ANN(Approximate Nearest Neighbor,近似最近邻)索引实现,通过近似计算加速搜索,避免扫描每一个向量。对用户而言,重要的是结果:快速找到在语义上接近源文档的文档。
为何应在引擎内部处理搜索逻辑
虽然可以在应用程序层面实现此场景(先获取文档 -> 提取向量 -> 发送单独的 KNN 查询 -> 结合过滤器),但这会使系统架构更复杂。应用程序需要:
- 在服务间传递向量。
- 防止意外记录日志。
- 检查嵌入模型版本。
- 保持数据与主索引同步。
- 应用与正常搜索相同的过滤器。
当搜索系统自行执行查找时,路径更短:
- 应用程序传递源文档的 ID。
- 搜索系统在索引中找到预计算的向量表示。
- 搜索系统运行最近邻搜索(KNN)或其近似变体(ANN)。
- 搜索系统返回找到的文档,并应用相同的访问过滤器和元数据。
这种引擎内处理的优势包括:
- 减少应用程序的跨服务请求。
- 大型向量无需通过外部 API 传输。
- 过滤器更接近搜索逻辑。
- 结果更易于复现和调试。
- 应用程序无需额外的相似度计算层。
混合搜索(Hybrid Search)是生产环境的主流
词法搜索并未消失。精确的错误代码、SKU、名称、法规引用和近重复项仍更适合通过词法处理。因此,生产系统通常采用混合搜索:
- 全文本搜索提供精确匹配。
- 向量搜索通过语义添加结果。
- 过滤器约束搜索空间。
- 重排序(Reranking)优化最终顺序。
正如对比所示,词法搜索在严格精确匹配上胜出,而向量搜索提高了语义关系的覆盖率。
关键要点
- MLT 的定义:指基于已有文档而非新查询词发起的相似文档搜索场景。
- 经典方法(词法):基于 TF-IDF/BM25,依赖关键词匹配。优势在于成本低、对精确标识符(如 SKU、错误代码)匹配准确;劣势在于无法处理同义词、改写或跨语言语义。
- 现代方法(向量):基于 Embeddings 向量表示。优势在于能理解语义相似性,即使措辞不同也能匹配;劣势在于计算成本较高,且对精确标识符匹配不如词法方法直接。
- 混合搜索(Hybrid Search):生产环境最佳实践。结合全文本搜索的精确性和向量搜索的语义覆盖能力,辅以过滤器和重排序。
- 架构优化:将 MLT 逻辑下沉至搜索引擎引擎内部(如 Manticore Search 的
knn函数),由引擎直接通过文档 ID 查找向量并执行 KNN/
