{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "613b5312",
   "metadata": {},
   "source": [
    "# Aim\n",
    "\n",
    "Aim makes it super easy to visualize and debug LangChain executions. Aim tracks inputs and outputs of LLMs and tools, as well as actions of agents. \n",
    "\n",
    "With Aim, you can easily debug and examine an individual execution:\n",
    "\n",
    "![](https://user-images.githubusercontent.com/13848158/227784778-06b806c7-74a1-4d15-ab85-9ece09b458aa.png)\n",
    "\n",
    "Additionally, you have the option to compare multiple executions side by side:\n",
    "\n",
    "![](https://user-images.githubusercontent.com/13848158/227784994-699b24b7-e69b-48f9-9ffa-e6a6142fd719.png)\n",
    "\n",
    "Aim is fully open source, [learn more](https://github.com/aimhubio/aim) about Aim on GitHub.\n",
    "\n",
    "Let's move forward and see how to enable and configure Aim callback."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3615f1e2",
   "metadata": {},
   "source": [
    "<h3>Tracking LangChain Executions with Aim</h3>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5d271566",
   "metadata": {},
   "source": [
    "In this notebook we will explore three usage scenarios. To start off, we will install the necessary packages and import certain modules. Subsequently, we will configure two environment variables that can be established either within the Python script or through the terminal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d16e00da",
   "metadata": {
    "id": "mf88kuCJhbVu"
   },
   "outputs": [],
   "source": [
    "!pip install aim\n",
    "!pip install langchain\n",
    "!pip install openai\n",
    "!pip install google-search-results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c970cda9",
   "metadata": {
    "id": "g4eTuajwfl6L"
   },
   "outputs": [],
   "source": [
    "import os\n",
    "from datetime import datetime\n",
    "\n",
    "from langchain.callbacks import AimCallbackHandler, StdOutCallbackHandler\n",
    "from langchain.llms import OpenAI"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "426ecf0d",
   "metadata": {},
   "source": [
    "Our examples use a GPT model as the LLM, and OpenAI offers an API for this purpose. You can obtain the key from the following link: https://platform.openai.com/account/api-keys .\n",
    "\n",
    "We will use the SerpApi to retrieve search results from Google. To acquire the SerpApi key, please go to https://serpapi.com/manage-api-key ."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b2b1cfc2",
   "metadata": {
    "id": "T1bSmKd6V2If"
   },
   "outputs": [],
   "source": [
    "os.environ[\"OPENAI_API_KEY\"] = \"...\"\n",
    "os.environ[\"SERPAPI_API_KEY\"] = \"...\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "53070869",
   "metadata": {
    "id": "QenUYuBZjIzc"
   },
   "source": [
    "The event methods of `AimCallbackHandler` accept the LangChain module or agent as input and log at least the prompts and generated results, as well as the serialized version of the LangChain module, to the designated Aim run."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a30e90d",
   "metadata": {
    "id": "KAz8weWuUeXF"
   },
   "outputs": [],
   "source": [
    "session_group = datetime.now().strftime(\"%m.%d.%Y_%H.%M.%S\")\n",
    "aim_callback = AimCallbackHandler(\n",
    "    repo=\".\",\n",
    "    experiment_name=\"scenario 1: OpenAI LLM\",\n",
    ")\n",
    "\n",
    "callbacks = [StdOutCallbackHandler(), aim_callback]\n",
    "llm = OpenAI(temperature=0, callbacks=callbacks)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f591582",
   "metadata": {
    "id": "b8WfByB4fl6N"
   },
   "source": [
    "The `flush_tracker` function is used to record LangChain assets on Aim. By default, the session is reset rather than being terminated outright."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8a425743",
   "metadata": {},
   "source": [
    "<h3>Scenario 1</h3> In the first scenario, we will use OpenAI LLM."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "795cda48",
   "metadata": {
    "id": "o_VmneyIUyx8"
   },
   "outputs": [],
   "source": [
    "# scenario 1 - LLM\n",
    "llm_result = llm.generate([\"Tell me a joke\", \"Tell me a poem\"] * 3)\n",
    "aim_callback.flush_tracker(\n",
    "    langchain_asset=llm,\n",
    "    experiment_name=\"scenario 2: Chain with multiple SubChains on multiple generations\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7374776f",
   "metadata": {},
   "source": [
    "<h3>Scenario 2</h3> Scenario two involves chaining with multiple SubChains across multiple generations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f946249a",
   "metadata": {
    "id": "trxslyb1U28Y"
   },
   "outputs": [],
   "source": [
    "from langchain.chains import LLMChain\n",
    "from langchain.prompts import PromptTemplate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1012e817",
   "metadata": {
    "id": "uauQk10SUzF6"
   },
   "outputs": [],
   "source": [
    "# scenario 2 - Chain\n",
    "template = \"\"\"You are a playwright. Given the title of play, it is your job to write a synopsis for that title.\n",
    "Title: {title}\n",
    "Playwright: This is a synopsis for the above play:\"\"\"\n",
    "prompt_template = PromptTemplate(input_variables=[\"title\"], template=template)\n",
    "synopsis_chain = LLMChain(llm=llm, prompt=prompt_template, callbacks=callbacks)\n",
    "\n",
    "test_prompts = [\n",
    "    {\n",
    "        \"title\": \"documentary about good video games that push the boundary of game design\"\n",
    "    },\n",
    "    {\"title\": \"the phenomenon behind the remarkable speed of cheetahs\"},\n",
    "    {\"title\": \"the best in class mlops tooling\"},\n",
    "]\n",
    "synopsis_chain.apply(test_prompts)\n",
    "aim_callback.flush_tracker(\n",
    "    langchain_asset=synopsis_chain, experiment_name=\"scenario 3: Agent with Tools\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f18e2d10",
   "metadata": {},
   "source": [
    "<h3>Scenario 3</h3> The third scenario involves an agent with tools."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9de08db4",
   "metadata": {
    "id": "_jN73xcPVEpI"
   },
   "outputs": [],
   "source": [
    "from langchain.agents import AgentType, initialize_agent, load_tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0992df94",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "Gpq4rk6VT9cu",
    "outputId": "68ae261e-d0a2-4229-83c4-762562263b66"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m I need to find out who Leo DiCaprio's girlfriend is and then calculate her age raised to the 0.43 power.\n",
      "Action: Search\n",
      "Action Input: \"Leo DiCaprio girlfriend\"\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3mLeonardo DiCaprio seemed to prove a long-held theory about his love life right after splitting from girlfriend Camila Morrone just months ...\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m I need to find out Camila Morrone's age\n",
      "Action: Search\n",
      "Action Input: \"Camila Morrone age\"\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m25 years\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m I need to calculate 25 raised to the 0.43 power\n",
      "Action: Calculator\n",
      "Action Input: 25^0.43\u001b[0m\n",
      "Observation: \u001b[33;1m\u001b[1;3mAnswer: 3.991298452658078\n",
      "\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n",
      "Final Answer: Camila Morrone is Leo DiCaprio's girlfriend and her current age raised to the 0.43 power is 3.991298452658078.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "# scenario 3 - Agent with Tools\n",
    "tools = load_tools([\"serpapi\", \"llm-math\"], llm=llm, callbacks=callbacks)\n",
    "agent = initialize_agent(\n",
    "    tools,\n",
    "    llm,\n",
    "    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,\n",
    "    callbacks=callbacks,\n",
    ")\n",
    "agent.run(\n",
    "    \"Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?\"\n",
    ")\n",
    "aim_callback.flush_tracker(langchain_asset=agent, reset=False, finish=True)"
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "provenance": []
  },
  "gpuClass": "standard",
  "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.9.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}