Combine documents from multiple retrievers in create_retrieval_chain #24864
Replies: 2 comments 5 replies
-
Hey @kartiksonaghela! I'm here to help you with any bugs, questions, or contributions you have in mind. Let's tackle this together! 😊 To update the from __future__ import annotations
from typing import Any, Dict, Union
from langchain_core.retrievers import (
BaseRetriever,
RetrieverOutput,
)
from langchain_core.runnables import Runnable, RunnablePassthrough
def create_retrieval_chain(
retriever: Union[BaseRetriever, Runnable[dict, RetrieverOutput]],
additional_retriever: Union[BaseRetriever, Runnable[dict, RetrieverOutput]],
combine_docs_chain: Runnable[Dict[str, Any], str],
) -> Runnable:
"""Create retrieval chain that retrieves documents from multiple retrievers and then passes them on.
Args:
retriever: Primary retriever-like object that returns list of documents.
additional_retriever: Additional retriever-like object to retrieve more documents.
combine_docs_chain: Runnable that takes inputs and produces a string output.
Returns:
An LCEL Runnable. The Runnable return is a dictionary containing at the very
least a `context` and `answer` key.
"""
if not isinstance(retriever, BaseRetriever):
primary_retrieval_docs: Runnable[dict, RetrieverOutput] = retriever
else:
primary_retrieval_docs = (lambda x: x["input"]) | retriever
if not isinstance(additional_retriever, BaseRetriever):
additional_retrieval_docs: Runnable[dict, RetrieverOutput] = additional_retriever
else:
additional_retrieval_docs = (lambda x: x["input"]) | additional_retriever
def merge_documents(primary_docs, additional_docs):
# Assuming both primary_docs and additional_docs are lists of documents
return primary_docs + additional_docs[:3] # Add 3 more documents from additional retriever
merged_retrieval_docs = (
primary_retrieval_docs.with_config(run_name="retrieve_primary_documents")
| (lambda x: {"primary_docs": x})
| additional_retrieval_docs.with_config(run_name="retrieve_additional_documents")
| (lambda x: {"additional_docs": x})
| (lambda x: merge_documents(x["primary_docs"], x["additional_docs"]))
)
retrieval_chain = (
RunnablePassthrough.assign(
context=merged_retrieval_docs.with_config(run_name="merge_documents"),
).assign(answer=combine_docs_chain)
).with_config(run_name="retrieval_chain")
return retrieval_chain This updated function now takes an additional retriever and merges the documents retrieved from both retrievers, adding 3 more documents from the additional retriever to the primary retriever's documents. The merged documents are then passed to the In the context of the LangChain framework, you can use the For example, you can use the from operator import itemgetter
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
# Define the prompt template
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
# Define the model
model = ChatOpenAI()
# Define the chain
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| model
| StrOutputParser()
) This example shows how to set up a retrieval-augmented generation chain using LangChain, which can be adapted to include multiple retrievers and combine their outputs [1][2][3]. |
Beta Was this translation helpful? Give feedback.
-
did you solve this problem, I also want to combine multiQuery retriever with chat history but could not find the documentation |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Checked other resources
Commit to Help
Example Code
Description
As you can see in create_retrieval_chain(history_aware_retriever, question_answer_chain) from history_aware_retriever we are getting n similar chunks based on question and then we pass it to question_answer_chain to get the answer. I want to further add more retrieved chunks to history_aware_retriever . So if history_aware_retriever gets around 10 documents i want to add more 3 to it and then pass it to question_answer_chain note that the additional 3 chunks are basically from some different version of same question. In short i want to update question_answer_chain with more chunks but not from this particular flow .
Thankyou
System Info
All Latest Verison
Beta Was this translation helpful? Give feedback.
All reactions