如何将多个检索器的结果合并
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 参考
- EnsembleRetriever 来自
langchain/retrievers/ensemble
- MemoryVectorStore 来自
langchain/vectorstores/memory
- OpenAIEmbeddings 来自
@langchain/openai
- BaseRetriever 来自
@langchain/core/retrievers
- BaseRetrieverInput 来自
@langchain/core/retrievers
- Document 来自
@langchain/core/documents
下一步
您现在已经了解了如何将多个检索器的结果合并。接下来,查看一些其他检索操作指南,例如如何 使用每个文档中的多个嵌入改进结果
或如何 创建自己的自定义检索器
。