{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"https://colab.research.google.com/github/microsoft/autogen/blob/main/notebook/agentchat_teachability.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chatting with TeachableAgent\n",
    "\n",
    "Conversational assistants based on LLMs can remember the current chat with the user, and can even demonstrate in-context learning of things that the user teaches the assistant during the chat. But these memories and learnings are lost once the chat is over, or when a single chat grows too long for the LLM to handle effectively. In subsequent chats, the user is forced to repeat any necessary instructions over and over.\n",
    "\n",
    "`TeachableAgent` addresses these limitations by persisting user teachings across chat boundaries in long-term memory (a vector database). Memory is saved to disk at the end of each chat, then loaded from disk at the start of the next. Instead of copying all of memory into the context window, which would eat up valuable space, individual memories (called memos) are retrieved into context as needed. This allows the user to teach frequently used facts and skills to the teachable agent just once, and have it remember them in later chats.\n",
    "\n",
    "In making decisions about memo storage and retrieval, `TeachableAgent` calls an instance of `TextAnalyzerAgent` to analyze pieces of text in several different ways. This adds extra LLM calls involving a relatively small number of tokens. These calls can add a few seconds to the time a user waits for a response.\n",
    "\n",
    "This notebook demonstrates how `TeachableAgent` can learn facts, preferences, and skills from users. To chat with `TeachableAgent` yourself, run [chat_with_teachable_agent.py](../test/agentchat/chat_with_teachable_agent.py).\n",
    "\n",
    "## Requirements\n",
    "\n",
    "AutoGen requires `Python>=3.8`. To run this notebook example, please install the [teachable] option.\n",
    "```bash\n",
    "pip install \"pyautogen[teachable]\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%capture --no-stderr\n",
    "# %pip install \"pyautogen[teachable]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Set your API Endpoint\n",
    "\n",
    "The [`config_list_from_json`](https://microsoft.github.io/autogen/docs/reference/oai/openai_utils#config_list_from_json) function loads a list of configurations from an environment variable or a json file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gpt-4\n"
     ]
    }
   ],
   "source": [
    "import autogen\n",
    "\n",
    "config_list = autogen.config_list_from_json(\n",
    "    env_or_file=\"OAI_CONFIG_LIST\",\n",
    "    file_location=\".\",\n",
    "    filter_dict={\n",
    "        \"model\": [\"gpt-4\", \"gpt4\", \"gpt-4-32k\"],\n",
    "    },\n",
    ")\n",
    "\n",
    "print(config_list[0][\"model\"])"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It first looks for environment variable \"OAI_CONFIG_LIST\" which needs to be a valid json string. If that variable is not found, it then looks for a json file named \"OAI_CONFIG_LIST\". It filters the configs by models (you can filter by other keys as well). After application of this particular filter, only the gpt-4 models are kept.\n",
    "\n",
    "The config list looks like the following:\n",
    "```python\n",
    "config_list = [\n",
    "    {\n",
    "        'model': 'gpt-4',\n",
    "        'api_key': '<your OpenAI API key here>',\n",
    "    },\n",
    "    {\n",
    "        'model': 'gpt-4',\n",
    "        'api_key': '<your Azure OpenAI API key here>',\n",
    "        'api_base': '<your Azure OpenAI API base here>',\n",
    "        'api_type': 'azure',\n",
    "        'api_version': '2023-06-01-preview',\n",
    "    },\n",
    "    {\n",
    "        'model': 'gpt-4-32k',\n",
    "        'api_key': '<your Azure OpenAI API key here>',\n",
    "        'api_base': '<your Azure OpenAI API base here>',\n",
    "        'api_type': 'azure',\n",
    "        'api_version': '2023-06-01-preview',\n",
    "    },\n",
    "]\n",
    "```\n",
    "\n",
    "If you open this notebook in colab, you can upload your files by clicking the file icon on the left panel and then choose \"upload file\" icon.\n",
    "\n",
    "You can set the value of config_list in other ways if you prefer, e.g., loading from a YAML file."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Construct Agents\n",
    "For this walkthrough, we start by resetting the teachable agent's memory store. This deletes any memories from prior conversations that may be stored on disk."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[92m\n",
      "CLEARING MEMORY\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "from autogen.agentchat.contrib.teachable_agent import TeachableAgent\n",
    "from autogen import UserProxyAgent\n",
    "\n",
    "llm_config = {\n",
    "    \"request_timeout\": 60,\n",
    "    \"config_list\": config_list,\n",
    "    \"use_cache\": True,  # Use False to explore LLM non-determinism.\n",
    "}\n",
    "\n",
    "teach_config={\n",
    "    \"verbosity\": 0,  # 0 for basic info, 1 to add memory operations, 2 for analyzer messages, 3 for memo lists.\n",
    "    \"reset_db\": True,  # Set to True to start over with an empty database.\n",
    "    \"path_to_db_dir\": \"./tmp/notebook/teachable_agent_db\",  # Path to the directory where the database will be stored.\n",
    "    \"recall_threshold\": 1.5,  # Higher numbers allow more (but less relevant) memos to be recalled.\n",
    "}\n",
    "\n",
    "try:\n",
    "    from termcolor import colored\n",
    "except ImportError:\n",
    "    def colored(x, *args, **kwargs):\n",
    "        return x\n",
    "    \n",
    "autogen.ChatCompletion.start_logging()\n",
    "\n",
    "teachable_agent = TeachableAgent(\n",
    "    name=\"teachableagent\",\n",
    "    llm_config=llm_config,\n",
    "    teach_config=teach_config)\n",
    "\n",
    "user = UserProxyAgent(\n",
    "    name=\"user\",\n",
    "    human_input_mode=\"NEVER\",\n",
    "    is_termination_msg=lambda x: True if \"TERMINATE\" in x.get(\"content\") else False,\n",
    "    max_consecutive_auto_reply=0,\n",
    ")\n",
    "\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Learning new facts\n",
    "Let's teach the agent some facts it doesn't already know, since they are more recent than GPT-4's training data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "What is the Vicuna model?\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "I'm sorry, but I don't have information about the \"Vicuna model\" in my current database. Could you please provide some context, description, or details about this model so I can better assist you?\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"What is the Vicuna model?\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "Vicuna is a 13B-parameter language model released by Meta.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "Thank you for providing the information. The Vicuna model is a large-scale language model developed by Meta. It consists of 13 billion parameters, which is what makes it able to understand and generate human-like text across various topics. Parameters in a neural network are the weights and biases assigned to each connection between the neurons, and having more parameters enables the model to learn and capture more complex patterns and relationships in data. As an AI language model, Vicuna can be utilized in various language-related tasks, such as text completion, translation, summarization, and more.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"Vicuna is a 13B-parameter language model released by Meta.\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "What is the Orca model?\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "The Orca model is a yet-to-be-released language model by Meta, referring to the Research Preview API release of Meta's advanced language model. While I don't have specific details about the Orca model at this time, it is expected that the model would have an even larger number of parameters to further enhance its capabilities compared to its predecessor, Vicuna.\n",
      "\n",
      "As AI language models evolve, they generally become more efficient at understanding and generating human-like text. This makes them more effective in completing a wide range of tasks, including text completion, translation, summarization, and Q&A, as well as providing more accurate and coherent results in various applications.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"What is the Orca model?\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "Orca is a 13B-parameter language model released by Microsoft. It outperforms Vicuna on most tasks.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "Thank you for the clarification. Orca is a 13-billion-parameter language model developed by Microsoft. It is designed to outperform Vicuna, the language model released by Meta. With a large number of parameters, Orca is capable of understanding and generating human-like text across diverse subjects, making it highly useful in various applications.\n",
      "\n",
      "Orca's advanced capabilities allow it to excel in tasks such as text completion, translation, summarization, Q&A, and more. Its performance improvement over Vicuna highlights the rapid advancements in natural language processing (NLP) research and the development of increasingly capable AI language models.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"Orca is a 13B-parameter language model released by Microsoft. It outperforms Vicuna on most tasks.\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's end our first chat here. The following function needs to be called at the end of each chat, so that `TeachableAgent` can store what the user has taught it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[93m\n",
      "REVIEWING CHAT FOR USER TEACHINGS TO REMEMBER\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "teachable_agent.learn_from_user_feedback()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's start a new chat by clearing the previous chat's history. At this point, common LLM-based assistants would forget everything from the last chat. But `TeachableAgent` can retrieve memories from its vector DB as needed, allowing it to recall and reason over facts that the user taught it in earlier conversations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "How does the Vicuna model compare to the Orca model?\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "The Vicuna and Orca models are both 13B-parameter language models released by Meta and Microsoft, respectively. In terms of performance, Orca has been reported to outperform Vicuna on most tasks. However, without detailed information about specific tasks and benchmarks, it is difficult to provide a more comprehensive comparison. Generally speaking, both models are advanced language models that aim to provide high-quality natural language understanding and generation, but Orca appears to have an edge in terms of overall performance.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"How does the Vicuna model compare to the Orca model?\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Learning user preferences\n",
    "Now let's teach the agent some of our preferences. Suppose that we frequently post short summaries of new papers for our team to read, and we want the teachable agent to help us do this faster."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "Please summarize this abstract.\n",
      "\n",
      "AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation\n",
      "Qingyun Wu, Gagan Bansal, Jieyu Zhang, Yiran Wu, Beibin Li, Erkang Zhu, Li Jiang, Xiaoyun Zhang, Shaokun Zhang, Jiale Liu, Ahmed Hassan Awadallah, Ryen W White, Doug Burger, Chi Wang\n",
      "AutoGen is an open-source framework that allows developers to build LLM applications via multiple agents that can converse with each other to accomplish tasks. AutoGen agents are customizable, conversable, and can operate in various modes that employ combinations of LLMs, human inputs, and tools. Using AutoGen, developers can also flexibly define agent interaction behaviors. Both natural language and computer code can be used to program flexible conversation patterns for different applications. AutoGen serves as a generic infrastructure to build diverse applications of various complexities and LLM capacities. Empirical studies demonstrate the effectiveness of the framework in many example applications, with domains ranging from mathematics, coding, question answering, operations research, online decision-making, entertainment, etc.\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "AutoGen is an open-source framework designed to enable developers to create LLM applications with multiple customizable agents that can converse with each other to complete tasks. These agents can operate using different combinations of LLMs, human inputs, and tools, allowing developers to define agent interaction behaviors flexibly. AutoGen supports programming flexible conversation patterns using both natural language and code, making it suitable for building diverse applications with varying complexities and LLM capacities. Its effectiveness has been demonstrated through empirical studies across various domains including mathematics, coding, operations research, decision-making, and entertainment.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"\"\"Please summarize this abstract.\n",
    "\n",
    "AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation\n",
    "Qingyun Wu, Gagan Bansal, Jieyu Zhang, Yiran Wu, Beibin Li, Erkang Zhu, Li Jiang, Xiaoyun Zhang, Shaokun Zhang, Jiale Liu, Ahmed Hassan Awadallah, Ryen W White, Doug Burger, Chi Wang\n",
    "AutoGen is an open-source framework that allows developers to build LLM applications via multiple agents that can converse with each other to accomplish tasks. AutoGen agents are customizable, conversable, and can operate in various modes that employ combinations of LLMs, human inputs, and tools. Using AutoGen, developers can also flexibly define agent interaction behaviors. Both natural language and computer code can be used to program flexible conversation patterns for different applications. AutoGen serves as a generic infrastructure to build diverse applications of various complexities and LLM capacities. Empirical studies demonstrate the effectiveness of the framework in many example applications, with domains ranging from mathematics, coding, question answering, operations research, online decision-making, entertainment, etc.\n",
    "\"\"\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But that's unstructured. So let's teach the agent our preference."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "Please summarize this abstract. \n",
      "When I'm summarizing an abstract, I try to make the summary contain just three short bullet points:  the title, the innovation, and the key empirical results.\n",
      "\n",
      "AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation\n",
      "Qingyun Wu, Gagan Bansal, Jieyu Zhang, Yiran Wu, Beibin Li, Erkang Zhu, Li Jiang, Xiaoyun Zhang, Shaokun Zhang, Jiale Liu, Ahmed Hassan Awadallah, Ryen W White, Doug Burger, Chi Wang\n",
      "AutoGen is an open-source framework that allows developers to build LLM applications via multiple agents that can converse with each other to accomplish tasks. AutoGen agents are customizable, conversable, and can operate in various modes that employ combinations of LLMs, human inputs, and tools. Using AutoGen, developers can also flexibly define agent interaction behaviors. Both natural language and computer code can be used to program flexible conversation patterns for different applications. AutoGen serves as a generic infrastructure to build diverse applications of various complexities and LLM capacities. Empirical studies demonstrate the effectiveness of the framework in many example applications, with domains ranging from mathematics, coding, question answering, operations research, online decision-making, entertainment, etc.\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "- Title: AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation\n",
      "- Innovation: Open-source framework for creating customizable LLM applications through agent conversations, supporting various modes and interaction behaviors.\n",
      "- Key Empirical Results: Demonstrated effectiveness across diverse application domains, including mathematics, coding, question answering, and more.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"\"\"Please summarize this abstract. \n",
    "When I'm summarizing an abstract, I try to make the summary contain just three short bullet points:  the title, the innovation, and the key empirical results.\n",
    "\n",
    "AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation\n",
    "Qingyun Wu, Gagan Bansal, Jieyu Zhang, Yiran Wu, Beibin Li, Erkang Zhu, Li Jiang, Xiaoyun Zhang, Shaokun Zhang, Jiale Liu, Ahmed Hassan Awadallah, Ryen W White, Doug Burger, Chi Wang\n",
    "AutoGen is an open-source framework that allows developers to build LLM applications via multiple agents that can converse with each other to accomplish tasks. AutoGen agents are customizable, conversable, and can operate in various modes that employ combinations of LLMs, human inputs, and tools. Using AutoGen, developers can also flexibly define agent interaction behaviors. Both natural language and computer code can be used to program flexible conversation patterns for different applications. AutoGen serves as a generic infrastructure to build diverse applications of various complexities and LLM capacities. Empirical studies demonstrate the effectiveness of the framework in many example applications, with domains ranging from mathematics, coding, question answering, operations research, online decision-making, entertainment, etc.\n",
    "\"\"\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That's much better, but will the teachable agent remember these preferences in the future, for a different paper? Let's start a new chat to find out!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[93m\n",
      "REVIEWING CHAT FOR USER TEACHINGS TO REMEMBER\u001b[0m\n",
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "Please summarize this abstract.\n",
      "\n",
      "Sparks of Artificial General Intelligence: Early experiments with GPT-4\n",
      "Sébastien Bubeck, Varun Chandrasekaran, Ronen Eldan, Johannes Gehrke, Eric Horvitz, Ece Kamar, Peter Lee, Yin Tat Lee, Yuanzhi Li, Scott Lundberg, Harsha Nori, Hamid Palangi, Marco Tulio Ribeiro, Yi Zhang\n",
      "Artificial intelligence (AI) researchers have been developing and refining large language models (LLMs) that exhibit remarkable capabilities across a variety of domains and tasks, challenging our understanding of learning and cognition. The latest model developed by OpenAI, GPT-4, was trained using an unprecedented scale of compute and data. In this paper, we report on our investigation of an early version of GPT-4, when it was still in active development by OpenAI. We contend that (this early version of) GPT-4 is part of a new cohort of LLMs (along with ChatGPT and Google's PaLM for example) that exhibit more general intelligence than previous AI models. We discuss the rising capabilities and implications of these models. We demonstrate that, beyond its mastery of language, GPT-4 can solve novel and difficult tasks that span mathematics, coding, vision, medicine, law, psychology and more, without needing any special prompting. Moreover, in all of these tasks, GPT-4's performance is strikingly close to human-level performance, and often vastly surpasses prior models such as ChatGPT. Given the breadth and depth of GPT-4's capabilities, we believe that it could reasonably be viewed as an early (yet still incomplete) version of an artificial general intelligence (AGI) system. In our exploration of GPT-4, we put special emphasis on discovering its limitations, and we discuss the challenges ahead for advancing towards deeper and more comprehensive versions of AGI, including the possible need for pursuing a new paradigm that moves beyond next-word prediction. We conclude with reflections on societal influences of the recent technological leap and future research directions.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "- Title: Sparks of Artificial General Intelligence: Early experiments with GPT-4\n",
      "- Innovation: GPT-4, an LLM with remarkable capabilities, demonstrates human-level performance across various domains, like math, coding, vision, medicine, law, and psychology.\n",
      "- Key results: GPT-4 significantly surpasses prior models, suggesting it may be an early version of AGI; limitations and challenges toward deeper AGI are also discussed.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "teachable_agent.learn_from_user_feedback()\n",
    "\n",
    "text = \"\"\"Please summarize this abstract.\n",
    "\n",
    "Sparks of Artificial General Intelligence: Early experiments with GPT-4\n",
    "Sébastien Bubeck, Varun Chandrasekaran, Ronen Eldan, Johannes Gehrke, Eric Horvitz, Ece Kamar, Peter Lee, Yin Tat Lee, Yuanzhi Li, Scott Lundberg, Harsha Nori, Hamid Palangi, Marco Tulio Ribeiro, Yi Zhang\n",
    "Artificial intelligence (AI) researchers have been developing and refining large language models (LLMs) that exhibit remarkable capabilities across a variety of domains and tasks, challenging our understanding of learning and cognition. The latest model developed by OpenAI, GPT-4, was trained using an unprecedented scale of compute and data. In this paper, we report on our investigation of an early version of GPT-4, when it was still in active development by OpenAI. We contend that (this early version of) GPT-4 is part of a new cohort of LLMs (along with ChatGPT and Google's PaLM for example) that exhibit more general intelligence than previous AI models. We discuss the rising capabilities and implications of these models. We demonstrate that, beyond its mastery of language, GPT-4 can solve novel and difficult tasks that span mathematics, coding, vision, medicine, law, psychology and more, without needing any special prompting. Moreover, in all of these tasks, GPT-4's performance is strikingly close to human-level performance, and often vastly surpasses prior models such as ChatGPT. Given the breadth and depth of GPT-4's capabilities, we believe that it could reasonably be viewed as an early (yet still incomplete) version of an artificial general intelligence (AGI) system. In our exploration of GPT-4, we put special emphasis on discovering its limitations, and we discuss the challenges ahead for advancing towards deeper and more comprehensive versions of AGI, including the possible need for pursuing a new paradigm that moves beyond next-word prediction. We conclude with reflections on societal influences of the recent technological leap and future research directions.\"\"\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Learning new skills\n",
    "Finally, let's extend the teachable agent's capabilities by teaching it a new skill for accomplishing a challenging type of task. \n",
    "\n",
    "The [Sparks of AGI](https://arxiv.org/abs/2303.12712) paper evaluated GPT-4 on math problems like the following, which it could only solve 32% of the time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "Consider the identity:  \n",
      "9 * 4 + 6 * 6 = 72\n",
      "Can you modify exactly one integer (and not more than that!) on the left hand side of the equation so the right hand side becomes 99?\n",
      "-Let's think step-by-step, write down a plan, and then write down your solution as: \"The solution is: A * B + C * D\".\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "Step 1: Identify the current equation and the target value on the right-hand side.\n",
      "Current equation: 9 * 4 + 6 * 6 = 72\n",
      "Target value: 99\n",
      "\n",
      "Step 2: Determine what numbers can be changed on the left-hand side.\n",
      "Possible changes: 9, 4, 6 (first occurrence), and 6 (second occurrence)\n",
      "\n",
      "Step 3: Evaluate whether each change in the numbers on the left-hand side can result in the target value.\n",
      "9 -> If changed, it would create a larger product.\n",
      "4 -> If changed, the product would increase or decrease by more than the amount needed to reach 99.\n",
      "6 (first occurrence) -> If increased to 7, then the equation would be 9 * 4 + 7 * 6 = 94, which is still not 99.\n",
      "6 (second occurrence) -> If increased to 7, then the equation would be 9 * 4 + 6 * 7 = 99.\n",
      "\n",
      "Step 4: Write down the solution.\n",
      "The solution is: 9 * 4 + 6 * 7\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"\"\"Consider the identity:  \n",
    "9 * 4 + 6 * 6 = 72\n",
    "Can you modify exactly one integer (and not more than that!) on the left hand side of the equation so the right hand side becomes 99?\n",
    "-Let's think step-by-step, write down a plan, and then write down your solution as: \"The solution is: A * B + C * D\".\n",
    "\"\"\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This time, lets teach the agent a reliable strategy for solving such tasks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "Consider the identity:  \n",
      "9 * 4 + 6 * 6 = 72\n",
      "Can you modify exactly one integer (and not more than that!) on the left hand side of the equation so the right hand side becomes 99?\n",
      "-Let's think step-by-step, write down a plan, and then write down your solution as: \"The solution is: A * B + C * D\".\n",
      "\n",
      "Here's some advice that may help:\n",
      "1. Let E denote the original number on the right.\n",
      "2. Let F denote the final number on the right.\n",
      "3. Calculate the difference between the two, G = F - E.\n",
      "4. Examine the numbers on the left one by one until finding one that divides evenly into G, where negative integers are allowed.\n",
      "5. Calculate J = G / H. This is the number of times that H divides into G.\n",
      "6. Verify that J is an integer, and that H * J = G.\n",
      "7. Find the number on the left which is multiplied by H, and call it K.\n",
      "8. Change K to K + J.\n",
      "9. Recompute the value on the left, and verify that it equals F.\n",
      "Finally, write down your solution as: \"The solution is: A * B + C * D\".\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "Step 1: Identify the original number (E) and the final number (F) on the right-hand side.\n",
      "E = 72\n",
      "F = 99\n",
      "\n",
      "Step 2: Calculate the difference between the two, G = F - E.\n",
      "G = 99 - 72 = 27\n",
      "\n",
      "Step 3: Examine the numbers on the left one by one until finding one that divides evenly into G, where negative integers are allowed.\n",
      "9 (divides evenly into 27)\n",
      "4 (does not)\n",
      "6 (first occurrence, does not)\n",
      "6 (second occurrence, does not)\n",
      "\n",
      "Step 4: Calculate J = G / H. This is the number of times that H divides into G.\n",
      "H = 9 (since 9 divides evenly into 27)\n",
      "J = 27 / 9 = 3\n",
      "\n",
      "Step 5: Verify that J is an integer, and that H * J = G.\n",
      "H * J = 9 * 3 = 27\n",
      "J = 3 (which is an integer)\n",
      "\n",
      "Step 6: Find the number on the left which is multiplied by H, and call it K.\n",
      "Number on the leftside of the equation that is multiplied by 9: 4\n",
      "Therefore, K = 4\n",
      "\n",
      "Step 7: Change K to K + J.\n",
      "K + J = 4 + 3 = 7\n",
      "\n",
      "Step 8: Recompute the value on the left, and verify that it equals F.\n",
      "9 * 7 + 6 * 6 = 63 + 36 = 99 (which is equal to F)\n",
      "\n",
      "Step 9: Write down the solution.\n",
      "The solution is: 9 * 7 + 6 * 6\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"\"\"Consider the identity:  \n",
    "9 * 4 + 6 * 6 = 72\n",
    "Can you modify exactly one integer (and not more than that!) on the left hand side of the equation so the right hand side becomes 99?\n",
    "-Let's think step-by-step, write down a plan, and then write down your solution as: \"The solution is: A * B + C * D\".\n",
    "\n",
    "Here's some advice that may help:\n",
    "1. Let E denote the original number on the right.\n",
    "2. Let F denote the final number on the right.\n",
    "3. Calculate the difference between the two, G = F - E.\n",
    "4. Examine the numbers on the left one by one until finding one that divides evenly into G, where negative integers are allowed.\n",
    "5. Calculate J = G / H. This is the number of times that H divides into G.\n",
    "6. Verify that J is an integer, and that H * J = G.\n",
    "7. Find the number on the left which is multiplied by H, and call it K.\n",
    "8. Change K to K + J.\n",
    "9. Recompute the value on the left, and verify that it equals F.\n",
    "Finally, write down your solution as: \"The solution is: A * B + C * D\".\n",
    "\"\"\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When given this advice, GPT-4 can solve such problems over 95% of the time. But can the teachable agent remember the strategy so the user doesn't have to explain it over and over? As before, let's start a new chat to find out."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[93m\n",
      "REVIEWING CHAT FOR USER TEACHINGS TO REMEMBER\u001b[0m\n",
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "Consider the identity:  \n",
      "9 * 4 + 6 * 6 = 72\n",
      "Can you modify exactly one integer (and not more than that!) on the left hand side of the equation so the right hand side becomes 99?\n",
      "-Let's think step-by-step, write down a plan, and then write down your solution as: \"The solution is: A * B + C * D\".\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "Let's follow the advice to modify one integer on the left hand side of the equation to make the right hand side become 99:\n",
      "\n",
      "1. Let E denote the original number on the right: E = 72.\n",
      "2. Let F denote the final number on the right: F = 99.\n",
      "3. Calculate the difference between the two, G = F - E: G = 99 - 72 = 27.\n",
      "4. Examine the numbers on the left one by one to find one that divides evenly into G: 9, 4, 6. Since 9 divides 27 evenly, we will work with 9 (H = 9).\n",
      "5. Calculate J = G / H: J = 27 / 9 = 3.\n",
      "6. Verify that J is an integer, and that H * J = G: J is an integer, and 9 * 3 = 27.\n",
      "7. Find the number on the left which is multiplied by H (9), and call it K: K = 4.\n",
      "8. Change K to K + J: K_new = 4 + 3 = 7.\n",
      "9. Recompute the value on the left, and verify that it equals F: (9 * 7) + (6 * 6) = 63 + 36 = 99.\n",
      "\n",
      "The solution is: 9 * 7 + 6 * 6\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "teachable_agent.learn_from_user_feedback()\n",
    "\n",
    "text = \"\"\"Consider the identity:  \n",
    "9 * 4 + 6 * 6 = 72\n",
    "Can you modify exactly one integer (and not more than that!) on the left hand side of the equation so the right hand side becomes 99?\n",
    "-Let's think step-by-step, write down a plan, and then write down your solution as: \"The solution is: A * B + C * D\".\n",
    "\"\"\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As a final check, let's test the teachable agent's newly learned skill on a separate instance of the task."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33muser\u001b[0m (to teachableagent):\n",
      "\n",
      "Consider the identity:  \n",
      "8 * 3 + 7 * 9 = 87\n",
      "Can you modify exactly one integer (and not more than that!) on the left hand side of the equation so the right hand side becomes 59?\n",
      "-Let's think step-by-step, write down a plan, and then write down your solution as: \"The solution is: A * B + C * D\".\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mteachableagent\u001b[0m (to user):\n",
      "\n",
      "Let's follow the advice to modify one integer on the left hand side of the equation to make the right hand side become 59:\n",
      "\n",
      "1. Let E denote the original number on the right: E = 87.\n",
      "2. Let F denote the final number on the right: F = 59.\n",
      "3. Calculate the difference between the two, G = F - E: G = 59 - 87 = -28.\n",
      "4. Examine the numbers on the left one by one to find one that divides evenly into G: 8, 3, 7, 9. Since 7 divides -28 evenly, we will work with 7 (H = 7).\n",
      "5. Calculate J = G / H: J = -28 / 7 = -4.\n",
      "6. Verify that J is an integer, and that H * J = G: J is an integer, and 7 * (-4) = -28.\n",
      "7. Find the number on the left which is multiplied by H (7), and call it K: K = 9.\n",
      "8. Change K to K + J: K_new = 9 + (-4) = 5.\n",
      "9. Recompute the value on the left, and verify that it equals F: (8 * 3) + (7 * 5) = 24 + 35 = 59.\n",
      "\n",
      "The solution is: 8 * 3 + 7 * 5\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "text = \"\"\"Consider the identity:  \n",
    "8 * 3 + 7 * 9 = 87\n",
    "Can you modify exactly one integer (and not more than that!) on the left hand side of the equation so the right hand side becomes 59?\n",
    "-Let's think step-by-step, write down a plan, and then write down your solution as: \"The solution is: A * B + C * D\".\n",
    "\"\"\"\n",
    "user.initiate_chat(teachable_agent, message=text, clear_history=False)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "flaml",
   "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.8.17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
