{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "44c9933a",
   "metadata": {},
   "source": [
    "# Conversation Knowledge Graph\n",
    "\n",
    "This type of memory uses a knowledge graph to recreate memory.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c798006-ca04-4de3-83eb-cf167fb2bd01",
   "metadata": {},
   "source": [
    "## Using memory with LLM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f71f40ba",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.llms import OpenAI\n",
    "from langchain.memory import ConversationKGMemory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2f4a3c85",
   "metadata": {},
   "outputs": [],
   "source": [
    "llm = OpenAI(temperature=0)\n",
    "memory = ConversationKGMemory(llm=llm)\n",
    "memory.save_context({\"input\": \"say hi to sam\"}, {\"output\": \"who is sam\"})\n",
    "memory.save_context({\"input\": \"sam is a friend\"}, {\"output\": \"okay\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "72283b4f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': 'On Sam: Sam is friend.'}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory.load_memory_variables({\"input\": \"who is sam\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c8ff11e",
   "metadata": {},
   "source": [
    "We can also get the history as a list of messages (this is useful if you are using this with a chat model)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "44df43af",
   "metadata": {},
   "outputs": [],
   "source": [
    "memory = ConversationKGMemory(llm=llm, return_messages=True)\n",
    "memory.save_context({\"input\": \"say hi to sam\"}, {\"output\": \"who is sam\"})\n",
    "memory.save_context({\"input\": \"sam is a friend\"}, {\"output\": \"okay\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "4726b1c8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': [SystemMessage(content='On Sam: Sam is friend.', additional_kwargs={})]}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory.load_memory_variables({\"input\": \"who is sam\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc956b0e",
   "metadata": {},
   "source": [
    "We can also more modularly get current entities from a new message (will use previous messages as context)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "36331ca5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Sam']"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory.get_current_entities(\"what's Sams favorite color?\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8749134",
   "metadata": {},
   "source": [
    "We can also more modularly get knowledge triplets from a new message (will use previous messages as context)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b02d44db",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[KnowledgeTriple(subject='Sam', predicate='favorite color', object_='red')]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory.get_knowledge_triplets(\"her favorite color is red\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7a02ef3",
   "metadata": {},
   "source": [
    "## Using in a chain\n",
    "\n",
    "Let's now use this in a chain!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b462baf1",
   "metadata": {},
   "outputs": [],
   "source": [
    "llm = OpenAI(temperature=0)\n",
    "from langchain.chains import ConversationChain\n",
    "from langchain.prompts.prompt import PromptTemplate\n",
    "\n",
    "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. \n",
    "If the AI does not know the answer to a question, it truthfully says it does not know. The AI ONLY uses information contained in the \"Relevant Information\" section and does not hallucinate.\n",
    "\n",
    "Relevant Information:\n",
    "\n",
    "{history}\n",
    "\n",
    "Conversation:\n",
    "Human: {input}\n",
    "AI:\"\"\"\n",
    "prompt = PromptTemplate(input_variables=[\"history\", \"input\"], template=template)\n",
    "conversation_with_kg = ConversationChain(\n",
    "    llm=llm, verbose=True, prompt=prompt, memory=ConversationKGMemory(llm=llm)\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "97efaf38",
   "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. \n",
      "If the AI does not know the answer to a question, it truthfully says it does not know. The AI ONLY uses information contained in the \"Relevant Information\" section and does not hallucinate.\n",
      "\n",
      "Relevant Information:\n",
      "\n",
      "\n",
      "\n",
      "Conversation:\n",
      "Human: Hi, what's up?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Hi there! I'm doing great. I'm currently in the process of learning about the world around me. I'm learning about different cultures, languages, and customs. It's really fascinating! How about you?\""
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_kg.predict(input=\"Hi, what's up?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "55b5bcad",
   "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. \n",
      "If the AI does not know the answer to a question, it truthfully says it does not know. The AI ONLY uses information contained in the \"Relevant Information\" section and does not hallucinate.\n",
      "\n",
      "Relevant Information:\n",
      "\n",
      "\n",
      "\n",
      "Conversation:\n",
      "Human: My name is James and I'm helping Will. He's an engineer.\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Hi James, it's nice to meet you. I'm an AI and I understand you're helping Will, the engineer. What kind of engineering does he do?\""
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_kg.predict(\n",
    "    input=\"My name is James and I'm helping Will. He's an engineer.\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9981e219",
   "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. \n",
      "If the AI does not know the answer to a question, it truthfully says it does not know. The AI ONLY uses information contained in the \"Relevant Information\" section and does not hallucinate.\n",
      "\n",
      "Relevant Information:\n",
      "\n",
      "On Will: Will is an engineer.\n",
      "\n",
      "Conversation:\n",
      "Human: What do you know about Will?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "' Will is an engineer.'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_kg.predict(input=\"What do you know about Will?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8c09a239",
   "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.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
