diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..7affdc5 Binary files /dev/null and b/.DS_Store differ diff --git a/lab-chains-in-langchain.ipynb b/lab-chains-in-langchain.ipynb deleted file mode 100644 index 290f3bb..0000000 --- a/lab-chains-in-langchain.ipynb +++ /dev/null @@ -1,728 +0,0 @@ -{ - "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", - "
" - ], - "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": [ - "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" - }, - "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 -} diff --git a/lab_chains_in_langchain.ipynb b/lab_chains_in_langchain.ipynb new file mode 100644 index 0000000..7ffefef --- /dev/null +++ b/lab_chains_in_langchain.ipynb @@ -0,0 +1,1032 @@ +{ + "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": 9, + "id": "541eb2f1", + "metadata": { + "id": "541eb2f1" + }, + "outputs": [], + "source": [ + "!pip install -qU langchain langchain-openai python-dotenv pandas\n", + "\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "code", + "source": [ + "\n", + "import os\n", + "import time\n", + "import warnings\n", + "import tiktoken\n", + "\n", + "from google.colab import userdata\n", + "\n", + "\n", + "def load_colab_secret(secret_name: str) -> None:\n", + " \"\"\"Load a Colab secret into an environment variable.\"\"\"\n", + " try:\n", + " secret_value = userdata.get(secret_name)\n", + "\n", + " if not secret_value:\n", + " raise ValueError(\"Secret is empty.\")\n", + "\n", + " os.environ[secret_name] = secret_value\n", + "\n", + " except Exception as exc:\n", + " raise RuntimeError(\n", + " f\"Could not access {secret_name}. \"\n", + " \"Make sure it exists in Colab's Secrets tab and \"\n", + " \"that notebook access is enabled.\"\n", + " ) from exc\n", + "\n", + "\n", + "load_colab_secret(\"OPENAI_API_KEY\")\n", + "load_colab_secret(\"PINECONE_API_KEY\")\n", + "load_colab_secret(\"HF_TOKEN\")\n", + "\n", + "print(\"Environment ready ✅\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "4GgHNd4TLrvz", + "outputId": "50ede7e5-37ed-4920-e96d-b3a97f8fc3a9" + }, + "id": "4GgHNd4TLrvz", + "execution_count": 11, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Environment ready ✅\n" + ] + } + ] + }, + { + "cell_type": "code", + "execution_count": null, + "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": 13, + "id": "b84e441b", + "metadata": { + "tags": [], + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "b84e441b", + "outputId": "6d0b9f0e-ccae-4dd8-93bb-287028f5a6d0" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Requirement already satisfied: pandas in /usr/local/lib/python3.12/dist-packages (3.0.5)\n", + "Requirement already satisfied: numpy>=1.26.0 in /usr/local/lib/python3.12/dist-packages (from pandas) (2.0.2)\n", + "Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.12/dist-packages (from pandas) (2.9.0.post0)\n", + "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.12/dist-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)\n" + ] + } + ], + "source": [ + "!pip install pandas" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", + "metadata": { + "tags": [], + "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b" + }, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "\n", + "import pandas as pd\n", + "\n", + "data_path = Path('Data.csv')\n", + "if not data_path.exists():\n", + " data_path = Path('./Data chains in langchains.csv')\n", + "df = pd.read_csv(data_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "b7a09c35", + "metadata": { + "tags": [], + "colab": { + "base_uri": "https://localhost:8080/", + "height": 206 + }, + "id": "b7a09c35", + "outputId": "eea7665e-e938-46f1-87d7-ca04f16be783" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "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..." + ], + "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", + "
" + ] + }, + "metadata": {}, + "execution_count": 15 + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "b940ce7c", + "metadata": { + "id": "b940ce7c" + }, + "source": [ + "## LLMChain" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "427e1119", + "metadata": { + "id": "427e1119" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "e92dff22", + "metadata": { + "tags": [], + "id": "e92dff22" + }, + "outputs": [], + "source": [ + "from langchain_openai import ChatOpenAI\n", + "from langchain_core.output_parsers import StrOutputParser\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langchain_core.runnables import RunnableLambda, RunnablePassthrough" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "943237a7", + "metadata": { + "id": "943237a7" + }, + "outputs": [], + "source": [ + "#Replace None by your own value and justify\n", + "llm = ChatOpenAI(model='gpt-4.1-mini', temperature=0.5)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "cdcdb42d", + "metadata": { + "id": "cdcdb42d" + }, + "outputs": [], + "source": [ + "prompt = ChatPromptTemplate.from_template(\n", + " \"Write a short and catchy product description for the following product: {product}\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "d7abc20b", + "metadata": { + "id": "d7abc20b" + }, + "outputs": [], + "source": [ + "\n", + "chain = prompt | llm | StrOutputParser()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "ad44d1fb", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 53 + }, + "id": "ad44d1fb", + "outputId": "ef8ee9fd-121b-44d7-a3e9-33213cc8c8eb" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'Sleep like royalty with our Queen Size Sheet Set—ultra-soft, breathable, and designed for a perfect fit. Elevate your bedroom comfort and enjoy nights of luxurious rest!'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 24 + } + ], + "source": [ + "product = df[\"Product\"][0]\n", + "chain.invoke(product)" + ] + }, + { + "cell_type": "markdown", + "id": "69b03469", + "metadata": { + "id": "69b03469" + }, + "source": [ + "## SimpleSequentialChain" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "febee243", + "metadata": { + "id": "febee243" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "2f31aa8a", + "metadata": { + "id": "2f31aa8a" + }, + "outputs": [], + "source": [ + "llm = ChatOpenAI(model='gpt-4.1-mini', temperature=0.9)\n", + "\n", + "# prompt template 1\n", + "first_prompt = ChatPromptTemplate.from_template(\n", + " \"Write a short and catchy product description for: {product}\"\n", + ")\n", + "\n", + "# Chain 1\n", + "chain_one = first_prompt | llm | StrOutputParser()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "3f5d5b76", + "metadata": { + "id": "3f5d5b76" + }, + "outputs": [], + "source": [ + "\n", + "# prompt template 2\n", + "second_prompt = ChatPromptTemplate.from_template(\n", + " \"Based on this product description, suggest 3 target customer types:\\n\\n{text}\"\n", + ")\n", + "# chain 2\n", + "chain_two = second_prompt | llm | StrOutputParser()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "6c1eb2c4", + "metadata": { + "id": "6c1eb2c4" + }, + "outputs": [], + "source": [ + "overall_simple_chain = chain_one | chain_two" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "78458efe", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 71 + }, + "id": "78458efe", + "outputId": "67e68fb9-3127-411a-8673-5dda083a2264" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'1. **Comfort-Seeking Homeowners** \\n Individuals or families who prioritize high-quality bedding for a cozy and luxurious sleep experience.\\n\\n2. **Young Professionals** \\n People setting up their first apartments or upgrading their bedroom essentials with stylish and comfortable sheets.\\n\\n3. **Gift Buyers** \\n Shoppers looking for elegant and practical gifts for weddings, housewarmings, or special occasions.'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 29 + } + ], + "source": [ + "overall_simple_chain.invoke(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": null, + "id": "4c129ef6", + "metadata": { + "id": "4c129ef6" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "016187ac", + "metadata": { + "id": "016187ac" + }, + "outputs": [], + "source": [ + "llm = ChatOpenAI(model='gpt-4.1-mini', temperature=0.9)\n", + "\n", + "\n", + "first_prompt = ChatPromptTemplate.from_template(\n", + " \"Translate the following review to Italian:\\n\\n{review}\"\n", + ")\n", + "\n", + "first_output_key = \"italian_review\"\n", + "chain_one = first_prompt | llm | StrOutputParser()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "0fb0730e", + "metadata": { + "id": "0fb0730e" + }, + "outputs": [], + "source": [ + "second_prompt = ChatPromptTemplate.from_template(\n", + " \"Summarize this review in 1 sentence:\\n\\n{italian_review}\"\n", + ")\n", + "\n", + "second_output_key = \"summary\"\n", + "chain_two = second_prompt | llm | StrOutputParser()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "6accf92d", + "metadata": { + "id": "6accf92d" + }, + "outputs": [], + "source": [ + "# prompt template 3: translate to italian or other language\n", + "third_prompt = ChatPromptTemplate.from_template(\n", + " \"What language is this review written in?\\n\\n{review}\"\n", + ")\n", + "# chain 3: input= Review and output= language\n", + "third_output_key = \"language\"\n", + "chain_three = third_prompt | llm | StrOutputParser()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "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", + " \"Write a polite follow-up email in {language} based on this summary:\\n\\n{summary}\"\n", + ")\n", + "fourth_output_key = \"followup_message\"\n", + "chain_four = fourth_prompt | llm | StrOutputParser()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "89603117", + "metadata": { + "id": "89603117" + }, + "outputs": [], + "source": [ + "# overall_chain: input= Review\n", + "# and output= italian_Review,summary, followup_message\n", + "input_variables = [\"review\"]\n", + "output_variables = [\"italian_review\", \"summary\", \"followup_message\"]\n", + "\n", + "overall_chain = (\n", + " RunnableLambda(lambda review: {input_variables[0]: review})\n", + " | RunnablePassthrough.assign(**{first_output_key: chain_one})\n", + " | RunnablePassthrough.assign(\n", + " **{second_output_key: chain_two, third_output_key: chain_three}\n", + " )\n", + " | RunnablePassthrough.assign(**{fourth_output_key: chain_four})\n", + " | RunnableLambda(\n", + " lambda state: {key: state[key] for key in [*input_variables, *output_variables]}\n", + " )\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "51b04f45", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "51b04f45", + "outputId": "250c7039-d79d-4646-d645-acf45604e83d" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'review': \"Je trouve le goût médiocre. La mousse ne tient pas, c'est bizarre. J'achète les mêmes dans le commerce et le goût est bien meilleur...\\nVieux lot ou contrefaçon !?\",\n", + " 'italian_review': 'Trovo il gusto mediocre. La schiuma non regge, è strano. Compro gli stessi al supermercato e il gusto è molto migliore...\\nVecchio lotto o contraffazione!?',\n", + " 'summary': \"L'utente ritiene il gusto mediocre e la schiuma scadente rispetto a confezioni precedenti acquistate al supermercato, sospettando un lotto vecchio o una contraffazione.\",\n", + " 'followup_message': \"Objet : Suivi concernant votre avis sur notre produit\\n\\nBonjour,\\n\\nNous vous remercions d'avoir pris le temps de nous faire part de votre avis concernant notre produit. Nous sommes désolés d'apprendre que votre expérience n'a pas été à la hauteur de vos attentes, notamment en ce qui concerne le goût et la qualité de la mousse.\\n\\nAfin de mieux comprendre la situation et de vous apporter une solution adaptée, pourriez-vous s'il vous plaît nous indiquer le numéro de lot ainsi que le lieu et la date d'achat de la bouteille concernée ? Cela nous permettra de vérifier la conformité du produit et d'écarter toute possibilité de lot défectueux ou de contrefaçon.\\n\\nNous attachons une grande importance à la qualité de nos produits et à la satisfaction de nos clients, et nous espérons pouvoir rapidement résoudre ce désagrément.\\n\\nDans l'attente de votre retour, nous restons à votre disposition pour toute question complémentaire.\\n\\nCordialement, \\n[Votre prénom et nom] \\n[Votre poste] \\n[Nom de l’entreprise] \\n[Coordonnées de contact]\"}" + ] + }, + "metadata": {}, + "execution_count": 36 + } + ], + "source": [ + "review = df.Review[5]\n", + "overall_chain.invoke(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": 37, + "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": 38, + "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": 39, + "id": "31b06fc8", + "metadata": { + "id": "31b06fc8" + }, + "outputs": [], + "source": [ + "from typing import Literal\n", + "\n", + "from pydantic import BaseModel, Field\n", + "\n", + "class RouteQuery(BaseModel):\n", + " destination: Literal[\n", + " 'physics', 'math', 'History', 'computer science', 'biology', 'DEFAULT'\n", + " ] = Field(description='The best prompt for the input')\n", + " next_inputs: str = Field(description='The original or improved input')" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "f3f50bcc", + "metadata": { + "id": "f3f50bcc" + }, + "outputs": [], + "source": [ + "llm = ChatOpenAI(model='gpt-4.1-mini', temperature=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "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 = prompt | llm | StrOutputParser()\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": 42, + "id": "9f98018a", + "metadata": { + "id": "9f98018a" + }, + "outputs": [], + "source": [ + "default_prompt = ChatPromptTemplate.from_template(\"{input}\")\n", + "default_chain = default_prompt | llm | StrOutputParser()" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "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", + "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 >>\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "1387109d", + "metadata": { + "id": "1387109d" + }, + "outputs": [], + "source": [ + "router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(\n", + " destinations=destinations_str\n", + ")\n", + "router_prompt = ChatPromptTemplate.from_template(router_template)\n", + "router_chain = router_prompt | llm.with_structured_output(\n", + " RouteQuery, method='json_schema'\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "2fb7d560", + "metadata": { + "id": "2fb7d560" + }, + "outputs": [], + "source": [ + "def route_input(user_input):\n", + " route = router_chain.invoke({'input': user_input})\n", + " selected_chain = destination_chains.get(route.destination, default_chain)\n", + " return selected_chain.invoke(route.next_inputs)\n", + "\n", + "chain = RunnableLambda(route_input)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "d86b2131", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 107 + }, + "id": "d86b2131", + "outputId": "b8e591d4-6840-4380-f2b2-b7cb4403d11f" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'Black body radiation is the electromagnetic radiation emitted by an idealized object called a black body, which absorbs all incident radiation regardless of frequency or angle. When this object is at a certain temperature, it emits radiation with a characteristic spectrum that depends only on its temperature, not on its material. This spectrum is continuous and peaks at a wavelength inversely proportional to the temperature (Wien’s law). Black body radiation was crucial in the development of quantum mechanics because classical physics couldn’t explain its observed spectrum, leading to Planck’s introduction of quantized energy levels.'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 46 + } + ], + "source": [ + "chain.invoke(\"What is black body radiation?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "3b717379", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 53 + }, + "id": "3b717379", + "outputId": "0b97e1bd-38d7-44fe-c5d0-967621bbcea4" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "\"Great! Let's break down the problem:\\n\\n1. Identify the numbers involved: 2 and 2.\\n2. Understand the operation: addition (+).\\n3. Add the two numbers together: 2 + 2.\\n\\nNow, performing the addition:\\n\\n2 + 2 = 4.\\n\\nSo, the answer is **4**.\"" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 47 + } + ], + "source": [ + "chain.invoke(\"what is 2 + 2\")" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "29e5be01", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 143 + }, + "id": "29e5be01", + "outputId": "ec76ad63-b277-4573-e965-73a1048f9cbf" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'Every cell in our body contains DNA because DNA holds the complete set of instructions necessary for the structure, function, and regulation of the organism. Here’s a detailed explanation:\\n\\n1. **Genetic Blueprint:** DNA (deoxyribonucleic acid) contains genes, which are sequences of nucleotides that encode the information to build proteins and RNA molecules. Proteins are essential for virtually all cellular functions, including metabolism, signaling, structural support, and replication.\\n\\n2. **Cellular Identity and Function:** Although different cell types (e.g., muscle cells, nerve cells, skin cells) perform specialized functions, they all originate from a single fertilized egg and share the same DNA. The difference in cell types arises from differential gene expression—cells turn on or off specific genes depending on their role, but the underlying DNA sequence remains the same.\\n\\n3. **Development and Growth:** During development, cells divide and differentiate, but each new cell inherits a complete copy of the organism’s DNA. This ensures that every cell has the full genetic information needed to maintain the organism’s integrity and respond to environmental signals.\\n\\n4. **Repair and Maintenance:** DNA in every cell allows for the production of proteins required for cell repair, maintenance, and replication. Without DNA, cells would lack the instructions to sustain themselves or reproduce.\\n\\n5. **Evolutionary Consistency:** Having DNA in every cell ensures genetic continuity across generations and within the organism’s lifespan, allowing for stable inheritance and proper functioning.\\n\\nIn summary, every cell contains DNA because it is the fundamental repository of genetic information that guides all cellular activities, maintains organismal unity, and enables life to function cohesively.'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 48 + } + ], + "source": [ + "chain.invoke(\"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!**" + ] + }, + { + "cell_type": "code", + "source": [ + "chain.invoke(\"What causes the Northern Lights?\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 71 + }, + "id": "-pG8FR8VXKOp", + "outputId": "1afd0f0c-2186-4944-8fa0-a36de41bbf75" + }, + "id": "-pG8FR8VXKOp", + "execution_count": 50, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "\"The Northern Lights, or Aurora Borealis, are caused by charged particles from the Sun—mainly electrons and protons—colliding with gases in Earth's atmosphere. These particles are funneled by Earth's magnetic field toward the polar regions, where they interact with oxygen and nitrogen atoms. This interaction excites the atoms, causing them to emit light, which we see as colorful glowing patterns in the sky.\"" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 50 + } + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "anaconda-ml-ai", + "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.13.13" + }, + "colab": { + "provenance": [] + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file