You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并多个FAISS索引为单个检索器且保留单独使用能力

可行方案与替代实现

方案一:使用LangChain的EnsembleRetriever合并检索器

LangChain中不存在MultiIndexRetriever,但可以用EnsembleRetriever组合多个FAISS检索器,同时保留每个原始索引实例,既能满足合并后的问答需求,也支持单独调用索引做相似性搜索。

实现步骤

  1. 为每个FAISS索引创建独立检索器
  2. 用EnsembleRetriever组合检索器(可自定义权重)
  3. 保留原始FAISS索引,用于后续单独搜索
  4. 开启QA链的源文档返回,获取参考页面信息

完整代码示例

from langchain.retrievers import EnsembleRetriever
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.chains import RetrievalQA

# 加载并保存索引(原逻辑保留)
pdf = load_pdf(help_doc_name)
faiss_index_ft9Help = FAISS.from_documents(pdf, OpenAIEmbeddings())
faiss_index_ft9Help.save_local(index_path + "/" + help_doc_name)

pdf = load_pdf(newsletters_doc_name)
faiss_index_newsletters = FAISS.from_documents(pdf, OpenAIEmbeddings())
faiss_index_newsletters.save_local(index_path + "/" + newsletters_doc_name)

pdf = load_pdf(supportCases_doc_name)
faiss_index_supportCases = FAISS.from_documents(pdf, OpenAIEmbeddings())
faiss_index_supportCases.save_local(index_path + "/" + supportCases_doc_name)

# 为每个索引创建独立检索器,可单独调整返回数量
retriever_help = faiss_index_ft9Help.as_retriever(search_kwargs={"k": 3})
retriever_newsletters = faiss_index_newsletters.as_retriever(search_kwargs={"k": 3})
retriever_support = faiss_index_supportCases.as_retriever(search_kwargs={"k": 3})

# 组合成EnsembleRetriever,权重可按需分配
ensemble_retriever = EnsembleRetriever(
    retrievers=[retriever_help, retriever_newsletters, retriever_support],
    weights=[0.4, 0.3, 0.3]
)

# 创建QA链,开启源文档返回以获取参考页面
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=ensemble_retriever,
    verbose=False,
    return_source_documents=True
)

# 问答交互逻辑(新增参考页面输出)
while True:
    question = input("You: ")
    if question.lower() == "exit":
        print("Bot: Goodbye!")
        break
    
    result = qa_chain({"query": question})
    response = result["result"]
    source_docs = result["source_documents"]
    
    print("Bot: " + response + "\n")
    print("参考页面:")
    for doc in source_docs:
        # 需确保PDF加载时保留source和page元数据,根据实际情况调整
        print(f"- 来源:{doc.metadata.get('source', '未知')},页码:{doc.metadata.get('page', '未知')}")
    print("\n")

# 单独使用单个索引进行相似性搜索示例
def search_single_index(index, query):
    return index.similarity_search(query, k=3)

# 调用示例
help_search_results = search_single_index(faiss_index_ft9Help, "你的问题")
news_search_results = search_single_index(faiss_index_newsletters, "你的问题")
support_search_results = search_single_index(faiss_index_supportCases, "你的问题")

方案二:手动合并FAISS索引(保留原索引副本)

如果不需要动态调整各索引权重,可以直接合并三个FAISS索引,同时保留原始索引副本用于单独搜索。

实现代码

# 加载并保存原始索引(原逻辑保留)
# ...(省略原加载代码)

# 创建原始索引副本,用于后续单独搜索
faiss_index_ft9Help_copy = FAISS.from_documents(load_pdf(help_doc_name), OpenAIEmbeddings())
faiss_index_newsletters_copy = FAISS.from_documents(load_pdf(newsletters_doc_name), OpenAIEmbeddings())
faiss_index_supportCases_copy = FAISS.from_documents(load_pdf(supportCases_doc_name), OpenAIEmbeddings())

# 合并三个索引
merged_index = faiss_index_ft9Help.merge_from(faiss_index_newsletters)
merged_index.merge_from(faiss_index_supportCases)

# 创建合并后的检索器用于QA链
merged_retriever = merged_index.as_retriever(search_kwargs={"k": 9})

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=merged_retriever,
    verbose=False,
    return_source_documents=True
)

# 问答交互和单独搜索逻辑同方案一
# ...(省略对应代码)

关键注意事项

  • 元数据保留:加载PDF时需确保保留source(来源文件名)和page(页码)元数据,否则无法获取有效参考页面信息。
  • 参数优化:根据业务需求调整检索器的k值(返回结果数量)和EnsembleRetriever的权重,提升问答准确性。
  • 索引复用:后续可直接用FAISS.load_local()加载已保存的索引,避免重复创建,提升运行效率。

内容的提问来源于stack exchange,提问作者Pasindu Lakshan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:38:38