langchain-ai / langchain

🦜🔗 Build context-aware reasoning applications
https://python.langchain.com
MIT License
94.59k stars 15.31k forks source link

Issue: SQLDatabaseChain fails to run when initialised with custom read only memory #11211

Closed amadupu closed 1 year ago

amadupu commented 1 year ago

Issue you'd like to raise.

I have custom memory with memory key as 'context' as follows which i would like to use in the underling chain as readonly memory

memory = ScopeContextMemory(memory_key='context')
readonlymemory = ReadOnlySharedMemory(memory_key='context', memory=memory)

i have the following template stored in a file

Given an input question, first create a syntactically correct {dialect} query to run, then look at the results of the query and return the answer.
Use the following format:

Question: "Question here"
SQLQuery: "SQL Query to run"
SQLResult: "Result of the SQLQuery"
Answer: "Final answer here"

Only use the following tables:
{table_info}

Use the following context for the query generation:
{context}

i have prompt initialised as follows

with open('prompts/sql_default_prompt.txt','r') as fp:
    DEFAULT_PROMPT = PromptTemplate(input_variables=['input','table_info','dialect', 'context'], 
                                          template=fp.read())

NOTE: 'context' is added as one of the input variable

Ive initialised SQL Database chain as follows

llm=OpenAI(temperature=0)

chain = SQLDatabaseChain.from_llm(llm=llm, 
                                  db=db, 
                                  verbose=True,
                                  use_query_checker=True, 
                                  prompt=DEFAULT_PROMPT,
                                  return_intermediate_steps=True, 
                                  memory=memory,
                                  top_k=3)

when i tried to run im getting an exception on missing input keys 'context'

chain("List Items under the shopping cart for Davis")

---------------------------------------------------------------------------
ValueError  
    169 missing_keys = set(self.input_keys).difference(inputs)
    170 if missing_keys:
--> 171     raise ValueError(f"Missing some input keys: {missing_keys}")

ValueError: Missing some input keys: {'context'}

Suggestion:

Ive tried looking at the documention on memory and its usage in chain , tools and agents but could not figure out what is going wrong here. any pointers on the cause is appreciated and how can i remediate the thing

dosubot[bot] commented 1 year ago

🤖

Hello,

Thank you for bringing this issue to our attention. The error you're encountering is due to the 'context' key not being found in the inputs dictionary when the load_memory_variables method is called in the ReadOnlySharedMemory class.

In the LangChain framework, the load_memory_variables method is expected to handle all necessary keys in the inputs dictionary, including 'context'. If the 'context' key is not found in the inputs dictionary, the SQLDatabaseChain will throw a "Missing some input keys: {'context'}" error.

To fix this issue, you need to modify the load_memory_variables method to handle the 'context' key. Here is an example of how you can do this:

def load_memory_variables(self, inputs: Dict[str, Any]) -> Dict[str, str]:
    """Load memory variables from memory."""
    if 'context' not in inputs:
        inputs['context'] = None
    return self.memory.load_memory_variables(inputs)

This code checks if the 'context' key is in the inputs dictionary. If it's not, it adds the 'context' key with a value of None. Then, it calls the load_memory_variables method of the memory object with the updated inputs dictionary.

Please note that this is a workaround and might not be the best solution depending on your use case. If you continue to encounter issues, please provide more details about your use case and we'll be happy to assist further.

Best, Dosu

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

amadupu commented 1 year ago

@dosu-bot

as a part of ScopeContextMemory im taking care of the context in the load_memory_variables method definition. is there anything wrong it the following implementation

class ScopeContextMemory(BaseMemory, BaseModel):
    """Memory class for storing information about scope context."""

    # Define dictionary to store information about entities.
    context: dict = {}
    # Define key to pass information about entities into prompt.
    memory_key: str = "context"

    def clear(self):
        self.context = {}

    @property
    def memory_variables(self) -> List[str]:
        """Define the variables we are providing to the prompt."""
        return [self.memory_key]

    def load_memory_variables(self, inputs: Dict[str, Any]) -> Dict[str, str]:
        """Load the memory variables, in this case the scope context flattend key value pairs in."""

        # Return combined information about entities to put into context.

        flattend_context = ''
        for key,value in self.context.items():
            flattend_context += '{}:{}\n'.format(key,value)

        return {self.memory_key: flattend_context}
