langchain icon indicating copy to clipboard operation
langchain copied to clipboard

Specific name of the current chain is not displayed

Open AI-Chef opened this issue 1 year ago • 1 comments

System Info

LangChain v0.0.229, Python v3.10.12, Ubuntu 20.04.2 LTS

Who can help?

@hwchase17 @agola11

Information

  • [ ] The official example notebooks/scripts
  • [X] My own modified scripts

Related Components

  • [ ] LLMs/Chat Models
  • [ ] Embedding Models
  • [ ] Prompts / Prompt Templates / Prompt Selectors
  • [ ] Output Parsers
  • [ ] Document Loaders
  • [ ] Vector Stores / Retrievers
  • [ ] Memory
  • [ ] Agents / Agent Executors
  • [ ] Tools / Toolkits
  • [X] Chains
  • [X] Callbacks/Tracing
  • [ ] Async

Reproduction

I am encountering an issue where the specific name of the current chain is not being displayed in the console output, even though I have set 'verbose=True' in the MultiPromptChain and other Chains. When the program enters a new chain, it only prints 'Entering new chain...' without specifying the name of the chain. This makes it difficult to debug and understand which chain is currently being used. Could you please look into this issue and provide a way to display the name of the current chain in the console output? Thank you.

The output could be

> Entering new  chain...


> Entering new  chain...
lib/python3.10/site-packages/langchain/chains/llm.py:275: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
  warnings.warn(

> Finished chain.
math: {'input': 'What is the derivative of a function?'}

> Entering new  chain...
Prompt after formatting:
You are a very good mathematician. You are great at answering math questions. \nYou are so good because you are able to break down hard problems into their component parts, \nanswer the component parts, and then put them together to answer the broader question.
Here is a question:
What is the derivative of a function?

> Finished chain.

> Finished chain.

Expected behavior

> Entering new MultiPromptChain chain...


> Entering new LLMRouterChain chain...
lib/python3.10/site-packages/langchain/chains/llm.py:275: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
  warnings.warn(

> Finished chain.
math: {'input': 'What is the derivative of a function?'}

> Entering new LLMChain[math] chain...
Prompt after formatting:
You are a very good mathematician. You are great at answering math questions. \nYou are so good because you are able to break down hard problems into their component parts, \nanswer the component parts, and then put them together to answer the broader question.
Here is a question:
What is the derivative of a function?

> Finished chain.

> Finished chain.

AI-Chef avatar Jul 11 '23 08:07 AI-Chef

My code is followed the documentation https://python.langchain.com/docs/modules/chains/foundational/router And everyone can check on https://gist.github.com/AI-Chef/b952f5222ce64ea3365a0e6d8dc32dbf

AI-Chef avatar Jul 11 '23 08:07 AI-Chef

Hello @AI-Chef, I think its because of on_chain_start() method is not able to parse the chain name in stdout.py file, as there is no "name" field in "serialized" dictionary. I did some debugging and found out that there is an "id" field in that dictionary which is a list. Last element in that list is the name of chain class that you are looking for.

{'lc': 1, 'type': 'not_implemented', 'id': ['langchain', 'chains', 'router', 'multi_prompt', 'MultiPromptChain']}

Solution

 def on_chain_start(
        self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any
    ) -> None:
        """Print out that we are entering a chain."""
        class_name = serialized.get("id", "")[-1]
        print(f"\n\n\033[1m> Entering new {class_name} chain...\033[0m")

Final output

←[1m> Entering new MultiPromptChain chain...←[0m
{'lc': 1, 'type': 'not_implemented', 'id': ['langchain', 'chains', 'router', 'llm_router', 'LLMRouterChain']}


←[1m> Entering new LLMRouterChain chain...←[0m
^c

I hope this helps :)

gaurang98671 avatar Jul 12 '23 14:07 gaurang98671

Hello @gaurang98671, Thank you for your insightful solution. It's great to see how you've debugged the issue and found a way to extract the chain class name from the "id" field in the serialized dictionary.

However, I'd like to propose a slight modification to your solution. Instead of using class_name = serialized.get("id", "")[-1], I believe it would be more appropriate to use class_name = serialized.get("id", [""])[-1]. The reason for this is that the "id" field is an array. If the "id" is not found and the default value "" is returned, the subsequent index [-1] would result in an out-of-bounds error.

So the modified code would look like this:

def on_chain_start(
    self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any
) -> None:
    """Print out that we are entering a chain."""
    class_name = serialized.get("id", [""])[-1]
    print(f"\n\n\033[1m> Entering new {class_name} chain...\033[0m")

AI-Chef avatar Jul 13 '23 13:07 AI-Chef

@AI-Chef, ahh mybad, thanks for pointing that out.

gaurang98671 avatar Jul 13 '23 22:07 gaurang98671

Solved in pull #6124

AI-Chef avatar Jul 14 '23 00:07 AI-Chef