langchain icon indicating copy to clipboard operation
langchain copied to clipboard

feat: add saving and loading conversation chain with memory

Open ibiscp opened this issue 2 years ago • 4 comments

I implemented saving and loading conversation chain with memory:

from langchain.llms import OpenAI
from langchain.chains import ConversationChain
from langchain.chains.conversation.memory import ConversationBufferMemory

llm = OpenAI(temperature=0)
conversation = ConversationChain(
    llm=llm, 
    verbose=True, 
    memory=ConversationBufferMemory()
)

conversation.predict(input="Hi there! My name is Ibis Prevedello")
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.

Current conversation:

Human: Hi there! My name is Ibis Prevedello
AI:

> Finished chain.
" Hi Ibis Prevedello! It's nice to meet you. My name is AI-1. What can I do for you today?"

Saving the chain!

conversation.save("conversation_test.json")

Loading the chain!

from langchain.chains.loading import load_chain_from_config
import json

# Open json file
with open("conversation_test.json", "r") as f:
    conversation_json = json.load(f)

loaded = load_chain_from_config(conversation_json)

loaded.predict(input="What is my name?")
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.

Current conversation:

Human: Hi there! My name is Ibis Prevedello
AI:  Hi Ibis Prevedello! It's nice to meet you. My name is AI-1. What can I do for you today?
Human: What is my name?
AI:

> Finished chain.
' Your name is Ibis Prevedello. Is there anything else I can help you with?'

ibiscp avatar Feb 11 '23 14:02 ibiscp

Yes, I can work on that. I just got confused about why the Memory is inside the conversation chain. Sorry, I've been working on this code for some hours only.

ibiscp avatar Feb 11 '23 21:02 ibiscp

Yes, I can work on that. I just got confused about why the Memory is inside the conversation chain. Sorry, I've been working on this code for some hours only.

yeah - this is tech debt :/ we should move to its own folder at some point, but that can be separate pr

hwchase17 avatar Feb 11 '23 21:02 hwchase17

@hwchase17 Can we merge this?

ibiscp avatar Feb 16 '23 17:02 ibiscp

I tried the sample code and it works.

Then I switched from ConversationBufferMemory to ConversationSummaryBufferMemory and got the following error

Traceback (most recent call last):
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 372, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/fastapi/applications.py", line 261, in __call__
    await super().__call__(scope, receive, send)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/starlette/middleware/cors.py", line 84, in __call__
    await self.app(scope, receive, send)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/starlette/routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/starlette/routing.py", line 259, in handle
    await self.app(scope, receive, send)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/starlette/routing.py", line 61, in app
    response = await func(request)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/fastapi/routing.py", line 227, in app
    raw_response = await run_endpoint_function(
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/fastapi/routing.py", line 160, in run_endpoint_function
    return await dependant.call(**values)
  File "/Users/gilbertleung/Projects/social-wallet-nft/./py_packages/telegram_server/app.py", line 54, in telegram
    conversation = load_chain_from_config(conversation_json)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/langchain/chains/loading.py", line 469, in load_chain_from_config
    return chain_loader(config, **kwargs)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/langchain/chains/loading.py", line 75, in _load_llm_conversation_chain
    memory = load_memory_from_config(memory_config)
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/langchain/chains/conversation/loading.py", line 22, in load_memory_from_config
    return memory_cls(**config)
  File "pydantic/main.py", line 340, in pydantic.main.BaseModel.__init__
  File "pydantic/main.py", line 1103, in pydantic.main.validate_model
  File "/Users/gilbertleung/Projects/social-wallet-nft/.venv/lib/python3.9/site-packages/langchain/chains/conversation/memory.py", line 359, in validate_prompt_input_variables
    prompt_variables = values["prompt"].input_variables
KeyError: 'prompt'

Here's the file

{
    "memory": {
        "buffer": [
            "Human: hello\nAI:  Hi there! It's nice to meet you. How can I help you today?"
        ],
        "max_token_limit": 2000,
        "moving_summary_buffer": "",
        "llm": {
            "model_name": "text-davinci-003",
            "temperature": 0.7,
            "max_tokens": 256,
            "top_p": 1,
            "frequency_penalty": 0,
            "presence_penalty": 0,
            "n": 1,
            "best_of": 1,
            "request_timeout": null,
            "logit_bias": {},
            "_type": "openai"
        },
        "prompt": {
            "input_variables": [
                "summary",
                "new_lines"
            ],
            "output_parser": null,
            "template": "Progressively summarize the lines of conversation provided, adding onto the previous summary returning a new summary.\n\nEXAMPLE\nCurrent summary:\nThe human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good.\n\nNew lines of conversation:\nHuman: Why do you think artificial intelligence is a force for good?\nAI: Because artificial intelligence will help humans reach their full potential.\n\nNew summary:\nThe human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good because it will help humans reach their full potential.\nEND OF EXAMPLE\n\nCurrent summary:\n{summary}\n\nNew lines of conversation:\n{new_lines}\n\nNew summary:",
            "template_format": "f-string",
            "validate_template": true,
            "_type": "prompt"
        },
        "memory_key": "history",
        "human_prefix": "Human",
        "ai_prefix": "AI",
        "output_key": null,
        "input_key": null,
        "_type": "conversation_summary_buffer"
    },
    "verbose": true,
    "prompt": {
        "input_variables": [
            "history",
            "input"
        ],
        "output_parser": null,
        "template": "The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n\nCurrent conversation:\n{history}\nHuman: {input}\nAI:",
        "template_format": "f-string",
        "validate_template": true,
        "_type": "prompt"
    },
    "llm": {
        "model_name": "text-davinci-003",
        "temperature": 0.0,
        "max_tokens": 256,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0,
        "n": 1,
        "best_of": 1,
        "request_timeout": null,
        "logit_bias": {},
        "_type": "openai"
    },
    "output_key": "response",
    "input_key": "input",
    "_type": "llm_conversation_chain"
}

gilbertl avatar Feb 17 '23 23:02 gilbertl