I'm working with LangChain to create a retrieval-based QA system. However, when I attempt to chain Runnables, I encounter a TypeError that I'm unable to resolve. The error occurs when I try to use the | (pipe) operator to chain a RunnablePassthrough with a custom prompt and a ChatOpenAI instance.
Here is the error message I'm receiving:
TypeError: Expected a Runnable, callable or dict. Instead got an unsupported type: <class 'str'>
I've pinpointed the error to this part of the code:
rag_chain = ( {"context": context, "question": RunnablePassthrough()} | rag_custom_prompt | llm )
I expect the RunnablePassthrough() to pass the context and question to the next step in the chain, but it seems to fail during the coercion to a Runnable.
The following is pretty much my entire code:
## Convert the pdf into txt
def pdf_to_txt(inst_manuals):
txt = ""
for manual in inst_manuals:
reader = PdfReader(inst_manuals)
for page in reader.pages:
txt += page.extract_text()
return txt
## Convert txt into chunks
def chunkify_txt(txt):
txt_splitter = CharacterTextSplitter(
separator= "\n",
chunk_size= 1000,
chunk_overlap= 200,
length_function= len
)
chunks = txt_splitter.split_text(txt)
return chunks
## Obtain the vector store
def get_vector(chunks):
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_texts(texts= chunks, embedding = embeddings)
return vectorstore
## Retrieve useful info similar to user query
def retrieve(vectorstore, question):
logging.basicConfig()
logging.getLogger("langchain.retrievers.multi_query").setLevel(logging.INFO)
retriever_from_llm = MultiQueryRetriever.from_llm(
retriever=vectorstore.as_retriever(), llm=ChatOpenAI(temperature=0)
)
unique_docs = retriever_from_llm.get_relevant_documents(query=question)
print(f"Number of unique documents retrieved: {len(unique_docs)}")
return unique_docs
## Generate response for user query
def gen_resp(retriever, question):
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
template = """... [custom prompt template] ..."""
rag_custom_prompt = PromptTemplate.from_template(template)
context = "\n".join(doc.page_content for doc in retriever)
rag_chain = (
{"context": context, "question": RunnablePassthrough()} | rag_custom_prompt | llm
)
answer = rag_chain.invoke(question)
return answer
Has anyone encountered this before? Any suggestions on how to properly chain these Runnables or what I might be doing wrong?
I have attempted the following:
Using different retrievers (details of which could be provided upon request). I've checked the LangChain documentation for proper usage of Runnables and chaining operations. I've tried interchanging the context and question keys in the rag_chain dictionary to see if the order was the issue.