langchain-ai / langchain

๐Ÿฆœ๐Ÿ”— Build context-aware reasoning applications
https://python.langchain.com
MIT License
92.38k stars 14.77k forks source link

Getting ConversationBufferMemory to work with create_pandas_dataframe_agent #3106

Closed eike-heimpel closed 2 months ago

eike-heimpel commented 1 year ago

I have been trying to add memory to my create_pandas_dataframe_agent agent and ran into some issues.

I created the agent like this

agent = create_pandas_dataframe_agent(
    llm=llm,
    df=df,
    prefix=prefix,
    suffix=suffix,
    max_iterations=4,
    input_variables=["df", "chat_history", "input", "agent_scratchpad"],
)

and ran into

  File "/path/projects/test/langchain/main.py", line 42, in <module>
    a = agent.run("This is a test")
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/langchain/chains/base.py", line 213, in run
    return self(args[0])[self.output_keys[0]]
           ^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/langchain/chains/base.py", line 106, in __call__
    inputs = self.prep_inputs(inputs)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/langchain/chains/base.py", line 185, in prep_inputs
    raise ValueError(
ValueError: A single string input was passed in, but this chain expects multiple inputs ({'input', 'chat_history'}). When a chain expects multiple inputs, please call it by passing in a dictionary, eg `chain({'foo': 1, 'bar': 2})

I was able to fix it by modifying the create_pandas_dataframe_agent to accept the memory object and then passing that along to the AgentCreator like so:

return AgentExecutor.from_agent_and_tools(
        agent=agent,
        tools=tools,
        verbose=verbose,
        return_intermediate_steps=return_intermediate_steps,
        max_iterations=max_iterations,
        max_execution_time=max_execution_time,
        early_stopping_method=early_stopping_method,
        memory=memory,
    )

Not sure what I did wrong or if I am misunderstanding something in general, maybe this is just the current behavior and adding memory would be a feature request?

MoElaSec commented 1 year ago

๐Ÿ‘‡ SOLVED_DOWN ๐ŸŽŠ Kinda

Backstory:

While: trying to have more than 1 chat-history as a key (the goal was having a chat-history for each user)

Issue:

Just wanted to add that I'm going thru the excat smae issue.

memory = ConversationBufferMemory(memory_key="chat-history", return_messages=True)

# create and return the chat agent
agent = initialize_agent(
        tools=tools,
        llm=model,
        agent="chat-conversational-react-description",
        verbose=True,
        memory=memory
)

search_me = "how to cook a banana"

agent.run(search_me)

Error:

ValueError: A single string input was passed in, but this chain expects multiple inputs ({'chat_history', 'input'}). When a chain expects multiple inputs, please call it by passing in a dictionary, eg `chain({'foo': 1, 'bar': 2})`

Edit:

SOLUTION:

Apperently I was to tired to notice, however all what we have to do is the following:

out = agent({"input": search_me, "chat_history": []})
print(out)

Then later on you will just have to save the output and of course your input:

memory.save_context({"input": search_me}, {"ouput": out})

memory.load_memory_variables({"username_id"})

it does show indeed only the desired key searches (in this case it's dynamically associated to each user)

{'username_id': [HumanMessage(content='ู…ุคุณุณุฉ ููˆู†ุฏุง ', additional_kwargs={}),
  Fonda | ููˆู†ุฏุง KSA-based company works with clients worldwide to develop brands through custom websites, e-commerce stores, social media management...', additional_kwargs={})]}
Rishav-hub commented 1 year ago

@eike-heimpel is it working for you? I am also having a similar issue where I am using multiple tools. One is RetrievalQA and the next is the Pandas toolkit. But Pandas toolkit is not able to access memory. Any solution for this?

tevslin commented 1 year ago

Just to add to the features request to have the Panda agent use memory

Rishav-hub commented 1 year ago

@tevslin This worked for me

"""Agent for working with pandas objects."""
from typing import Any, List, Optional

from langchain.agents.agent import AgentExecutor
# from langchain.agents.agent_toolkits.pandas.prompt import PREFIX, SUFFIX
from langchain.agents import ZeroShotAgent
from langchain.callbacks.base import BaseCallbackManager
from langchain.chains.llm import LLMChain
from langchain.llms.base import BaseLLM
from langchain.tools.python.tool import PythonAstREPLTool
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(memory_key="chat_history")
def create_pandas_dataframe_agent(
    llm: BaseLLM,
    df: Any,
    callback_manager: Optional[BaseCallbackManager] = None,
    prefix: str = PREFIX,
    suffix: str = SUFFIX,
    input_variables: Optional[List[str]] = None,
    verbose: bool = False,
    return_intermediate_steps: bool = False,
    max_iterations: Optional[int] = 15,
    max_execution_time: Optional[float] = None,
    early_stopping_method: str = "force",
    **kwargs: Any,
) -> AgentExecutor:
    """Construct a pandas agent from an LLM and dataframe."""
    import pandas as pd

    if not isinstance(df, pd.DataFrame):
        raise ValueError(f"Expected pandas object, got {type(df)}")
    if input_variables is None:
        input_variables = ["df", "input", "agent_scratchpad"]
    tools = [PythonAstREPLTool(locals={"df": df})]

    PREFIX = """
            You are working with a pandas dataframe in Python. The name of the dataframe is `df`.
            You should use the tools below to answer the question posed of you:"""

    SUFFIX = """
            This is the result of `print(df.head())`:
            {df}
            Begin!
            {chat_history}
            Question: {input}
            {agent_scratchpad}"""

    prompt = ZeroShotAgent.create_prompt(
        tools, 
        prefix=PREFIX,
        suffix=SUFFIX, 
        input_variables=["df", "input", "chat_history", "agent_scratchpad"]
    )

    print(prompt)

    partial_prompt = prompt.partial(df=str(df.head()))

    llm_chain = LLMChain(
        llm=llm,
        prompt=partial_prompt,
        callback_manager=callback_manager,
    )

    tool_names = [tool.name for tool in tools]

    agent = ZeroShotAgent(
        llm_chain=llm_chain,
        allowed_tools=tool_names,
        callback_manager=callback_manager,
        **kwargs,
    )
    return AgentExecutor.from_agent_and_tools(
        agent=agent,
        tools=tools,
        verbose=verbose,
        return_intermediate_steps=return_intermediate_steps,
        max_iterations=max_iterations,
        max_execution_time=max_execution_time,
        early_stopping_method=early_stopping_method,
        callback_manager=callback_manager,
        memory = memory
    )
tevslin commented 1 year ago

Thank you. That works very well. I did have to change the defaults of PREFIX and SUFFIX since they were undefined.

for production I'd suggest that memory be defined by the caller and passed in as an optional parameter with a default of None. Also the defaults for SUFFIX and PREFIX can be changed in prompts.py in the \pandas folder or overridden by the caller, Are you going to create a pull-request for this?

Rishav-hub commented 1 year ago

Thank you. That works very well. I did have to change the defaults of PREFIX and SUFFIX since they were undefined.

for production I'd suggest that memory be defined by the caller and passed in as an optional parameter with a default of None. Also the defaults for SUFFIX and PREFIX can be changed in prompts.py in the \pandas folder or overridden by the caller, Are you going to create a pull-request for this?

Sure I will create one!!. May I know what you mean by defining a caller?

tevslin commented 1 year ago

I just meant that the code which invokes create_pandas_dataframe_agent should allocate the memory buffer if it wants one and pass it as an optional parameter to create_pandas_dataframe_agent.

Rishav-hub commented 1 year ago

I just meant that the code which invokes create_pandas_dataframe_agent should allocate the memory buffer if it wants one and pass it as an optional parameter to create_pandas_dataframe_agent.

If the memory parameter is optional, then in the prompt the input variable {chat_history} would also be an optional parameter.

tevslin commented 1 year ago

You are absolutely right. Thanks.

From: Rishav Dash @.> Sent: Monday, May 1, 2023 11:11 AM To: hwchase17/langchain @.> Cc: Tom Evslin @.>; Mention @.> Subject: Re: [hwchase17/langchain] Getting ConversationBufferMemory to work with create_pandas_dataframe_agent (Issue #3106)

I just meant that the code which invokes create_pandas_dataframe_agent should allocate the memory buffer if it wants one and pass it as an optional parameter to create_pandas_dataframe_agent.

If the memory parameter is optional, then in the prompt the input variable {chat_history} would also be an optional parameter.

โ€” Reply to this email directly, view it on GitHub https://github.com/hwchase17/langchain/issues/3106#issuecomment-1529818780 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AGLSBBSSRCX5LBDIX7N3MKLXD7HBZANCNFSM6AAAAAAXDCEVV4 . You are receiving this because you were mentioned. https://github.com/notifications/beacon/AGLSBBREKIUAJRDC7ZLV3S3XD7HBZA5CNFSM6AAAAAAXDCEVV6WGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTS3F4XJY.gif Message ID: @. @.> >

eike-heimpel commented 1 year ago

@tevslin @Rishav-hub thanks for taking a look here, this sounds good! Is there a PR already that I could take a look at?

Rishav-hub commented 1 year ago

@tevslin @Rishav-hub thanks for taking a look here, this sounds good! Is there a PR already that I could take a look at?

Till now I have not made a PR regarding this.

Sulomus commented 1 year ago

Will we create a PR for this? It sounds like it would be great and have a great use case ๐Ÿ˜„

baswenneker commented 1 year ago

@tevslin @Rishav-hub thanks for taking a look here, this sounds good! Is there a PR already that I could take a look at?

Till now I have not made a PR regarding this.

Will the PR also work with OpenAI functions?

gaurangsultania commented 1 year ago

I am facing an error saying "chat_history" not defined. What mistake might I have committed?

Rishav-hub commented 1 year ago

I am facing an error saying "chat_history" not defined. What mistake might I have committed?

Can you send the code which is throwing this particular error?

Sulomus commented 1 year ago

I made it all work!

You need to change the prompt.py file but other then that it is easy.

Example code as a stackoverflow answer can be found here: https://stackoverflow.com/questions/76500981/how-to-add-conversational-memory-to-pandas-toolkit-agent/76562847#76562847

fuwentay commented 1 year ago

@tevslin @Rishav-hub thanks for taking a look here, this sounds good! Is there a PR already that I could take a look at?

Till now I have not made a PR regarding this.

hi Rishav, thanks for the great work!

can I just clarify that to implement memory for create_pandas_dataframe_agent, all you did was to change the function defined?

can I also ask if you're comfortable sharing your script that runs the agent? I'm having some issues implementing memory for the pandas df agent.

mikebilly commented 11 months ago

@tevslin This worked for me

"""Agent for working with pandas objects."""
from typing import Any, List, Optional

from langchain.agents.agent import AgentExecutor
# from langchain.agents.agent_toolkits.pandas.prompt import PREFIX, SUFFIX
from langchain.agents import ZeroShotAgent
from langchain.callbacks.base import BaseCallbackManager
from langchain.chains.llm import LLMChain
from langchain.llms.base import BaseLLM
from langchain.tools.python.tool import PythonAstREPLTool
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(memory_key="chat_history")
def create_pandas_dataframe_agent(
    llm: BaseLLM,
    df: Any,
    callback_manager: Optional[BaseCallbackManager] = None,
    prefix: str = PREFIX,
    suffix: str = SUFFIX,
    input_variables: Optional[List[str]] = None,
    verbose: bool = False,
    return_intermediate_steps: bool = False,
    max_iterations: Optional[int] = 15,
    max_execution_time: Optional[float] = None,
    early_stopping_method: str = "force",
    **kwargs: Any,
) -> AgentExecutor:
    """Construct a pandas agent from an LLM and dataframe."""
    import pandas as pd

    if not isinstance(df, pd.DataFrame):
        raise ValueError(f"Expected pandas object, got {type(df)}")
    if input_variables is None:
        input_variables = ["df", "input", "agent_scratchpad"]
    tools = [PythonAstREPLTool(locals={"df": df})]

    PREFIX = """
            You are working with a pandas dataframe in Python. The name of the dataframe is `df`.
            You should use the tools below to answer the question posed of you:"""

    SUFFIX = """
            This is the result of `print(df.head())`:
            {df}
            Begin!
            {chat_history}
            Question: {input}
            {agent_scratchpad}"""

    prompt = ZeroShotAgent.create_prompt(
        tools, 
        prefix=PREFIX,
        suffix=SUFFIX, 
        input_variables=["df", "input", "chat_history", "agent_scratchpad"]
    )

    print(prompt)

    partial_prompt = prompt.partial(df=str(df.head()))

    llm_chain = LLMChain(
        llm=llm,
        prompt=partial_prompt,
        callback_manager=callback_manager,
    )

    tool_names = [tool.name for tool in tools]

    agent = ZeroShotAgent(
        llm_chain=llm_chain,
        allowed_tools=tool_names,
        callback_manager=callback_manager,
        **kwargs,
    )
    return AgentExecutor.from_agent_and_tools(
        agent=agent,
        tools=tools,
        verbose=verbose,
        return_intermediate_steps=return_intermediate_steps,
        max_iterations=max_iterations,
        max_execution_time=max_execution_time,
        early_stopping_method=early_stopping_method,
        callback_manager=callback_manager,
        memory = memory
    )

I'm getting:

[/usr/local/lib/python3.10/dist-packages/langchain/memory/chat_memory.py](https://localhost:8080/#) in _get_input_output(self, inputs, outputs)
     25         if self.output_key is None:
     26             if len(outputs) != 1:
---> 27                 raise ValueError(f"One output key expected, got {outputs.keys()}")
     28             output_key = list(outputs.keys())[0]
     29         else:

ValueError: One output key expected, got dict_keys(['output', 'intermediate_steps'])
divija12 commented 11 months ago

Doing this worked for me:

memory=ConversationBufferMemory(memory_key="chat_history", input_key='input', output_key="output")

and while calling the agent:

response = agent( { "input": query } )

Quoting from this: https://github.com/langchain-ai/langchain/issues/2068#issuecomment-1494537932

MuazAshraf commented 10 months ago

from langchain.memory.buffer import ConversationBufferMemory import pinecone from langchain.vectorstores import Pinecone from langchain.chat_models import ChatOpenAI from langchain.chains import LLMChain from langchain.chains import RetrievalQA from langchain.chains import ConversationalRetrievalChain from langchain.embeddings.openai import OpenAIEmbeddings from langchain.prompts import PromptTemplate from langchain.chains.router import MultiRetrievalQAChain from langchain.chains.question_answering import load_qa_chain from langchain.agents import AgentType, initialize_agent from langchain.tools import Tool from flask import Flask, render_template, request, jsonify import os

app = Flask(name)

Initialize Openai

from dotenv import load_dotenv

Load environment variables from .env file

load_dotenv('.env') OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") PINECONE_API_KEY = os.getenv('PINECONE_API_KEY') PINECONE_API_ENV = os.getenv('PINECONE_API_ENV')

Initialize pinecone and set index

pinecone.init( api_key=PINECONE_API_KEY,
environment=PINECONE_API_ENV
) index_name = "main"

Initialize embeddings and AI

projectwe_embeddings = OpenAIEmbeddings()

Prompt Template

template = """ QUESTION: {question}

CHAT HISTORY: {chat_history}

ANSWER: """ prompt = PromptTemplate(input_variables=["chat_history", "question"], template=template)

FOR PROJECTWE

projectwe_retriever = Pinecone.from_existing_index(index_name=index_name, embedding=projectwe_embeddings, namespace="ProjectWe-Virtual Assistant")

projectwe memory

projectwe_memory = ConversationBufferMemory(memory_key="chat_history", input_key="question",return_messages=True)

Llms

llm = ChatOpenAI(temperature=0) projectwe_chain = LLMChain(llm=llm, prompt=prompt,output_key='question')

ProjectWe-Chain

chain1 = load_qa_chain(llm, chain_type="stuff", memory=projectwe_memory)

p_chain = ConversationalRetrievalChain( retriever=projectwe_retriever.as_retriever(), question_generator=projectwe_chain, combine_docs_chain=chain1, )

For MUSE

Initialize embeddings and AI

muse_embeddings = OpenAIEmbeddings()

Prompt Template

template = """

QUESTION: {question} CHAT HISTORY: {chat_history}

ANSWER: """ prompt = PromptTemplate(input_variables=["chat_history", "question"], template=template)

muse_memory = ConversationBufferMemory(memory_key="chat_history", input_key="question",return_messages=True)

muse_retriever = Pinecone.from_existing_index(index_name=index_name, embedding=muse_embeddings, namespace="cust-muse-mojomosaic-pinecone")

Llms

llm = ChatOpenAI(temperature=0) muse_chain = LLMChain(llm=llm, prompt=prompt,output_key='question')

ProjectWe-Chain

chain2 = load_qa_chain(llm, chain_type="stuff", memory=muse_memory)

m_chain = ConversationalRetrievalChain( retriever=muse_retriever.as_retriever(), question_generator=muse_chain, combine_docs_chain=chain2,

)

initilaize tool

tools=[ Tool.from_function( func=p_chain.run, name="ProjectWe_Virtual_Assistant", description="DESCRIBE ProjectWe" ), Tool.from_function( func=m_chain.run, name="Muse", description="Generate sections from Muse Bootstrap snippets for ProjectWe_Virtual_Assistant" ) ]

Set up Agent

model_name="gpt-4" agent_llm = ChatOpenAI(temperature=0.2,model_name=model_name)

Agent memory

agent_memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

chatagent = initialize_agent(tools, agent_llm, agent=AgentType.OPENAI_FUNCTIONS, memory = agent_memory,verbose=True)

@app.route('/') def index(): return render_template("flow.html")

@app.route('/send_message', methods=['POST']) def ask(): message = request.form['message'] if chatagent is None: return jsonify({'message': 'Agent not initialized'}) response = chatagent.run ({'input': {'question': message, 'chat_history': []}}) mem = agent_memory.save_context({'question': message}, {'answer': response}) chat_history = agent_memory.load_memory_variables({})['chat_history'] print("Response", response) return jsonify({'message': response, 'memory': chat_history})

if name == 'main': app.run(port = 5005, debug=True) Whole error:

Entering new AgentExecutor chain...

Invoking: Muse with ProjectWe

127.0.0.1 - - [01/Nov/2023 00:30:17] "POST /send_message HTTP/1.1" 500 - Traceback (most recent call last): File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 2213, in call return self.wsgi_app(environ, start_response) File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 2193, in wsgi_app response = self.handle_exception(e) File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 2190, in wsgi_app response = self.full_dispatch_request() File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1486, in full_dispatch_request rv = self.handle_user_exception(e) File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1484, in full_dispatch_request rv = self.dispatch_request() File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1469, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(*view_args) File "D:\mojosolo_projects\mojobob\conver.py", line 125, in ask response = chatagent.run ({'input': {'question': message, 'chat_history': []}}) File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\chains\base.py", line 487, in run return self(args[0], callbacks=callbacks, tags=tags, metadata=metadata)[ File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\chains\base.py", line 292, in call raise e File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\chains\base.py", line 286, in call self._call(inputs, run_manager=run_manager) File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\agents\agent.py", line 1039, in _call next_step_output = self._take_next_step( File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\agents\agent.py", line 894, in _take_next_step observation = tool.run( File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\tools\base.py", line 356, in run raise e File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\tools\base.py", line 328, in run self._run(tool_args, run_manager=run_manager, **tool_kwargs) File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\tools\base.py", line 499, in _run self.func( File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\chains\base.py", line 487, in run return self(args[0], callbacks=callbacks, tags=tags, metadata=metadata)[ File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\chains\base.py", line 268, in call inputs = self.prep_inputs(inputs) File "C:\Users\MUAZ\AppData\Local\Programs\Python\Python39\lib\site-packages\langchain\chains\base.py", line 415, in prep_inputs raise ValueError( ValueError: A single string input was passed in, but this chain expects multiple inputs ({'question', 'chat_history'}). When a chain expects multiple inputs, please call it by passing in a dictionary, eg chain({'foo': 1, 'bar': 2})

TinaHage commented 10 months ago

@tevslin This worked for me

"""Agent for working with pandas objects."""
from typing import Any, List, Optional

from langchain.agents.agent import AgentExecutor
# from langchain.agents.agent_toolkits.pandas.prompt import PREFIX, SUFFIX
from langchain.agents import ZeroShotAgent
from langchain.callbacks.base import BaseCallbackManager
from langchain.chains.llm import LLMChain
from langchain.llms.base import BaseLLM
from langchain.tools.python.tool import PythonAstREPLTool
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(memory_key="chat_history")
def create_pandas_dataframe_agent(
    llm: BaseLLM,
    df: Any,
    callback_manager: Optional[BaseCallbackManager] = None,
    prefix: str = PREFIX,
    suffix: str = SUFFIX,
    input_variables: Optional[List[str]] = None,
    verbose: bool = False,
    return_intermediate_steps: bool = False,
    max_iterations: Optional[int] = 15,
    max_execution_time: Optional[float] = None,
    early_stopping_method: str = "force",
    **kwargs: Any,
) -> AgentExecutor:
    """Construct a pandas agent from an LLM and dataframe."""
    import pandas as pd

    if not isinstance(df, pd.DataFrame):
        raise ValueError(f"Expected pandas object, got {type(df)}")
    if input_variables is None:
        input_variables = ["df", "input", "agent_scratchpad"]
    tools = [PythonAstREPLTool(locals={"df": df})]

    PREFIX = """
            You are working with a pandas dataframe in Python. The name of the dataframe is `df`.
            You should use the tools below to answer the question posed of you:"""

    SUFFIX = """
            This is the result of `print(df.head())`:
            {df}
            Begin!
            {chat_history}
            Question: {input}
            {agent_scratchpad}"""

    prompt = ZeroShotAgent.create_prompt(
        tools, 
        prefix=PREFIX,
        suffix=SUFFIX, 
        input_variables=["df", "input", "chat_history", "agent_scratchpad"]
    )

    print(prompt)

    partial_prompt = prompt.partial(df=str(df.head()))

    llm_chain = LLMChain(
        llm=llm,
        prompt=partial_prompt,
        callback_manager=callback_manager,
    )

    tool_names = [tool.name for tool in tools]

    agent = ZeroShotAgent(
        llm_chain=llm_chain,
        allowed_tools=tool_names,
        callback_manager=callback_manager,
        **kwargs,
    )
    return AgentExecutor.from_agent_and_tools(
        agent=agent,
        tools=tools,
        verbose=verbose,
        return_intermediate_steps=return_intermediate_steps,
        max_iterations=max_iterations,
        max_execution_time=max_execution_time,
        early_stopping_method=early_stopping_method,
        callback_manager=callback_manager,
        memory = memory
    )

How to use the function to start asking questions? @Rishav-hub

3dhunter97 commented 8 months ago

Thank you. That works very well. I did have to change the defaults of PREFIX and SUFFIX since they were undefined.

for production I'd suggest that memory be defined by the caller and passed in as an optional parameter with a default of None. Also the defaults for SUFFIX and PREFIX can be changed in prompts.py in the \pandas folder or overridden by the caller, Are you going to create a pull-request for this?

@tevslin Can you please share your SUFFIX and PREFIX that you have used for working with a CSV that uses memory and do not hallucinate much on the response. Thanks in advance

tevslin commented 8 months ago

I havenโ€™t been using Langchain lately as much as I appreciate it (busy with Autogen) and have never used it with CSVs,

From: 3dhunter97 @.> Sent: Friday, January 12, 2024 1:49 AM To: langchain-ai/langchain @.> Cc: Tom Evslin @.>; Mention @.> Subject: Re: [langchain-ai/langchain] Getting ConversationBufferMemory to work with create_pandas_dataframe_agent (Issue #3106)

Thank you. That works very well. I did have to change the defaults of PREFIX and SUFFIX since they were undefined.

for production I'd suggest that memory be defined by the caller and passed in as an optional parameter with a default of None. Also the defaults for SUFFIX and PREFIX can be changed in prompts.py in the \pandas folder or overridden by the caller, Are you going to create a pull-request for this?

@tevslin https://github.com/tevslin Can you please share your SUFFIX and PREFIX that you have used for working with a CSV that uses memory and do not hallucinate much on the response. Thanks in advance

โ€” Reply to this email directly, view it on GitHub https://github.com/langchain-ai/langchain/issues/3106#issuecomment-1888522623 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AGLSBBQCHBVLBFTVH5NNZ6DYODMG5AVCNFSM6AAAAAAXDCEVV6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOBYGUZDENRSGM . You are receiving this because you were mentioned. https://github.com/notifications/beacon/AGLSBBXSEETFCXGZESQQXI3YODMG5A5CNFSM6AAAAAAXDCEVV6WGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTTQSCIX6.gif Message ID: @. @.> >

ammarsaf commented 7 months ago

Error ModuleNotFoundError: No module named 'langchain.tools.python.tool'

ikouchiha47 commented 5 months ago

Error ModuleNotFoundError: No module named 'langchain.tools.python.tool'

https://python.langchain.com/docs/integrations/tools/python

ikouchiha47 commented 5 months ago

I am having some issues with the agent and agent executor. I have a pipeline as such.

class LanguageModelLoaderGPU:
    # @suppress_error_output
    model_cfg = TapexModel()

    def __init__(self, model_name=None, model_file=None):
        self.model_name = self.model_cfg.model_name if model_name is None else model_name
        self.model_file = self.model_cfg.model_file if model_file is None else model_file
        self.verbose = False

        quantization_config = BitsAndBytesConfig(
            load_in_8bit=True,
            llm_int8_threshold=100.0)

        _model = BartForConditionalGeneration.from_pretrained(
            self.model_cfg.t_model_name,
            torch_dtype=torch.float16,
            cache_dir="./models",
            # max_new_tokens=256,
            # top_p=0.95,
            # top_k=5,
            # quantization_config=quantization_config,
        )
        _tokenizer = TapexTokenizer.from_pretrained(
            self.model_cfg.t_model_name,
            model_max_length=512,
            cache_dir="./models",
        )
        pipe_summary = pipeline("table-question-answering", model=_model, tokenizer=_tokenizer, max_new_tokens=1024)
        hf_summary = HuggingFacePipeline(pipeline=pipe_summary)

        self.model = hf_summary

And I am trying to use the agent.invoke.

class CliViewer:
    def __init__(self, file_name):
        self.file_name = file_name
        self.df = pd.read_csv(file_name)

        print("getting llm model", self.df.head())

        _llm = LanguageModelLoaderGPU()
        # chat_memory = PandasChatMemory(_llm.model).with_history().with_summary()
        chat_memory = PandasChatMemory(_llm.model).get_memory()
        #
        # print("initializing pandas agent")
        self.agent = create_pandas_dataframe_agent(
            llm=_llm.model,
            df=self.df,
            # suffix=SUFFIX_WITH_DF,
            agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
            prefix=TEMPLATE,
            early_stopping_method='generate',
            max_iterations=5,
            include_df_in_prompt=True,
            agent_executor_kwargs={
                'handling_parsing_errors': "Check your output and make sure it conforms!",
                'memory': chat_memory,
            },
            verbose=True,
        )

        print("pandas agent loading complete", self.df.head())
        # session = PromptSession(history=FileHistory(".agent-history-file"))
        # while True:
        question = "How many matches did Chennai Super Kings win and lose?"

        print("invoking agent")
        result = self.agent.invoke({"input": question}, callbacks=[StreamingStdOutCallbackHandler()])
        print("result", result)

I am getting an error.

Short summary:

  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/src/views/clileet.py", line 114, in __init__
    result = self.agent.invoke({"input": question}, callbacks=[StreamingStdOutCallbackHandler()])
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    raise ValueError(
ValueError: Keyword argument `table` should be a list of dict, but is <generator object TableQuestionAnsweringArgumentHandler.__call__.<locals>.<genexpr> at 0x16dc0ecf0>

Trace:

Traceback (most recent call last):
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/main.py", line 53, in <module>
    main()
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/main.py", line 47, in main
    run_cli_command(args)
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/main.py", line 23, in run_cli_command
    CliViewer(args.file)
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/src/views/clileet.py", line 114, in __init__
    result = self.agent.invoke({"input": question}, callbacks=[StreamingStdOutCallbackHandler()])
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain/chains/base.py", line 163, in invoke
    raise e
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain/chains/base.py", line 153, in invoke
    self._call(inputs, run_manager=run_manager)
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain/agents/agent.py", line 1432, in _call
    next_step_output = self._take_next_step(
                       ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain/agents/agent.py", line 1138, in _take_next_step
    [
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain/agents/agent.py", line 1166, in _iter_next_step
    output = self.agent.plan(
             ^^^^^^^^^^^^^^^^
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain/agents/agent.py", line 397, in plan
    for chunk in self.runnable.stream(inputs, config={"callbacks": callbacks}):
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/runnables/base.py", line 2685, in stream
    yield from self.transform(iter([input]), config, **kwargs)
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/runnables/base.py", line 2672, in transform
    yield from self._transform_stream_with_config(
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/runnables/base.py", line 1743, in _transform_stream_with_config
    chunk: Output = context.run(next, iterator)  # type: ignore
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/runnables/base.py", line 2636, in _transform
    for output in final_pipeline:
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/runnables/base.py", line 1209, in transform
    for chunk in input:
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/runnables/base.py", line 4532, in transform
    yield from self.bound.transform(
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/runnables/base.py", line 1226, in transform
    yield from self.stream(final, config, **kwargs)
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/language_models/llms.py", line 386, in stream
    yield self.invoke(input, config=config, stop=stop, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/language_models/llms.py", line 248, in invoke
    self.generate_prompt(
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/language_models/llms.py", line 569, in generate_prompt
    return self.generate(prompt_strings, stop=stop, callbacks=callbacks, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/language_models/llms.py", line 748, in generate
    output = self._generate_helper(
             ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/language_models/llms.py", line 606, in _generate_helper
    raise e
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_core/language_models/llms.py", line 593, in _generate_helper
    self._generate(
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/langchain_community/llms/huggingface_pipeline.py", line 266, in _generate
    responses = self.pipeline(
                ^^^^^^^^^^^^^^
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/transformers/pipelines/table_question_answering.py", line 344, in __call__
    pipeline_inputs = self._args_parser(*args, **kwargs)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/alexday/dev/llmexperiments/csv-agents-llm/.venv/lib/python3.12/site-packages/transformers/pipelines/table_question_answering.py", line 54, in __call__
    raise ValueError(
ValueError: Keyword argument `table` should be a list of dict, but is <generator object TableQuestionAnsweringArgumentHandler.__call__.<locals>.<genexpr> at 0x16dc0ecf0>

Help please?