diff --git a/lab-chains-in-langchain.ipynb b/lab-chains-in-langchain.ipynb index 290f3bb..d7d10dd 100644 --- a/lab-chains-in-langchain.ipynb +++ b/lab-chains-in-langchain.ipynb @@ -1,728 +1,1629 @@ { - "cells": [ - { - "cell_type": "markdown", - "id": "52824b89-532a-4e54-87e9-1410813cd39e", - "metadata": {}, - "source": [ - "# Lab | Chains in LangChain\n", - "\n", - "## Outline\n", - "\n", - "* LLMChain\n", - "* Sequential Chains\n", - " * SimpleSequentialChain\n", - " * SequentialChain\n", - "* Router Chain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "541eb2f1", - "metadata": {}, - "outputs": [], - "source": [ - "import warnings\n", - "warnings.filterwarnings('ignore')" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "b7ed03ed-1322-49e3-b2a2-33e94fb592ef", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "from dotenv import load_dotenv, find_dotenv\n", - "_ = load_dotenv(find_dotenv())\n", - "\n", - "OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')\n", - "HUGGINGFACEHUB_API_TOKEN = os.getenv('HUGGINGFACEHUB_API_TOKEN')" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "b84e441b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "#!pip install pandas" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import pandas as pd\n", - "df = pd.read_csv('./lab/data/Data.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "b7a09c35", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ProductReview
0Queen Size Sheet SetI ordered a king size set. My only criticism w...
1Waterproof Phone PouchI loved the waterproof sac, although the openi...
2Luxury Air MattressThis mattress had a small hole in the top of i...
3Pillows InsertThis is the best throw pillow fillers on Amazo...
4Milk Frother Handheld\\nI loved this product. But they only seem to l...
\n", - "
" + "cells": [ + { + "cell_type": "markdown", + "id": "52824b89-532a-4e54-87e9-1410813cd39e", + "metadata": { + "id": "52824b89-532a-4e54-87e9-1410813cd39e" + }, + "source": [ + "# Lab | Chains in LangChain\n", + "\n", + "## Outline\n", + "\n", + "* LLMChain\n", + "* Sequential Chains\n", + " * SimpleSequentialChain\n", + " * SequentialChain\n", + "* Router Chain" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "541eb2f1", + "metadata": { + "id": "541eb2f1" + }, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b7ed03ed-1322-49e3-b2a2-33e94fb592ef", + "metadata": { + "tags": [], + "id": "b7ed03ed-1322-49e3-b2a2-33e94fb592ef" + }, + "outputs": [], + "source": [ + "import os\n", + "\n", + "from dotenv import load_dotenv, find_dotenv\n", + "_ = load_dotenv(find_dotenv())\n", + "\n", + "OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')\n", + "HUGGINGFACEHUB_API_TOKEN = os.getenv('HUGGINGFACEHUB_API_TOKEN')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "b84e441b", + "metadata": { + "tags": [], + "id": "b84e441b" + }, + "outputs": [], + "source": [ + "#!pip install pandas" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", + "metadata": { + "tags": [], + "colab": { + "base_uri": "https://localhost:8080/", + "height": 73 + }, + "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", + "outputId": "77a70b98-7a71-4ae0-9860-ee46cf276220" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "\n", + " \n", + " \n", + " Upload widget is only available when the cell has been executed in the\n", + " current browser session. Please rerun this cell to enable.\n", + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Saving Data.csv to Data.csv\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "# df = pd.read_csv('./lab/data/Data.csv')\n", + "\n", + "from google.colab import files\n", + "uploaded = files.upload()\n", + "\n", + "df = pd.read_csv(\"Data.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "b7a09c35", + "metadata": { + "tags": [], + "colab": { + "base_uri": "https://localhost:8080/", + "height": 268 + }, + "id": "b7a09c35", + "outputId": "04a704cb-4062-4e19-db13-a0aee3a1c5da" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + " Product \\\n", + "0 Queen Size Sheet Set \n", + "1 Waterproof Phone Pouch \n", + "2 Luxury Air Mattress \n", + "3 Pillows Insert \n", + "4 Milk Frother Handheld\\r\\n \n", + "5 L'Or Espresso Café \\r\\n \n", + "6 Hervidor de Agua Eléctrico \n", + "\n", + " Review \n", + "0 I ordered a king size set. My only criticism w... \n", + "1 I loved the waterproof sac, although the openi... \n", + "2 This mattress had a small hole in the top of i... \n", + "3 This is the best throw pillow fillers on Amazo... \n", + "4  I loved this product. But they only seem to l... \n", + "5 Je trouve le goût médiocre. La mousse ne tient... \n", + "6 Está lu bonita calienta muy rápido, es muy fun... " + ], + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ProductReview
0Queen Size Sheet SetI ordered a king size set. My only criticism w...
1Waterproof Phone PouchI loved the waterproof sac, although the openi...
2Luxury Air MattressThis mattress had a small hole in the top of i...
3Pillows InsertThis is the best throw pillow fillers on Amazo...
4Milk Frother Handheld\\r\\nI loved this product. But they only seem to l...
5L'Or Espresso Café \\r\\nJe trouve le goût médiocre. La mousse ne tient...
6Hervidor de Agua EléctricoEstá lu bonita calienta muy rápido, es muy fun...
\n", + "
\n", + "
\n", + "\n", + "
\n", + " \n", + "\n", + " \n", + "\n", + " \n", + "
\n", + "\n", + "\n", + "
\n", + "
\n" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "dataframe", + "variable_name": "df", + "summary": "{\n \"name\": \"df\",\n \"rows\": 7,\n \"fields\": [\n {\n \"column\": \"Product\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 7,\n \"samples\": [\n \"Queen Size Sheet Set\",\n \"Waterproof Phone Pouch\",\n \"L'Or Espresso Caf\\u00e9\\u00a0\\r\\n\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Review\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 7,\n \"samples\": [\n \"I ordered a king size set. My only criticism would be that I wish seller would offer the king size set with 4 pillowcases. I separately ordered a two pack of pillowcases so I could have a total of four. When I saw the two packages, it looked like the color did not exactly match. Customer service was excellent about sending me two more pillowcases so I would have four that matched. Excellent! For the cost of these sheets, I am satisfied with the characteristics and coolness of the sheets.\",\n \"I loved the waterproof sac, although the opening was made of a hard plastic. I don\\u2019t know if that would break easily. But I couldn\\u2019t turn my phone on, once it was in the pouch.\",\n \"Je trouve le go\\u00fbt m\\u00e9diocre. La mousse ne tient pas, c'est bizarre. J'ach\\u00e8te les m\\u00eames dans le commerce et le go\\u00fbt est bien meilleur...\\r\\nVieux lot ou contrefa\\u00e7on !?\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" + } + }, + "metadata": {}, + "execution_count": 22 + } + ], + "source": [ + "df.head(10)" + ] + }, + { + "cell_type": "markdown", + "id": "b940ce7c", + "metadata": { + "id": "b940ce7c" + }, + "source": [ + "## LLMChain" + ] + }, + { + "cell_type": "code", + "source": [ + "!pip install -q \\\n", + " \"langchain==0.2.17\" \\\n", + " \"langchain-core<0.3\" \\\n", + " \"langchain-community<0.3\" \\\n", + " \"langchain-openai<0.2\"" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "e3QGpN_nusfM", + "outputId": "9db3865d-b3aa-4acf-fbfb-777bfb2707a2" + }, + "id": "e3QGpN_nusfM", + "execution_count": 6, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m61.0/61.0 kB\u001b[0m \u001b[31m3.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m30.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m397.1/397.1 kB\u001b[0m \u001b[31m36.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.3/2.3 MB\u001b[0m \u001b[31m60.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m51.5/51.5 kB\u001b[0m \u001b[31m2.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m311.8/311.8 kB\u001b[0m \u001b[31m15.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m18.0/18.0 MB\u001b[0m \u001b[31m60.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m948.6/948.6 kB\u001b[0m \u001b[31m54.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m65.5/65.5 kB\u001b[0m \u001b[31m6.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m51.0/51.0 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", + "cupy-cuda12x 14.0.1 requires numpy<2.6,>=2.0, but you have numpy 1.26.4 which is incompatible.\n", + "google-adk 2.4.0 requires tenacity<10,>=9, but you have tenacity 8.5.0 which is incompatible.\n", + "xarray-einstats 0.10.0 requires numpy>=2.0, but you have numpy 1.26.4 which is incompatible.\n", + "langgraph-sdk 0.4.2 requires langchain-core<2,>=1.4.0, but you have langchain-core 0.2.43 which is incompatible.\n", + "pytensor 2.38.3 requires numpy>=2.0, but you have numpy 1.26.4 which is incompatible.\n", + "langgraph-prebuilt 1.1.0 requires langchain-core>=1.3.1, but you have langchain-core 0.2.43 which is incompatible.\n", + "opencv-python-headless 5.0.0.93 requires numpy>=2; python_version >= \"3.9\", but you have numpy 1.26.4 which is incompatible.\n", + "tifffile 2026.4.11 requires numpy>=2.0, but you have numpy 1.26.4 which is incompatible.\n", + "opencv-python 5.0.0.93 requires numpy>=2; python_version >= \"3.9\", but you have numpy 1.26.4 which is incompatible.\n", + "rasterio 1.5.0 requires numpy>=2, but you have numpy 1.26.4 which is incompatible.\n", + "jax 0.7.2 requires numpy>=2.0, but you have numpy 1.26.4 which is incompatible.\n", + "jaxlib 0.7.2 requires numpy>=2.0, but you have numpy 1.26.4 which is incompatible.\n", + "tobler 0.14.0 requires numpy>=2.0, but you have numpy 1.26.4 which is incompatible.\n", + "opencv-contrib-python 4.13.0.92 requires numpy>=2; python_version >= \"3.9\", but you have numpy 1.26.4 which is incompatible.\n", + "langgraph 1.2.9 requires langchain-core<2,>=1.4.7, but you have langchain-core 0.2.43 which is incompatible.\n", + "shap 0.52.0 requires numpy>=2, but you have numpy 1.26.4 which is incompatible.\u001b[0m\u001b[31m\n", + "\u001b[0m" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "import langchain\n", + "import langchain_core\n", + "import langchain_community\n", + "import langchain_openai\n", + "\n", + "print(langchain.__version__)\n", + "print(langchain_core.__version__)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "UDEP6rk-vu7i", + "outputId": "fb223ae2-d0e1-4492-ec86-4dbacd9a043e" + }, + "id": "UDEP6rk-vu7i", + "execution_count": 7, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "0.2.17\n", + "0.2.43\n" + ] + } + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "427e1119", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "427e1119", + "outputId": "3cd68918-451e-42a1-bd5f-ea7e2f8ab80a" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Collecting langchain_community\n", + " Downloading langchain_community-0.4.2-py3-none-any.whl.metadata (3.4 kB)\n", + "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /usr/local/lib/python3.12/dist-packages (from langchain_community) (3.14.1)\n", + "Collecting httpx-sse<1.0.0,>=0.4.0 (from langchain_community)\n", + " Downloading httpx_sse-0.4.3-py3-none-any.whl.metadata (9.7 kB)\n", + "Collecting langchain-classic<2.0.0,>=1.0.7 (from langchain_community)\n", + " Downloading langchain_classic-1.0.8-py3-none-any.whl.metadata (5.1 kB)\n", + "Requirement already satisfied: langchain-core<2.0.0,>=1.4.0 in /usr/local/lib/python3.12/dist-packages (from langchain_community) (1.4.9)\n", + "Requirement already satisfied: langsmith<1.0.0,>=0.1.125 in /usr/local/lib/python3.12/dist-packages (from langchain_community) (0.10.2)\n", + "Requirement already satisfied: numpy>=1.26.2 in /usr/local/lib/python3.12/dist-packages (from langchain_community) (2.0.2)\n", + "Collecting pydantic-settings<3.0.0,>=2.10.1 (from langchain_community)\n", + " Downloading pydantic_settings-2.14.2-py3-none-any.whl.metadata (3.4 kB)\n", + "Requirement already satisfied: pyyaml<7.0.0,>=5.3.0 in /usr/local/lib/python3.12/dist-packages (from langchain_community) (6.0.3)\n", + "Collecting requests<3.0.0,>=2.32.5 (from langchain_community)\n", + " Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)\n", + "Requirement already satisfied: sqlalchemy<3.0.0,>=1.4.0 in /usr/local/lib/python3.12/dist-packages (from langchain_community) (2.0.51)\n", + "Requirement already satisfied: tenacity!=8.4.0,<10.0.0,>=8.1.0 in /usr/local/lib/python3.12/dist-packages (from langchain_community) (9.1.4)\n", + "Requirement already satisfied: aiohappyeyeballs>=2.5.0 in /usr/local/lib/python3.12/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (2.7.1)\n", + "Requirement already satisfied: aiosignal>=1.4.0 in /usr/local/lib/python3.12/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (1.4.0)\n", + "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.12/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (26.1.0)\n", + "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.12/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (1.8.0)\n", + "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.12/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (6.7.1)\n", + "Requirement already satisfied: propcache>=0.2.0 in /usr/local/lib/python3.12/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (0.5.2)\n", + "Requirement already satisfied: typing_extensions>=4.4 in /usr/local/lib/python3.12/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (4.16.0)\n", + "Requirement already satisfied: yarl<2.0,>=1.17.0 in /usr/local/lib/python3.12/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (1.24.2)\n", + "Collecting langchain-text-splitters<2.0.0,>=1.1.2 (from langchain-classic<2.0.0,>=1.0.7->langchain_community)\n", + " Downloading langchain_text_splitters-1.1.2-py3-none-any.whl.metadata (3.3 kB)\n", + "Requirement already satisfied: pydantic<3.0.0,>=2.7.4 in /usr/local/lib/python3.12/dist-packages (from langchain-classic<2.0.0,>=1.0.7->langchain_community) (2.13.4)\n", + "Requirement already satisfied: jsonpatch<2.0.0,>=1.33.0 in /usr/local/lib/python3.12/dist-packages (from langchain-core<2.0.0,>=1.4.0->langchain_community) (1.33)\n", + "Requirement already satisfied: langchain-protocol>=0.0.17 in /usr/local/lib/python3.12/dist-packages (from langchain-core<2.0.0,>=1.4.0->langchain_community) (0.0.18)\n", + "Requirement already satisfied: packaging>=23.2.0 in /usr/local/lib/python3.12/dist-packages (from langchain-core<2.0.0,>=1.4.0->langchain_community) (26.2)\n", + "Requirement already satisfied: uuid-utils<1.0,>=0.12.0 in /usr/local/lib/python3.12/dist-packages (from langchain-core<2.0.0,>=1.4.0->langchain_community) (0.17.0)\n", + "Requirement already satisfied: anyio>=3.5.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (4.14.2)\n", + "Requirement already satisfied: distro>=1.7.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (1.9.0)\n", + "Requirement already satisfied: httpx<1,>=0.23.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (0.28.1)\n", + "Requirement already satisfied: orjson>=3.9.14 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (3.11.9)\n", + "Requirement already satisfied: requests-toolbelt>=1.0.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (1.0.0)\n", + "Requirement already satisfied: sniffio>=1.1 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (1.3.1)\n", + "Requirement already satisfied: websockets>=15.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (15.0.1)\n", + "Requirement already satisfied: xxhash>=3.0.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (3.8.1)\n", + "Requirement already satisfied: zstandard>=0.23.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (0.25.0)\n", + "Requirement already satisfied: python-dotenv>=0.21.0 in /usr/local/lib/python3.12/dist-packages (from pydantic-settings<3.0.0,>=2.10.1->langchain_community) (1.2.2)\n", + "Requirement already satisfied: typing-inspection>=0.4.0 in /usr/local/lib/python3.12/dist-packages (from pydantic-settings<3.0.0,>=2.10.1->langchain_community) (0.4.2)\n", + "Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.12/dist-packages (from requests<3.0.0,>=2.32.5->langchain_community) (3.4.9)\n", + "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.12/dist-packages (from requests<3.0.0,>=2.32.5->langchain_community) (3.18)\n", + "Requirement already satisfied: urllib3<3,>=1.26 in /usr/local/lib/python3.12/dist-packages (from requests<3.0.0,>=2.32.5->langchain_community) (2.5.0)\n", + "Requirement already satisfied: certifi>=2023.5.7 in /usr/local/lib/python3.12/dist-packages (from requests<3.0.0,>=2.32.5->langchain_community) (2026.6.17)\n", + "Requirement already satisfied: greenlet>=1 in /usr/local/lib/python3.12/dist-packages (from sqlalchemy<3.0.0,>=1.4.0->langchain_community) (3.5.3)\n", + "Requirement already satisfied: httpcore==1.* in /usr/local/lib/python3.12/dist-packages (from httpx<1,>=0.23.0->langsmith<1.0.0,>=0.1.125->langchain_community) (1.0.9)\n", + "Requirement already satisfied: h11>=0.16 in /usr/local/lib/python3.12/dist-packages (from httpcore==1.*->httpx<1,>=0.23.0->langsmith<1.0.0,>=0.1.125->langchain_community) (0.16.0)\n", + "Requirement already satisfied: jsonpointer>=1.9 in /usr/local/lib/python3.12/dist-packages (from jsonpatch<2.0.0,>=1.33.0->langchain-core<2.0.0,>=1.4.0->langchain_community) (3.1.1)\n", + "Requirement already satisfied: annotated-types>=0.6.0 in /usr/local/lib/python3.12/dist-packages (from pydantic<3.0.0,>=2.7.4->langchain-classic<2.0.0,>=1.0.7->langchain_community) (0.7.0)\n", + "Requirement already satisfied: pydantic-core==2.46.4 in /usr/local/lib/python3.12/dist-packages (from pydantic<3.0.0,>=2.7.4->langchain-classic<2.0.0,>=1.0.7->langchain_community) (2.46.4)\n", + "Downloading langchain_community-0.4.2-py3-none-any.whl (2.4 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m29.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading httpx_sse-0.4.3-py3-none-any.whl (9.0 kB)\n", + "Downloading langchain_classic-1.0.8-py3-none-any.whl (1.0 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m47.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading pydantic_settings-2.14.2-py3-none-any.whl (61 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m61.7/61.7 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading requests-2.34.2-py3-none-any.whl (73 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m73.1/73.1 kB\u001b[0m \u001b[31m5.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading langchain_text_splitters-1.1.2-py3-none-any.whl (35 kB)\n", + "Installing collected packages: requests, httpx-sse, pydantic-settings, langchain-text-splitters, langchain-classic, langchain_community\n", + " Attempting uninstall: requests\n", + " Found existing installation: requests 2.32.4\n", + " Uninstalling requests-2.32.4:\n", + " Successfully uninstalled requests-2.32.4\n", + "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", + "google-colab 1.0.0 requires requests==2.32.4, but you have requests 2.34.2 which is incompatible.\u001b[0m\u001b[31m\n", + "\u001b[0mSuccessfully installed httpx-sse-0.4.3 langchain-classic-1.0.8 langchain-text-splitters-1.1.2 langchain_community-0.4.2 pydantic-settings-2.14.2 requests-2.34.2\n" + ] + } + ], + "source": [ + "# !pip install langchain_community" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "e92dff22", + "metadata": { + "tags": [], + "id": "e92dff22" + }, + "outputs": [], + "source": [ + "from langchain_openai import ChatOpenAI\n", + "from langchain.prompts import ChatPromptTemplate\n", + "from langchain.chains import LLMChain" + ] + }, + { + "cell_type": "code", + "source": [ + "import os\n", + "from google.colab import userdata\n", + "os.environ[\"OPENAI_API_KEY\"] = userdata.get('OPENAI_API_KEY')\n", + "print(os.getenv(\"OPENAI_API_KEY\") is not None)" + ], + "metadata": { + "id": "jN0GBnCjw2TH" + }, + "id": "jN0GBnCjw2TH", + "execution_count": 16, + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "943237a7", + "metadata": { + "id": "943237a7" + }, + "outputs": [], + "source": [ + "#Replace None by your own value and justify\n", + "llm = ChatOpenAI(temperature=0.7)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "cdcdb42d", + "metadata": { + "id": "cdcdb42d" + }, + "outputs": [], + "source": [ + "prompt = ChatPromptTemplate.from_template(\"Describe the following product in a clear and concise way: {product}\"\n", + "\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "d7abc20b", + "metadata": { + "id": "d7abc20b", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "1e5907bb-3db8-424c-e078-875cba0196f4" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/tmp/ipykernel_682/546483037.py:1: LangChainDeprecationWarning: The class `LLMChain` was deprecated in LangChain 0.1.17 and will be removed in 1.0. Use RunnableSequence, e.g., `prompt | llm` instead.\n", + " chain = LLMChain(llm=llm, prompt=prompt)\n" + ] + } + ], + "source": [ + "\n", + "chain = LLMChain(llm=llm, prompt=prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "ad44d1fb", + "metadata": { + "id": "ad44d1fb", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 92 + }, + "outputId": "e0618234-e6ae-40ec-cdc4-72ba8cfefff5" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/tmp/ipykernel_682/3054109201.py:2: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use invoke instead.\n", + " chain.run(product)\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'Pillow inserts are soft, cushioned forms that go inside pillow covers to provide shape and support.'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 23 + } + ], + "source": [ + "product = \"Pillows Insert\"\n", + "chain.run(product)" + ] + }, + { + "cell_type": "code", + "source": [ + "product = \"L'Or Espresso Café\"\n", + "chain.run(product)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 36 + }, + "id": "1pCoUwLNzaMz", + "outputId": "1e43153b-5596-41b0-d52a-22ea0aead8df" + }, + "id": "1pCoUwLNzaMz", + "execution_count": 24, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "\"L'Or Espresso Café is a premium coffee blend that offers a rich and intense flavor, perfect for those who appreciate a strong and bold cup of coffee.\"" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 24 + } + ] + }, + { + "cell_type": "markdown", + "id": "69b03469", + "metadata": { + "id": "69b03469" + }, + "source": [ + "## SimpleSequentialChain" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "febee243", + "metadata": { + "id": "febee243" + }, + "outputs": [], + "source": [ + "from langchain.chains import SimpleSequentialChain" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "2f31aa8a", + "metadata": { + "id": "2f31aa8a" + }, + "outputs": [], + "source": [ + "llm = ChatOpenAI(temperature=0.9)\n", + "\n", + "# prompt template 1\n", + "first_prompt = ChatPromptTemplate.from_template(\n", + " \"Describe the following product in a clear and concise way: {product}\"\n", + ")\n", + "\n", + "# Chain 1\n", + "chain_one = LLMChain(llm=llm, prompt=first_prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "3f5d5b76", + "metadata": { + "id": "3f5d5b76" + }, + "outputs": [], + "source": [ + "\n", + "# prompt template 2\n", + "second_prompt = ChatPromptTemplate.from_template(\n", + " \"\"\"\n", + " Based on the following product description, write a short advertising slogan:\n", + "\n", + " {product_description}\n", + " \"\"\"\n", + ")\n", + "# chain 2\n", + "chain_two = LLMChain(llm=llm, prompt=second_prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "6c1eb2c4", + "metadata": { + "id": "6c1eb2c4" + }, + "outputs": [], + "source": [ + "overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],\n", + " verbose=True\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "78458efe", + "metadata": { + "id": "78458efe", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 146 + }, + "outputId": "8dbcc72e-489b-44e5-c7ac-3d88137b2ca3" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "WARNING:langchain_core.callbacks.manager:Error in StdOutCallbackHandler.on_chain_start callback: AttributeError(\"'NoneType' object has no attribute 'get'\")\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[36;1m\u001b[1;3mL'Or Espresso Café is a premium coffee product that offers a rich and intense espresso experience. Made from carefully selected Arabica and Robusta coffee beans, it delivers a bold and aromatic flavor profile that is perfect for espresso lovers. Enjoy the luxury of café-quality coffee in the comfort of your own home with L'Or Espresso Café.\u001b[0m\n", + "\u001b[33;1m\u001b[1;3m\"Indulge in luxury espresso at home with L'Or Espresso Café!\"\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'\"Indulge in luxury espresso at home with L\\'Or Espresso Café!\"'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 30 + } + ], + "source": [ + "overall_simple_chain.run(product)" + ] + }, + { + "cell_type": "markdown", + "id": "0dd59bda-9d02-44e7-b3d6-2bec61b99d8f", + "metadata": { + "id": "0dd59bda-9d02-44e7-b3d6-2bec61b99d8f" + }, + "source": [ + "**Repeat the above twice for different products**" + ] + }, + { + "cell_type": "markdown", + "id": "7b5ce18c", + "metadata": { + "id": "7b5ce18c" + }, + "source": [ + "## SequentialChain" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "4c129ef6", + "metadata": { + "id": "4c129ef6" + }, + "outputs": [], + "source": [ + "from langchain.chains import SequentialChain" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "016187ac", + "metadata": { + "id": "016187ac" + }, + "outputs": [], + "source": [ + "llm = ChatOpenAI(temperature=0.9)\n", + "\n", + "\n", + "first_prompt = ChatPromptTemplate.from_template(\n", + " \"Translate the {review} to english\"\n", + ")\n", + "\n", + "chain_one = LLMChain(llm=llm, prompt=first_prompt,output_key= \"english_review\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "0fb0730e", + "metadata": { + "id": "0fb0730e" + }, + "outputs": [], + "source": [ + "second_prompt = ChatPromptTemplate.from_template(\n", + " \"\"\"\n", + " Summarize the following customer review in one concise sentence:\n", + "\n", + " {review}\n", + " \"\"\"\n", + ")\n", + "\n", + "chain_two = LLMChain(llm=llm, prompt=second_prompt,output_key=\"review_summary\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "6accf92d", + "metadata": { + "id": "6accf92d" + }, + "outputs": [], + "source": [ + "# prompt template 3: translate to english or other language\n", + "third_prompt = ChatPromptTemplate.from_template(\n", + " \"\"\"\n", + " Translate the following customer review into English or keep its original language:\n", + "\n", + " {review}\n", + " \"\"\"\n", + ")\n", + "# chain 3: input= Review and output= language\n", + "chain_three = LLMChain(llm=llm, prompt=third_prompt,\n", + "output_key=\"translated_review\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "c7a46121", + "metadata": { + "id": "c7a46121" + }, + "outputs": [], + "source": [ + "\n", + "# prompt template 4: follow up message that take as inputs the two previous prompts' variables\n", + "fourth_prompt = ChatPromptTemplate.from_template(\n", + " \"\"\"\n", + " Write a polite follow-up message based on the information below.\n", + "\n", + " Review summary:\n", + " {review_summary}\n", + "\n", + " Translated review:\n", + " {translated_review}\n", + " \"\"\"\n", + ")\n", + "chain_four = LLMChain(llm=llm, prompt=fourth_prompt,\n", + " output_key=\"follow_up_message\"\n", + " )\n" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "89603117", + "metadata": { + "id": "89603117" + }, + "outputs": [], + "source": [ + "# overall_chain: input= Review\n", + "# and output= English_Review,summary, followup_message\n", + "overall_chain = SequentialChain(\n", + " chains=[chain_one, chain_two, chain_three, chain_four],\n", + " input_variables=[\"review\"],\n", + " output_variables=[\n", + " \"english_review\",\n", + " \"review_summary\",\n", + " \"translated_review\",\n", + " \"follow_up_message\"\n", + " ],\n", + " verbose=True\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "51b04f45", + "metadata": { + "id": "51b04f45", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "f829d867-0138-44ae-a6b4-493602b5f92d" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "WARNING:langchain_core.callbacks.manager:Error in StdOutCallbackHandler.on_chain_start callback: AttributeError(\"'NoneType' object has no attribute 'get'\")\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'review': \"\\xa0I loved this product. But they only seem to last a few months. The company was great replacing the first one (the frother falls out of the handle and can't be fixed). The after 4 months my second one did the same. I only use the frother for coffee once a day. It's not overuse or abuse. I'm very disappointed and will look for another. As I understand they will only replace once. Anyway, if you have one good luck.\",\n", + " 'english_review': \"I really liked this product. However, it seems to only last a few months. The company was great about replacing the first one (the frother falls out of the handle and can't be fixed). But after 4 months, my second one did the same thing. I only use the frother for coffee once a day, so it's not from overuse or abuse. I'm very disappointed and will be looking for another brand. I understand they will only replace it once. Anyway, if you have one, good luck.\",\n", + " 'review_summary': 'The customer loved the product but was disappointed that it only lasted a few months before malfunctioning, even with daily use for coffee, and will be looking for a new one as the company only replaces the product once.',\n", + " 'translated_review': \"I loved this product. But they only seem to last a few months. The company was great replacing the first one (the frother falls out of the handle and can't be fixed). The after 4 months my second one did the same. I only use the frother for coffee once a day. It's not overuse or abuse. I'm very disappointed and will look for another. As I understand they will only replace once. Anyway, if you have one good luck.\",\n", + " 'follow_up_message': 'Dear valued customer,\\n\\nThank you for taking the time to share your feedback with us. We are delighted to hear that you loved our product, but we are truly sorry to hear about the malfunctioning issue you experienced with it. We strive to provide high-quality products that last, and we apologize for any inconvenience this may have caused you.\\n\\nWe understand your disappointment and frustration, and we appreciate your understanding regarding our replacement policy. If you have any further questions or concerns, please do not hesitate to reach out to us. We value your loyalty as a customer and would like to assist you in any way we can.\\n\\nThank you for choosing our product, and we wish you the best of luck in finding a suitable replacement. Your satisfaction is our top priority, and we hope to have the opportunity to serve you better in the future.\\n\\nWarm regards, \\n[Your Name]\\n[Your Title]\\n[Company Name]'}" + ] + }, + "metadata": {}, + "execution_count": 59 + } + ], + "source": [ + "review = df.Review[4]\n", + "overall_chain(review)" + ] + }, + { + "cell_type": "markdown", + "id": "3187cf07-458a-4226-bec7-3dec7ee47af2", + "metadata": { + "id": "3187cf07-458a-4226-bec7-3dec7ee47af2" + }, + "source": [ + "**Repeat the above twice for different products or reviews**" + ] + }, + { + "cell_type": "markdown", + "id": "3041ea4c", + "metadata": { + "id": "3041ea4c" + }, + "source": [ + "## Router Chain" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "ade83f4f", + "metadata": { + "id": "ade83f4f" + }, + "outputs": [], + "source": [ + "physics_template = \"\"\"You are a very smart physics professor. \\\n", + "You are great at answering questions about physics in a concise\\\n", + "and easy to understand manner. \\\n", + "When you don't know the answer to a question you admit\\\n", + "that you don't know.\n", + "\n", + "Here is a question:\n", + "{input}\"\"\"\n", + "\n", + "\n", + "math_template = \"\"\"You are a very good mathematician. \\\n", + "You are great at answering math questions. \\\n", + "You are so good because you are able to break down \\\n", + "hard problems into their component parts,\n", + "answer the component parts, and then put them together\\\n", + "to answer the broader question.\n", + "\n", + "Here is a question:\n", + "{input}\"\"\"\n", + "\n", + "history_template = \"\"\"You are a very good historian. \\\n", + "You have an excellent knowledge of and understanding of people,\\\n", + "events and contexts from a range of historical periods. \\\n", + "You have the ability to think, reflect, debate, discuss and \\\n", + "evaluate the past. You have a respect for historical evidence\\\n", + "and the ability to make use of it to support your explanations \\\n", + "and judgements.\n", + "\n", + "Here is a question:\n", + "{input}\"\"\"\n", + "\n", + "\n", + "computerscience_template = \"\"\" You are a successful computer scientist.\\\n", + "You have a passion for creativity, collaboration,\\\n", + "forward-thinking, confidence, strong problem-solving capabilities,\\\n", + "understanding of theories and algorithms, and excellent communication \\\n", + "skills. You are great at answering coding questions. \\\n", + "You are so good because you know how to solve a problem by \\\n", + "describing the solution in imperative steps \\\n", + "that a machine can easily interpret and you know how to \\\n", + "choose a solution that has a good balance between \\\n", + "time complexity and space complexity.\n", + "\n", + "Here is a question:\n", + "{input}\"\"\"\n", + "\n", + "biology_template = \"\"\"You are an excellent biologist. \\\n", + "You have a deep understanding of living organisms, \\\n", + "from the molecular and cellular level to entire ecosystems. \\\n", + "You are skilled at observing patterns in nature, analyzing biological data, \\\n", + "and explaining complex processes like evolution, genetics, physiology, and ecology. \\\n", + "You can clearly communicate how life functions and adapts, \\\n", + "and you make connections between different biological concepts \\\n", + "to answer challenging questions.\n", + "\n", + "Here is a question:\n", + "{input}\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "5f590e9f", + "metadata": { + "id": "5f590e9f" + }, + "outputs": [], + "source": [ + "prompt_infos = [\n", + " {\n", + " \"name\": \"physics\",\n", + " \"description\": \"Good for answering questions about physics\",\n", + " \"prompt_template\": physics_template\n", + " },\n", + " {\n", + " \"name\": \"math\",\n", + " \"description\": \"Good for answering math questions\",\n", + " \"prompt_template\": math_template\n", + " },\n", + " {\n", + " \"name\": \"History\",\n", + " \"description\": \"Good for answering history questions\",\n", + " \"prompt_template\": history_template\n", + " },\n", + " {\n", + " \"name\": \"computer science\",\n", + " \"description\": \"Good for answering computer science questions\",\n", + " \"prompt_template\": computerscience_template\n", + " },\n", + " {\n", + " \"name\": \"biology\",\n", + " \"description\": \"Good for answering biology questions\",\n", + " \"prompt_template\": biology_template\n", + " }\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "31b06fc8", + "metadata": { + "id": "31b06fc8" + }, + "outputs": [], + "source": [ + "from langchain.chains.router import MultiPromptChain\n", + "from langchain.chains.router.llm_router import LLMRouterChain,RouterOutputParser\n", + "from langchain.prompts import PromptTemplate" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "f3f50bcc", + "metadata": { + "id": "f3f50bcc" + }, + "outputs": [], + "source": [ + "llm = ChatOpenAI(temperature=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "8eefec24", + "metadata": { + "id": "8eefec24" + }, + "outputs": [], + "source": [ + "destination_chains = {}\n", + "for p_info in prompt_infos:\n", + " name = p_info[\"name\"]\n", + " prompt_template = p_info[\"prompt_template\"]\n", + " prompt = ChatPromptTemplate.from_template(template=prompt_template)\n", + " chain = LLMChain(llm=llm, prompt=prompt)\n", + " destination_chains[name] = chain\n", + "\n", + "destinations = [f\"{p['name']}: {p['description']}\" for p in prompt_infos]\n", + "destinations_str = \"\\n\".join(destinations)" + ] + }, + { + "cell_type": "code", + "source": [ + "print(destinations_str)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "QELFiBmNGFP0", + "outputId": "719def79-2498-463a-cff6-7585446b426e" + }, + "id": "QELFiBmNGFP0", + "execution_count": 68, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "physics: Good for answering questions about physics\n", + "math: Good for answering math questions\n", + "History: Good for answering history questions\n", + "computer science: Good for answering computer science questions\n", + "biology: Good for answering biology questions\n" + ] + } + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "9f98018a", + "metadata": { + "id": "9f98018a" + }, + "outputs": [], + "source": [ + "default_prompt = ChatPromptTemplate.from_template(\"{input}\")\n", + "default_chain = LLMChain(llm=llm, prompt=default_prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "11b2e2ba", + "metadata": { + "id": "11b2e2ba" + }, + "outputs": [], + "source": [ + "MULTI_PROMPT_ROUTER_TEMPLATE = \"\"\"Given a raw text input to a \\\n", + "language model select the model prompt best suited for the input. \\\n", + "You will be given the names of the available prompts and a \\\n", + "description of what the prompt is best suited for. \\\n", + "You may also revise the original input if you think that revising\\\n", + "it will ultimately lead to a better response from the language model.\n", + "\n", + "<< FORMATTING >>\n", + "Return a markdown code snippet with a JSON object formatted to look like:\n", + "```json\n", + "{{{{\n", + " \"destination\": string \\ name of the prompt to use or \"DEFAULT\"\n", + " \"next_inputs\": string \\ a potentially modified version of the original input\n", + "}}}}\n", + "```\n", + "\n", + "REMEMBER: \"destination\" MUST be one of the candidate prompt \\\n", + "names specified below OR it can be \"DEFAULT\" if the input is not\\\n", + "well suited for any of the candidate prompts.\n", + "REMEMBER: \"next_inputs\" can just be the original input \\\n", + "if you don't think any modifications are needed.\n", + "\n", + "<< CANDIDATE PROMPTS >>\n", + "{destinations}\n", + "\n", + "<< INPUT >>\n", + "{{input}}\n", + "\n", + "<< OUTPUT (remember to include the ```json)>>\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "id": "1387109d", + "metadata": { + "id": "1387109d" + }, + "outputs": [], + "source": [ + "router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(\n", + " destinations=destinations_str\n", + ")\n", + "router_prompt = PromptTemplate(\n", + " template=router_template,\n", + " input_variables=[\"input\"],\n", + " output_parser=RouterOutputParser(),\n", + ")\n", + "\n", + "router_chain = LLMRouterChain.from_llm(llm, router_prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "2fb7d560", + "metadata": { + "id": "2fb7d560", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "d7ff4f72-b1f8-486d-fb51-cd5967de4650" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/tmp/ipykernel_682/2333002322.py:1: LangChainDeprecationWarning: Use RunnableLambda to select from multiple prompt templates. See example in API reference: https://api.python.langchain.com/en/latest/chains/langchain.chains.router.multi_prompt.MultiPromptChain.html\n", + " chain = MultiPromptChain(router_chain=router_chain,\n" + ] + } ], - "text/plain": [ - " Product Review\n", - "0 Queen Size Sheet Set I ordered a king size set. My only criticism w...\n", - "1 Waterproof Phone Pouch I loved the waterproof sac, although the openi...\n", - "2 Luxury Air Mattress This mattress had a small hole in the top of i...\n", - "3 Pillows Insert This is the best throw pillow fillers on Amazo...\n", - "4 Milk Frother Handheld\\n  I loved this product. But they only seem to l..." - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" + "source": [ + "chain = MultiPromptChain(router_chain=router_chain,\n", + " destination_chains=destination_chains,\n", + " default_chain=default_chain, verbose=True\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "d86b2131", + "metadata": { + "id": "d86b2131", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 144 + }, + "outputId": "f8e7b06d-5cb6-40b7-b141-657bb3ae51a8" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "WARNING:langchain_core.callbacks.manager:Error in StdOutCallbackHandler.on_chain_start callback: AttributeError(\"'NoneType' object has no attribute 'get'\")\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "physics: {'input': 'What is black body radiation?'}\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "\"Black body radiation refers to the electromagnetic radiation emitted by a perfect black body, which is an idealized physical body that absorbs all incident electromagnetic radiation and emits radiation at all frequencies. The radiation emitted by a black body depends only on its temperature and follows a specific distribution known as Planck's law. This type of radiation is important in understanding concepts such as thermal radiation and the behavior of objects at different temperatures.\"" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 73 + } + ], + "source": [ + "chain.run(\"What is black body radiation?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "3b717379", + "metadata": { + "id": "3b717379", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 90 + }, + "outputId": "2bdfe480-2e52-4182-d042-c550fb39a20a" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "WARNING:langchain_core.callbacks.manager:Error in StdOutCallbackHandler.on_chain_start callback: AttributeError(\"'NoneType' object has no attribute 'get'\")\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "math: {'input': 'what is 2 + 2'}\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'Thank you for the compliment! The answer to the question \"what is 2 + 2\" is 4.'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 74 + } + ], + "source": [ + "chain.run(\"what is 2 + 2\")" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "29e5be01", + "metadata": { + "id": "29e5be01", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 199 + }, + "outputId": "0d0f33a1-d350-49a7-af31-89b13cf21d5e" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "WARNING:langchain_core.callbacks.manager:Error in StdOutCallbackHandler.on_chain_start callback: AttributeError(\"'NoneType' object has no attribute 'get'\")\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "biology: {'input': 'Why does every cell in our body contain DNA?'}\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'Every cell in our body contains DNA because DNA is the genetic material that carries the instructions for the development, functioning, and reproduction of all living organisms. DNA contains the information needed to build and maintain an organism, including the proteins that make up our cells and tissues. \\n\\nHaving DNA in every cell ensures that each cell has the necessary information to carry out its specific functions and to replicate itself accurately during cell division. This ensures that the genetic information is passed on to the next generation of cells. \\n\\nAdditionally, DNA is constantly being used by cells to carry out processes such as protein synthesis, cell growth, and repair. Having DNA in every cell allows for the coordination of these processes and ensures that the organism functions properly as a whole. \\n\\nIn summary, every cell in our body contains DNA because it is essential for the proper functioning and development of all living organisms.'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 75 + } + ], + "source": [ + "chain.run(\"Why does every cell in our body contain DNA?\")" + ] + }, + { + "cell_type": "markdown", + "id": "09e0c60b-7ae0-453e-9467-142d8dafee6e", + "metadata": { + "id": "09e0c60b-7ae0-453e-9467-142d8dafee6e" + }, + "source": [ + "**Repeat the above at least once for different inputs and chains executions - Be creative!**" + ] } - ], - "source": [ - "df.head()" - ] - }, - { - "cell_type": "markdown", - "id": "b940ce7c", - "metadata": {}, - "source": [ - "## LLMChain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "427e1119", - "metadata": {}, - "outputs": [], - "source": [ - "!pip install langchain_community" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "e92dff22", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from langchain_openai import ChatOpenAI\n", - "from langchain.prompts import ChatPromptTemplate\n", - "from langchain.chains import LLMChain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "943237a7", - "metadata": {}, - "outputs": [], - "source": [ - "#Replace None by your own value and justify\n", - "llm = ChatOpenAI(temperature=None)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cdcdb42d", - "metadata": {}, - "outputs": [], - "source": [ - "prompt = ChatPromptTemplate.from_template( #Write a query that would take a variable to describe any product\n", - " \n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d7abc20b", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "chain = LLMChain(llm=llm, prompt=prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ad44d1fb", - "metadata": {}, - "outputs": [], - "source": [ - "product = #Select a product type to be describe\n", - "chain.run(product)" - ] - }, - { - "cell_type": "markdown", - "id": "69b03469", - "metadata": {}, - "source": [ - "## SimpleSequentialChain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "febee243", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.chains import SimpleSequentialChain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2f31aa8a", - "metadata": {}, - "outputs": [], - "source": [ - "llm = ChatOpenAI(temperature=0.9)\n", - "\n", - "# prompt template 1\n", - "first_prompt = ChatPromptTemplate.from_template(\n", - " #Repeat the initial query or create a new query that would feed into the second prompt\n", - ")\n", - "\n", - "# Chain 1\n", - "chain_one = LLMChain(llm=llm, prompt=first_prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3f5d5b76", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "# prompt template 2\n", - "second_prompt = ChatPromptTemplate.from_template(\n", - " #Write the second prompt query that takes an input variable whose input will come from the previous prompt\"\n", - ")\n", - "# chain 2\n", - "chain_two = LLMChain(llm=llm, prompt=second_prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6c1eb2c4", - "metadata": {}, - "outputs": [], - "source": [ - "overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],\n", - " verbose=True\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "78458efe", - "metadata": {}, - "outputs": [], - "source": [ - "overall_simple_chain.run(product)" - ] - }, - { - "cell_type": "markdown", - "id": "0dd59bda-9d02-44e7-b3d6-2bec61b99d8f", - "metadata": {}, - "source": [ - "**Repeat the above twice for different products**" - ] - }, - { - "cell_type": "markdown", - "id": "7b5ce18c", - "metadata": {}, - "source": [ - "## SequentialChain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c129ef6", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.chains import SequentialChain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "016187ac", - "metadata": {}, - "outputs": [], - "source": [ - "llm = ChatOpenAI(temperature=0.9)\n", - "\n", - "\n", - "first_prompt = ChatPromptTemplate.from_template(\n", - " #This prompt should translate a review\n", - ")\n", - "\n", - "chain_one = LLMChain(llm=llm, prompt=first_prompt, \n", - " output_key=None #Give a name to your output\n", - " )\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0fb0730e", - "metadata": {}, - "outputs": [], - "source": [ - "second_prompt = ChatPromptTemplate.from_template(\n", - " #Write a promplt to summarize a review\n", - ")\n", - "\n", - "chain_two = LLMChain(llm=llm, prompt=second_prompt, \n", - " output_key=None #give a name to this output\n", - " )\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6accf92d", - "metadata": {}, - "outputs": [], - "source": [ - "# prompt template 3: translate to english or other language\n", - "third_prompt = ChatPromptTemplate.from_template(\n", - " None\n", - ")\n", - "# chain 3: input= Review and output= language\n", - "chain_three = LLMChain(llm=llm, prompt=third_prompt,\n", - " output_key=None\n", - " )\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c7a46121", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "# prompt template 4: follow up message that take as inputs the two previous prompts' variables\n", - "fourth_prompt = ChatPromptTemplate.from_template(\n", - " None\n", - ")\n", - "chain_four = LLMChain(llm=llm, prompt=fourth_prompt,\n", - " output_key=None\n", - " )\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "89603117", - "metadata": {}, - "outputs": [], - "source": [ - "# overall_chain: input= Review \n", - "# and output= English_Review,summary, followup_message\n", - "overall_chain = SequentialChain(\n", - " chains=[chain_one, chain_two, chain_three, chain_four],\n", - " input_variables=None,\n", - " output_variables=[None, None, None],\n", - " verbose=True\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "51b04f45", - "metadata": {}, - "outputs": [], - "source": [ - "review = df.Review[5]\n", - "overall_chain(review)" - ] - }, - { - "cell_type": "markdown", - "id": "3187cf07-458a-4226-bec7-3dec7ee47af2", - "metadata": {}, - "source": [ - "**Repeat the above twice for different products or reviews**" - ] - }, - { - "cell_type": "markdown", - "id": "3041ea4c", - "metadata": {}, - "source": [ - "## Router Chain" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ade83f4f", - "metadata": {}, - "outputs": [], - "source": [ - "physics_template = \"\"\"You are a very smart physics professor. \\\n", - "You are great at answering questions about physics in a concise\\\n", - "and easy to understand manner. \\\n", - "When you don't know the answer to a question you admit\\\n", - "that you don't know.\n", - "\n", - "Here is a question:\n", - "{input}\"\"\"\n", - "\n", - "\n", - "math_template = \"\"\"You are a very good mathematician. \\\n", - "You are great at answering math questions. \\\n", - "You are so good because you are able to break down \\\n", - "hard problems into their component parts, \n", - "answer the component parts, and then put them together\\\n", - "to answer the broader question.\n", - "\n", - "Here is a question:\n", - "{input}\"\"\"\n", - "\n", - "history_template = \"\"\"You are a very good historian. \\\n", - "You have an excellent knowledge of and understanding of people,\\\n", - "events and contexts from a range of historical periods. \\\n", - "You have the ability to think, reflect, debate, discuss and \\\n", - "evaluate the past. You have a respect for historical evidence\\\n", - "and the ability to make use of it to support your explanations \\\n", - "and judgements.\n", - "\n", - "Here is a question:\n", - "{input}\"\"\"\n", - "\n", - "\n", - "computerscience_template = \"\"\" You are a successful computer scientist.\\\n", - "You have a passion for creativity, collaboration,\\\n", - "forward-thinking, confidence, strong problem-solving capabilities,\\\n", - "understanding of theories and algorithms, and excellent communication \\\n", - "skills. You are great at answering coding questions. \\\n", - "You are so good because you know how to solve a problem by \\\n", - "describing the solution in imperative steps \\\n", - "that a machine can easily interpret and you know how to \\\n", - "choose a solution that has a good balance between \\\n", - "time complexity and space complexity. \n", - "\n", - "Here is a question:\n", - "{input}\"\"\"\n", - "\n", - "biology_template = \"\"\"You are an excellent biologist. \\\n", - "You have a deep understanding of living organisms, \\\n", - "from the molecular and cellular level to entire ecosystems. \\\n", - "You are skilled at observing patterns in nature, analyzing biological data, \\\n", - "and explaining complex processes like evolution, genetics, physiology, and ecology. \\\n", - "You can clearly communicate how life functions and adapts, \\\n", - "and you make connections between different biological concepts \\\n", - "to answer challenging questions.\n", - "\n", - "Here is a question:\n", - "{input}\"\"\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5f590e9f", - "metadata": {}, - "outputs": [], - "source": [ - "prompt_infos = [\n", - " {\n", - " \"name\": \"physics\", \n", - " \"description\": \"Good for answering questions about physics\", \n", - " \"prompt_template\": physics_template\n", - " },\n", - " {\n", - " \"name\": \"math\", \n", - " \"description\": \"Good for answering math questions\", \n", - " \"prompt_template\": math_template\n", - " },\n", - " {\n", - " \"name\": \"History\", \n", - " \"description\": \"Good for answering history questions\", \n", - " \"prompt_template\": history_template\n", - " },\n", - " {\n", - " \"name\": \"computer science\", \n", - " \"description\": \"Good for answering computer science questions\", \n", - " \"prompt_template\": computerscience_template\n", - " },\n", - " {\n", - " \"name\": \"biology\",\n", - " \"description\": \"Good for answering biology questions\",\n", - " \"prompt_template\": biology_template\n", - " }\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "31b06fc8", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.chains.router import MultiPromptChain\n", - "from langchain.chains.router.llm_router import LLMRouterChain,RouterOutputParser\n", - "from langchain.prompts import PromptTemplate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f3f50bcc", - "metadata": {}, - "outputs": [], - "source": [ - "llm = ChatOpenAI(temperature=0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8eefec24", - "metadata": {}, - "outputs": [], - "source": [ - "destination_chains = {}\n", - "for p_info in prompt_infos:\n", - " name = p_info[\"name\"]\n", - " prompt_template = p_info[\"prompt_template\"]\n", - " prompt = ChatPromptTemplate.from_template(template=prompt_template)\n", - " chain = LLMChain(llm=llm, prompt=prompt)\n", - " destination_chains[name] = chain \n", - " \n", - "destinations = [f\"{p['name']}: {p['description']}\" for p in prompt_infos]\n", - "destinations_str = \"\\n\".join(destinations)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9f98018a", - "metadata": {}, - "outputs": [], - "source": [ - "default_prompt = ChatPromptTemplate.from_template(\"{input}\")\n", - "default_chain = LLMChain(llm=llm, prompt=default_prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11b2e2ba", - "metadata": {}, - "outputs": [], - "source": [ - "MULTI_PROMPT_ROUTER_TEMPLATE = \"\"\"Given a raw text input to a \\\n", - "language model select the model prompt best suited for the input. \\\n", - "You will be given the names of the available prompts and a \\\n", - "description of what the prompt is best suited for. \\\n", - "You may also revise the original input if you think that revising\\\n", - "it will ultimately lead to a better response from the language model.\n", - "\n", - "<< FORMATTING >>\n", - "Return a markdown code snippet with a JSON object formatted to look like:\n", - "```json\n", - "{{{{\n", - " \"destination\": string \\ name of the prompt to use or \"DEFAULT\"\n", - " \"next_inputs\": string \\ a potentially modified version of the original input\n", - "}}}}\n", - "```\n", - "\n", - "REMEMBER: \"destination\" MUST be one of the candidate prompt \\\n", - "names specified below OR it can be \"DEFAULT\" if the input is not\\\n", - "well suited for any of the candidate prompts.\n", - "REMEMBER: \"next_inputs\" can just be the original input \\\n", - "if you don't think any modifications are needed.\n", - "\n", - "<< CANDIDATE PROMPTS >>\n", - "{destinations}\n", - "\n", - "<< INPUT >>\n", - "{{input}}\n", - "\n", - "<< OUTPUT (remember to include the ```json)>>\"\"\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1387109d", - "metadata": {}, - "outputs": [], - "source": [ - "router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(\n", - " destinations=destinations_str\n", - ")\n", - "router_prompt = PromptTemplate(\n", - " template=router_template,\n", - " input_variables=[\"input\"],\n", - " output_parser=RouterOutputParser(),\n", - ")\n", - "\n", - "router_chain = LLMRouterChain.from_llm(llm, router_prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2fb7d560", - "metadata": {}, - "outputs": [], - "source": [ - "chain = MultiPromptChain(router_chain=router_chain, \n", - " destination_chains=destination_chains, \n", - " default_chain=default_chain, verbose=True\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d86b2131", - "metadata": {}, - "outputs": [], - "source": [ - "chain.run(\"What is black body radiation?\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3b717379", - "metadata": {}, - "outputs": [], - "source": [ - "chain.run(\"what is 2 + 2\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "29e5be01", - "metadata": {}, - "outputs": [], - "source": [ - "chain.run(\"Why does every cell in our body contain DNA?\")" - ] - }, - { - "cell_type": "markdown", - "id": "09e0c60b-7ae0-453e-9467-142d8dafee6e", - "metadata": {}, - "source": [ - "**Repeat the above at least once for different inputs and chains executions - Be creative!**" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.11.8" + }, + "colab": { + "provenance": [], + "gpuType": "T4" + }, + "accelerator": "GPU" }, - "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.11.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file