dosubot[bot] commented 1 year ago

🤖

Hello,

The error message "Missing some input keys: {'context'}" suggests that the 'context' key is expected but not provided in the input variables. This could be due to the 'context' key not being included in the memory_keys or input_key in the validate_prompt_input_variables method.

The validate_prompt_input_variables method in the ConversationChain class checks if the keys in memory_keys and input_key match the keys in prompt_variables. If they don't match, it raises a ValueError.

To resolve this issue, you need to ensure that the 'context' key is included in the memory_keys or input_key. If you're using a custom memory, you need to make sure that the 'context' key is included in the memory_variables of your custom memory class. If the 'context' key is supposed to be the input_key, you need to set the input_key to 'context' when initializing the ConversationChain class.

Here's an example of how you can do this:

from langchain.chains import ConversationChain
from langchain.llms import OpenAI
from langchain.memory import BaseMemory

class CustomMemory(BaseMemory):
    memories: Dict[str, Any] = dict()

    @property
    def memory_variables(self):
        return list(self.memories.keys())

    def load_memory_variables(self, inputs: Dict[str, Any]) -> Dict[str, str]:
        return self.memories

conversation = ConversationChain(llm=OpenAI(), memory=CustomMemory())

In this example, the 'context' key is included in the memory_variables of the CustomMemory class. Therefore, the 'context' key will be included in the memory_keys in the validate_prompt_input_variables method, and the ValueError will not be raised.

In the context shared, the BaseMemory class in LangChain has an abstract method load_memory_variables that returns key-value pairs given the text input to the chain. If you're handling the 'context' in the load_memory_variables method of your custom memory class, make sure that the 'context' key is included in the return value of this method.

I hope this helps! Let me know if you have any other questions.

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

amadupu commented 1 year ago

@dosu-bot

as ive indicated above im properly included the context in the definition memory variables but even then im having an issue

class ScopeContextMemory(BaseMemory, BaseModel):
    """Memory class for storing information about scope context."""

    # Define dictionary to store information about entities.
    context: dict = {}
    # Define key to pass information about entities into prompt.
    memory_key: str = "context"

    def clear(self):
        self.context = {}

    @property
    def memory_variables(self) -> List[str]:
        """Define the variables we are providing to the prompt."""
        return [self.memory_key]
amadupu commented 1 year ago

@dosu-bot i know your exceptional in helping the first level analysis..but i would perfer this question get addressed by the developer form lead by humans and not the bots. i love you though

dosubot[bot] commented 1 year ago

🤖

Hello,

Thank you for providing a detailed explanation of your issue. The error you're encountering is due to a mismatch between the input variables expected by the prompt and the keys provided from the memory and the normal input key. This is checked in the validate_prompt_input_variables method of the ConversationChain class.

In your case, the error message indicates that the 'context' key is missing. This suggests that the 'context' key is expected by the prompt but is not provided by the memory variables or the normal input key.

To resolve this issue, you should ensure that the 'context' key is included in the memory variables of your custom memory class or as the normal input key. If the 'context' key is already defined in your custom memory class, you should check that it is correctly being returned by the memory_variables property of your custom memory class.

Here's an example of how you might define the memory_variables property in your custom memory class:

class GenerativeAgentMemory(BaseMemory):
    context: str = Field(...)

    @property
    def memory_variables(self):
        return ['context']

In this example, the 'context' key is defined as a field in the GenerativeAgentMemory class and is included in the list of memory variables returned by the memory_variables property. This would ensure that the 'context' key is provided to the ConversationChain class and prevent the ValueError from being raised.

You can refer to the following sources for more information:

I hope this helps! If you have any other questions, feel free to ask.

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

amadupu commented 1 year ago

as explained in this thread https://github.com/langchain-ai/langchain/issues/6918#issuecomment-1694608940 the support for memory in SQLDatabaseChain is being looked into however the alternative way is epxlain which seems to work

amadupu commented 1 year ago

as explained in this thread https://github.com/langchain-ai/langchain/issues/6918#issuecomment-1694608940 the support for memory in SQLDatabaseChain is being looked into however the alternative way is epxlain which seems to work