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