跳至主要内容

如何将多个检索器的结果合并

先决条件

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

EnsembleRetriever 支持将多个检索器的结果合并。它用一个包含 BaseRetriever 对象列表初始化。EnsembleRetriever 会根据 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.