基于嵌入的向量搜索提供了一种根据语义相似性获取信息的有效方法,但在复杂的智能体场景中,仅依靠原始查询嵌入的最近邻结果往往不足。初始查询可能模糊、不够具体,或需要从多个不同角度综合信息。简单的检索可能导致向LLM提供次优的上下文,从而影响推理质量和任务成功率。高级检索策略旨在通过优化查询过程、增加结果多样性或提升相关性评分来解决这些局限。文档嵌入 (HyDE)一个重要难题是弥合短小、可能抽象的查询与内存中详细、内容丰富的文档之间的语义差距。例如,“智能体内存的最新进展是什么?”这样的查询,如果相关论文没有明确提到“智能体内存的进展”,它可能不会与具体描述新技术的论文紧密关联。HyDE通过先使用LLM生成一份文档(或答案),这份文档代表了一个理想响应可能的样子,从而解决这个问题。我们不直接嵌入原始查询 $q$,而是生成一份文档 $d_{hypo} = \text{LLM}(q)$。随后,我们嵌入这份文档得到 $e_{hypo} = f(d_{hypo})$,并使用 $e_{hypo}$ 对向量存储中实际的文档嵌入执行相似性搜索。其理念是,即使 $d_{hypo}$ 在事实上有误或不完整,它也可能包含比原始稀疏查询 $q$ 更接近真正相关文档的术语、措辞和语义结构。digraph G { rankdir=TB; node [shape=box, style=rounded, fontname="Arial", fontsize=10, color="#495057", fontcolor="#495057"]; edge [fontname="Arial", fontsize=9, color="#868e96"]; Query [label="原始查询 (q)", shape=parallelogram, style=filled, fillcolor="#a5d8ff"]; LLM [label="LLM 生成\n假设文档", style=filled, fillcolor="#bac8ff"]; HypoDoc [label="文档 (d_hypo)", shape=note, style=filled, fillcolor="#eebefa"]; EmbedHypo [label="嵌入 d_hypo", style=filled, fillcolor="#d0bfff"]; HypoEmb [label="嵌入向量 (e_hypo)", shape=cylinder, style=filled, fillcolor="#b2f2bb"]; VectorStore [label="向量存储\n(实际文档)", shape=cylinder, style=filled, fillcolor="#96f2d7"]; Search [label="使用 e_hypo\n相似性搜索", style=filled, fillcolor="#ffec99"]; Results [label="检索到的文档", shape=parallelogram, style=filled, fillcolor="#ffd8a8"]; Query -> LLM; LLM -> HypoDoc; HypoDoc -> EmbedHypo; EmbedHypo -> HypoEmb; HypoEmb -> Search; VectorStore -> Search; Search -> Results; }文档嵌入 (HyDE) 的高层工作流程。使用HyDE需要额外进行一次LLM调用,这会增加延迟和成本。其效果也取决于所生成文档的质量。一份质量不佳的 $d_{hypo}$ 可能会使搜索偏向不相关的结果。然而,对于用户意图明确但缺少目标文档中特定术语的查询,HyDE可以显著提升检索的相关性。多查询检索通常,单个查询向量无法捕捉信息需求的多个方面。智能体可能需要理解与复杂主题相关的不同方面或视角。多查询检索通过从原始查询生成多个相关查询,对每个查询执行搜索,然后合并结果来解决此问题。此过程通常包括:获取原始用户查询 $q$。使用LLM根据 $q$ 生成 $N$ 个变体或子查询 ${q_1, q_2, ..., q_N}$。这些变体可能从不同角度考虑、使用同义词或分解查询。在向量存储中执行 $N$ 次独立的相似性搜索,每次针对一个 $q_i$。收集检索到的文档集合 $D_1, D_2, ..., D_N$。合并并去重这些集合以形成最终上下文。digraph G { rankdir=TB; node [shape=box, style=filled, fontname="Arial", fontsize=10]; Query [label="原始查询 (q)", shape=parallelogram, fillcolor="#a5d8ff"]; LLMGen [label="LLM 生成子查询", fillcolor="#bac8ff"]; SubQueries [label="子查询 {q1, q2, ..., qN}", fillcolor="#eebefa"]; VS [label="向量存储", shape=cylinder, fillcolor="#96f2d7"]; Search1 [label="搜索 q1", fillcolor="#ffec99"]; Search2 [label="搜索 q2", fillcolor="#ffec99"]; Merge [label="合并与去重", fillcolor="#ffd8a8"]; FinalContext [label="最终上下文", shape=parallelogram, fillcolor="#ffc9c9"]; Query -> LLMGen -> SubQueries; SubQueries -> Search1; SubQueries -> Search2; VS -> Search1; VS -> Search2; Search1 -> Merge; Search2 -> Merge; Merge -> FinalContext; } 多查询检索的工作流程,生成多个搜索向量。此方法增加了检索文档的多样性,提高了覆盖不同相关子主题的可能性。权衡之处在于发送到向量存储的查询数量增加(可能是单个查询成本和延迟的 $N$ 倍),以及为生成查询而增加的LLM调用。此外,还需要谨慎合并,以避免最终上下文中的过度冗余。对检索结果进行重排序向量相似性搜索善于从庞大的语料库中快速找到语义相关的文档。然而,仅仅基于嵌入的余弦相似度或欧氏距离得出的前k个结果,可能并不总是根据更具体标准来判断的最相关结果。重排序引入了第二阶段来优化初始候选集。典型流程如下:使用快速方法(例如,向量相似性搜索)执行初步检索,获取 $M$ 份候选文档,其中 $M$ 通常大于最终所需的数量 $k$(例如,$M=50, k=5$)。使用更精细、可能较慢的重排序模型,根据这 $M$ 份文档与原始查询 $q$ 的相关性重新评分。根据重排序得分选择前 $k$ 份文档。重排序模型通常是交叉编码器。与用于初步检索的双编码器(独立嵌入查询和文档)不同,交叉编码器将查询和候选文档一起处理,从而可以进行更细致的交互分析(例如,使用交叉注意力)。这会产生更准确的相关性得分,但将其应用于整个语料库在计算上过于昂贵。{"layout": {"title": {"text": "重排序效果", "font": {"family": "Arial", "size": 14}}, "xaxis": {"title": {"text": "文档ID", "font": {"family": "Arial", "size": 10}}, "showticklabels": false}, "yaxis": {"title": {"text": "相关性得分", "font": {"family": "Arial", "size": 10}}, "range": [0, 1]}, "legend": {"font": {"family": "Arial", "size": 10}}, "autosize": true, "height": 300, "margin": {"l": 50, "r": 20, "t": 40, "b": 40}, "plot_bgcolor": "#e9ecef"}, "data": [{"x": ["Doc A", "Doc B", "Doc C", "Doc D", "Doc E", "Doc F", "Doc G", "Doc H"], "y": [0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6, 0.55], "type": "bar", "name": "初始检索得分", "marker": {"color": "#74c0fc"}}, {"x": ["Doc A", "Doc B", "Doc C", "Doc D", "Doc E", "Doc F", "Doc G", "Doc H"], "y": [0.85, 0.95, 0.7, 0.9, 0.6, 0.8, 0.5, 0.4], "type": "bar", "name": "重排序后得分", "marker": {"color": "#f76707"}}]}示例显示重排序如何改变初步检索到的文档的相关性顺序。文档B和文档D在重排序后显著提升。重排序由于第二阶段的评分过程会增加延迟。重排序模型的选择(其大小、训练数据、架构)会影响质量改进和性能开销。然而,对于要求检索上下文具有高准确性的应用,重排序通常是一个有益的补充。融合与混合方法不同的检索方法具有各自的优势。关键词搜索(如BM25)善于匹配特定术语,而向量搜索则捕捉语义含义。混合搜索结合了来自多个检索系统的结果。一种常用技术是倒数排名融合(RRF),它根据排名位置而非绝对分数结合来自不同源的排名列表,使其在处理得分不可比性时表现良好。通过融合例如向量搜索和关键词搜索的结果,智能体可以同时获得语义理解和术语特异性的好处。选择合适的策略没有单一的“最佳”高级检索策略。最佳选择取决于以下因素:任务要求: 任务是需要查找具体事实(倾向于准确性,可能重排序),还是需要广泛查看某个主题(倾向于多样性,可能多查询)?查询特点: 查询通常是模糊的(倾向于HyDE),还是多方面的(倾向于多查询)?延迟预算: 智能体需要多快获取信息?与简单的向量搜索相比,HyDE、多查询和重排序都会增加延迟。计算资源: 重排序器,特别是大型交叉编码器,可能需要大量计算。语料库属性: 内存存储中文档的性质可能会影响哪种策略最有效。实施这些高级策略需要仔细权衡检索质量、延迟和计算成本。然而,超越基本的最近邻搜索对于构建真正有效且具备知识的LLM智能体而言是经常必要的,这些智能体能够进行复杂的推理和完成长期任务。正如第六章所述,实验和评估对于确定最适合您特定应用的方法非常重要。