跳到主要内容

如何组合多个检索器的结果

先决条件

本指南假设你熟悉以下概念

EnsembleRetriever 支持对来自多个检索器的结果进行集成。它使用 BaseRetriever 对象列表进行初始化。EnsembleRetrievers 基于 Reciprocal Rank Fusion 算法对组成检索器的结果进行重新排序。

通过利用不同算法的优势,EnsembleRetriever 可以实现比任何单个算法更好的性能。

一个有用的模式是将关键词匹配检索器与密集检索器(如嵌入相似度)组合在一起,因为它们的优势是互补的。这可以被认为是一种“混合搜索”形式。稀疏检索器擅长根据关键词查找相关文档,而密集检索器擅长根据语义相似度查找相关文档。

下面我们演示了对 简单自定义检索器 的集成,该检索器仅返回直接包含输入查询的文档,以及从 演示内存中向量存储 派生的检索器。

import { EnsembleRetriever } from "langchain/retrievers/ensemble";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings } from "@langchain/openai";
import { BaseRetriever, BaseRetrieverInput } from "@langchain/core/retrievers";
import { Document } from "@langchain/core/documents";

class SimpleCustomRetriever extends BaseRetriever {
lc_namespace = [];

documents: Document[];

constructor(fields: { documents: Document[] } & BaseRetrieverInput) {
super(fields);
this.documents = fields.documents;
}

async _getRelevantDocuments(query: string): Promise<Document[]> {
return this.documents.filter((document) =>
document.pageContent.includes(query)
);
}
}

const docs1 = [
new Document({ pageContent: "I like apples", metadata: { source: 1 } }),
new Document({ pageContent: "I like oranges", metadata: { source: 1 } }),
new Document({
pageContent: "apples and oranges are fruits",
metadata: { source: 1 },
}),
];

const keywordRetriever = new SimpleCustomRetriever({ documents: docs1 });

const docs2 = [
new Document({ pageContent: "You like apples", metadata: { source: 2 } }),
new Document({ pageContent: "You like oranges", metadata: { source: 2 } }),
];

const vectorstore = await MemoryVectorStore.fromDocuments(
docs2,
new OpenAIEmbeddings()
);

const vectorstoreRetriever = vectorstore.asRetriever();

const retriever = new EnsembleRetriever({
retrievers: [vectorstoreRetriever, keywordRetriever],
weights: [0.5, 0.5],
});

const query = "apples";
const retrievedDocs = await retriever.invoke(query);

console.log(retrievedDocs);

/*
[
Document { pageContent: 'You like apples', metadata: { source: 2 } },
Document { pageContent: 'I like apples', metadata: { source: 1 } },
Document { pageContent: 'You like oranges', metadata: { source: 2 } },
Document {
pageContent: 'apples and oranges are fruits',
metadata: { source: 1 }
}
]
*/

API 参考

下一步

你现在已经学习了如何组合来自多个检索器的结果。接下来,查看一些其他检索操作指南,例如如何 使用多个嵌入来改进结果 或者如何 创建你自己的自定义检索器


本页内容是否有帮助?


你也可以在 GitHub 上留下详细的反馈 GitHub.