{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d31df93e",
   "metadata": {},
   "source": [
    "# Getting Started\n",
    "\n",
    "This notebook walks through the different types of memory you can use with the `ConversationChain`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d051c1da",
   "metadata": {},
   "source": [
    "## ConversationBufferMemory (default)\n",
    "By default, the `ConversationChain` uses `ConversationBufferMemory`: a simple type of memory that remembers all previous inputs/outputs and adds them to the context that is passed. Let's take a look at using this chain (setting `verbose=True` so we can see the prompt)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "54301321",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.llms import OpenAI\n",
    "from langchain.chains import ConversationChain\n",
    "from langchain.chains.conversation.memory import ConversationBufferMemory\n",
    "\n",
    "\n",
    "llm = OpenAI(temperature=0)\n",
    "conversation = ConversationChain(\n",
    "    llm=llm, \n",
    "    verbose=True, \n",
    "    memory=ConversationBufferMemory()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ae046bff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "Human: Hi there!\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Hi there! It's nice to meet you. How can I help you today?\""
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"Hi there!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d8e2a6ff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "Human: Hi there!\n",
      "AI:  Hi there! It's nice to meet you. How can I help you today?\n",
      "Human: I'm doing well! Just having a conversation with an AI.\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" That's great! It's always nice to have a conversation with someone new. What would you like to talk about?\""
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"I'm doing well! Just having a conversation with an AI.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "15eda316",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "Human: Hi there!\n",
      "AI:  Hi there! It's nice to meet you. How can I help you today?\n",
      "Human: I'm doing well! Just having a conversation with an AI.\n",
      "AI:  That's great! It's always nice to have a conversation with someone new. What would you like to talk about?\n",
      "Human: Tell me about yourself.\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Sure! I'm an AI created to help people with their everyday tasks. I'm programmed to understand natural language and provide helpful information. I'm also constantly learning and updating my knowledge base so I can provide more accurate and helpful answers.\""
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"Tell me about yourself.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4fad9448",
   "metadata": {},
   "source": [
    "## ConversationSummaryMemory\n",
    "Now let's take a look at using a slightly more complex type of memory - `ConversationSummaryMemory`. This type of memory creates a summary of the conversation over time. This can be useful for condensing information from the conversation over time.\n",
    "\n",
    "Let's walk through an example, again setting `verbose=True` so we can see the prompt."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f60a2fe8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains.conversation.memory import ConversationSummaryMemory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b7274f2c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "Human: Hi, what's up?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Hi there! I'm doing great. I'm currently helping a customer with a technical issue. How about you?\""
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary = ConversationChain(\n",
    "    llm=llm, \n",
    "    memory=ConversationSummaryMemory(llm=OpenAI()),\n",
    "    verbose=True\n",
    ")\n",
    "conversation_with_summary.predict(input=\"Hi, what's up?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a6b6b88f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "The human greets the AI and the AI responds, saying it is doing well and is currently helping a customer with a technical issue.\n",
      "Human: Tell me more about it!\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Sure! The customer is having trouble with their computer not connecting to the internet. I'm helping them troubleshoot the issue and figure out what the problem is. So far, we've tried resetting the router and checking the network settings, but the issue still persists. We're currently looking into other possible causes.\""
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary.predict(input=\"Tell me more about it!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "dad869fe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "\n",
      "The human greets the AI and the AI responds, saying it is doing well and is currently helping a customer with a technical issue. The customer is having trouble with their computer not connecting to the internet, and the AI is helping them troubleshoot the issue by resetting the router and checking the network settings. They are still looking into other possible causes.\n",
      "Human: Very cool -- what is the scope of the project?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "' The scope of the project is to help the customer troubleshoot the issue with their computer not connecting to the internet. We are currently resetting the router and checking the network settings, and we are looking into other possible causes.'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary.predict(input=\"Very cool -- what is the scope of the project?\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6eecf9d9",
   "metadata": {},
   "source": [
    "## ConversationBufferWindowMemory\n",
    "\n",
    "`ConversationBufferWindowMemory` keeps a list of the interactions of the conversation over time. It only uses the last K interactions. This can be useful for keeping a sliding window of the most recent interactions, so the buffer does not get too large\n",
    "\n",
    "Let's walk through an example, again setting `verbose=True` so we can see the prompt."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "2dac7769",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains.conversation.memory import ConversationBufferWindowMemory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "0b9da4cd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "Human: Hi, what's up?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Hi there! I'm doing great. I'm currently helping a customer with a technical issue. How about you?\""
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary = ConversationChain(\n",
    "    llm=llm, \n",
    "    # We set a low k=2, to only keep the last 2 interactions in memory\n",
    "    memory=ConversationBufferWindowMemory(k=2), \n",
    "    verbose=True\n",
    ")\n",
    "conversation_with_summary.predict(input=\"Hi, what's up?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "90f73431",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "Human: Hi, what's up?\n",
      "AI:  Hi there! I'm doing great. I'm currently helping a customer with a technical issue. How about you?\n",
      "Human: What's their issues?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" The customer is having trouble connecting to their Wi-Fi network. I'm helping them troubleshoot the issue and get them connected.\""
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary.predict(input=\"What's their issues?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "cbb499e7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "Human: Hi, what's up?\n",
      "AI:  Hi there! I'm doing great. I'm currently helping a customer with a technical issue. How about you?\n",
      "Human: What's their issues?\n",
      "AI:  The customer is having trouble connecting to their Wi-Fi network. I'm helping them troubleshoot the issue and get them connected.\n",
      "Human: Is it going well?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Yes, it's going well so far. We've already identified the problem and are now working on a solution.\""
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary.predict(input=\"Is it going well?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "0d209cfe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "Human: What's their issues?\n",
      "AI:  The customer is having trouble connecting to their Wi-Fi network. I'm helping them troubleshoot the issue and get them connected.\n",
      "Human: Is it going well?\n",
      "AI:  Yes, it's going well so far. We've already identified the problem and are now working on a solution.\n",
      "Human: What's the solution?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" The solution is to reset the router and reconfigure the settings. We're currently in the process of doing that.\""
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Notice here that the first interaction does not appear.\n",
    "conversation_with_summary.predict(input=\"What's the solution?\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6d2569f",
   "metadata": {},
   "source": [
    "## ConversationSummaryBufferMemory\n",
    "\n",
    "`ConversationSummaryBufferMemory` combines the last two ideas. It keeps a buffer of recent interactions in memory, but rather than just completely flushing old interactions it compiles them into a summary and uses both. Unlike the previous implementation though, it uses token length rather than number of interactions to determine when to flush interactions.\n",
    "\n",
    "Let's walk through an example, again setting `verbose=True` so we can see the prompt."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "e583a661",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains.conversation.memory import ConversationSummaryBufferMemory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "ebd68c10",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "Human: Hi, what's up?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Hi there! I'm doing great. I'm currently helping a customer with a technical issue. How about you?\""
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary = ConversationChain(\n",
    "    llm=llm, \n",
    "    # We set a very low max_token_limit for the purposes of testing.\n",
    "    memory=ConversationSummaryBufferMemory(llm=OpenAI(), max_token_limit=40),\n",
    "    verbose=True\n",
    ")\n",
    "conversation_with_summary.predict(input=\"Hi, what's up?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "86207a61",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "Human: Hi, what's up?\n",
      "AI:  Hi there! I'm doing great. I'm currently helping a customer with a technical issue. How about you?\n",
      "Human: Just working on writing some documentation!\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "' That sounds like a lot of work. What kind of documentation are you writing?'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary.predict(input=\"Just working on writing some documentation!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "76a0ab39",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "The human asked the AI what it was up to, and the AI responded that it was helping a customer with a technical issue.\n",
      "Human: Just working on writing some documentation!\n",
      "AI:  That sounds like a lot of work. What kind of documentation are you writing?\n",
      "Human: For LangChain! Have you heard of it?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "' Yes, I have heard of LangChain. It is a blockchain-based language learning platform. Can you tell me more about the documentation you are writing?'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# We can see here that there is a summary of the conversation and then some previous interactions\n",
    "conversation_with_summary.predict(input=\"For LangChain! Have you heard of it?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "8c669db1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe 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",
      "\n",
      "Current conversation:\n",
      "\n",
      "The human asked the AI what it was up to, and the AI responded that it was helping a customer with a technical issue. The human then mentioned they were writing documentation for LangChain, a blockchain-based language learning platform, and the AI revealed they had heard of it and asked the human to tell them more about the documentation they were writing.\n",
      "\n",
      "Human: Haha nope, although a lot of people confuse it for that\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished ConversationChain chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "' Oh, I see. So, what kind of documentation are you writing for LangChain?'"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# We can see here that the summary and the buffer are updated\n",
    "conversation_with_summary.predict(input=\"Haha nope, although a lot of people confuse it for that\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f71f40ba",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
