Christian01
Christian01

Reputation: 581

How to add langchain docs to LCEL chain?

I want to create a chain in langchain. And get the following error in short

TypeError: Expected a Runnable, callable or dict.Instead got an unsupported type: <class 'str'>

You find the complete error message at the end.

What I want to do?

First I pass my query through several retrievers and then use RRF to rerank. The result is result_context. It's a list of tuples (<document>,<score>). In the code below, I define my prompt template and join my document's page_content to one string. In the chain I want to pass my joined context and the query to the prompt. Further the final prompt should pass to the generation pipeline llm.

if self.prompt_template == None:
            template = """Use the following pieces of context to answer the question at the end.
            If you don't know the answer, just say that you don't know, don't try to make up an answer.
            Use three sentences maximum and keep the answer as concise as possible.
            Always say "thanks for asking!" at the end of the answer.

            {context}

            Question: {question}

            Helpful Answer:"""
            self.prompt_template = PromptTemplate.from_template(template)
        
        
prompt = ChatPromptTemplate.from_template(template)
context = "\n".join([doc.page_content for doc, score in result_context])
chain = (
            {"context":context, "question": RunnablePassthrough()}
            |prompt
            |llm
            |StrOutParser()
        )
            
inference = chain.invoke(query)
print(str(inference))

Now I get the following error and I don't know how to work around. I hope you can help me to fix the problem, that is possible to invoke the query to the chain.

Thanks in advance.

    169 prompt = ChatPromptTemplate.from_template(template)
    170 context = "\n".join([doc.page_content for doc, score in result_context])
    171 chain = (
--> 172     {"context":context, "question": RunnablePassthrough()}
    173     |prompt
    174     |llm
    175     |StrOutParser()
    176 )
    178 inference = chain.invoke(final_prompt)
    179 print(str(inference))

File /opt/conda/lib/python3.10/site-packages/langchain_core/runnables/base.py:433, in Runnable.__ror__(self, other)
    423 def __ror__(
    424     self,
    425     other: Union[
   (...)
    430     ],
    431 ) -> RunnableSerializable[Other, Output]:
    432     """Compose this runnable with another object to create a RunnableSequence."""
--> 433     return RunnableSequence(coerce_to_runnable(other), self)

File /opt/conda/lib/python3.10/site-packages/langchain_core/runnables/base.py:4373, in coerce_to_runnable(thing)
   4371     return RunnableLambda(cast(Callable[[Input], Output], thing))
   4372 elif isinstance(thing, dict):
-> 4373     return cast(Runnable[Input, Output], RunnableParallel(thing))
   4374 else:
   4375     raise TypeError(
   4376         f"Expected a Runnable, callable or dict."
   4377         f"Instead got an unsupported type: {type(thing)}"
   4378     )

File /opt/conda/lib/python3.10/site-packages/langchain_core/runnables/base.py:2578, in RunnableParallel.__init__(self, _RunnableParallel__steps, **kwargs)
   2575 merged = {**__steps} if __steps is not None else {}
   2576 merged.update(kwargs)
   2577 super().__init__(
-> 2578     steps={key: coerce_to_runnable(r) for key, r in merged.items()}
   2579 )

File /opt/conda/lib/python3.10/site-packages/langchain_core/runnables/base.py:2578, in <dictcomp>(.0)
   2575 merged = {**__steps} if __steps is not None else {}
   2576 merged.update(kwargs)
   2577 super().__init__(
-> 2578     steps={key: coerce_to_runnable(r) for key, r in merged.items()}
   2579 )

File /opt/conda/lib/python3.10/site-packages/langchain_core/runnables/base.py:4375, in coerce_to_runnable(thing)
   4373     return cast(Runnable[Input, Output], RunnableParallel(thing))
   4374 else:
-> 4375     raise TypeError(
   4376         f"Expected a Runnable, callable or dict."
   4377         f"Instead got an unsupported type: {type(thing)}"
   4378     )

TypeError: Expected a Runnable, callable or dict.Instead got an unsupported type: <class 'str'>

Upvotes: 0

Views: 486

Answers (1)

Andrew Nguonly
Andrew Nguonly

Reputation: 2621

The error is raised because the variable context is a string, but it must be of type Runnable. You can confirm this by modifying the chain slightly like this (this code will run successfully):

chain = (
    {"context": RunnablePassthrough(), "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)
            
inference = chain.invoke({
    "question": query,
    "context": context,  # pass context as a string here
})

However, a typical pattern is to pass a retriever (which isn't shown in your code sample) to the "context" key. Because you have several retrievers and a reranking step, constructing a single chain with all of these steps might be cumbersome.

References:

  1. Passing data through > Retrieval Example (LangChain)

Upvotes: 1

Related Questions