diff --git a/docs/00-introduction.ipynb b/docs/00-introduction.ipynb index 4d672f37..06650703 100644 --- a/docs/00-introduction.ipynb +++ b/docs/00-introduction.ipynb @@ -44,13 +44,6 @@ "!pip install -qU semantic-router==0.0.15" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_**⚠️ If using Google Colab, install the prerequisites and then restart the notebook before continuing**_" - ] - }, { "cell_type": "markdown", "metadata": {}, diff --git a/docs/01-save-load-from-file.ipynb b/docs/01-save-load-from-file.ipynb index 43937d2b..6c5945cb 100644 --- a/docs/01-save-load-from-file.ipynb +++ b/docs/01-save-load-from-file.ipynb @@ -39,13 +39,6 @@ "!pip install -qU semantic-router==0.0.15" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_**⚠️ If using Google Colab, install the prerequisites and then restart the notebook before continuing**_" - ] - }, { "cell_type": "markdown", "metadata": {}, diff --git a/docs/02-dynamic-routes.ipynb b/docs/02-dynamic-routes.ipynb index 70c5eced..88b7794a 100644 --- a/docs/02-dynamic-routes.ipynb +++ b/docs/02-dynamic-routes.ipynb @@ -1,376 +1,453 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Dynamic Routes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In semantic-router there are two types of routes that can be chosen. Both routes belong to the `Route` object, the only difference between them is that _static_ routes return a `Route.name` when chosen, whereas _dynamic_ routes use an LLM call to produce parameter input values.\n", - "\n", - "For example, a _static_ route will tell us if a query is talking about mathematics by returning the route name (which could be `\"math\"` for example). A _dynamic_ route can generate additional values, so it may decide a query is talking about maths, but it can also generate Python code that we can later execute to answer the user's query, this output may look like `\"math\", \"import math; output = math.sqrt(64)`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Installing the Library" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!pip install -qU semantic-router==0.0.15" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "_**⚠️ If using Google Colab, install the prerequisites and then restart the notebook before continuing**_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Initializing Routes and RouteLayer" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Dynamic routes are treated in the same way as static routes, let's begin by initializing a `RouteLayer` consisting of static routes." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from semantic_router import Route\n", - "\n", - "politics = Route(\n", - " name=\"politics\",\n", - " utterances=[\n", - " \"isn't politics the best thing ever\",\n", - " \"why don't you tell me about your political opinions\",\n", - " \"don't you just love the president\" \"don't you just hate the president\",\n", - " \"they're going to destroy this country!\",\n", - " \"they will save the country!\",\n", - " ],\n", - ")\n", - "chitchat = Route(\n", - " name=\"chitchat\",\n", - " utterances=[\n", - " \"how's the weather today?\",\n", - " \"how are things going?\",\n", - " \"lovely weather today\",\n", - " \"the weather is horrendous\",\n", - " \"let's go to the chippy\",\n", - " ],\n", - ")\n", - "\n", - "routes = [politics, chitchat]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We initialize our `RouteLayer` with our `encoder` and `routes`. We can use popular encoder APIs like `CohereEncoder` and `OpenAIEncoder`, or local alternatives like `FastEmbedEncoder`." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ + "cells": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m2024-01-07 18:11:05 INFO semantic_router.utils.logger Initializing RouteLayer\u001b[0m\n" - ] - } - ], - "source": [ - "import os\n", - "from getpass import getpass\n", - "from semantic_router import RouteLayer\n", - "from semantic_router.encoders import CohereEncoder, OpenAIEncoder\n", - "\n", - "# dashboard.cohere.ai\n", - "# os.environ[\"COHERE_API_KEY\"] = os.getenv(\"COHERE_API_KEY\") or getpass(\n", - "# \"Enter Cohere API Key: \"\n", - "# )\n", - "# platform.openai.com\n", - "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") or getpass(\n", - " \"Enter OpenAI API Key: \"\n", - ")\n", - "\n", - "# encoder = CohereEncoder()\n", - "encoder = OpenAIEncoder()\n", - "\n", - "rl = RouteLayer(encoder=encoder, routes=routes)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We run the solely static routes layer:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ + "cell_type": "markdown", + "metadata": { + "id": "UxqB7_Ieur0s" + }, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/02-dynamic-routes.ipynb)" + ] + }, { - "data": { - "text/plain": [ - "RouteChoice(name='chitchat', function_call=None)" + "cell_type": "markdown", + "metadata": { + "id": "EduhQaNAur0u" + }, + "source": [ + "# Dynamic Routes" ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "rl(\"how's the weather today?\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Creating a Dynamic Route" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As with static routes, we must create a dynamic route before adding it to our route layer. To make a route dynamic, we need to provide a `function_schema`. The function schema provides instructions on what a function is, so that an LLM can decide how to use it correctly." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "from datetime import datetime\n", - "from zoneinfo import ZoneInfo\n", - "\n", - "\n", - "def get_time(timezone: str) -> str:\n", - " \"\"\"Finds the current time in a specific timezone.\n", - "\n", - " :param timezone: The timezone to find the current time in, should\n", - " be a valid timezone from the IANA Time Zone Database like\n", - " \"America/New_York\" or \"Europe/London\".\n", - " :type timezone: str\n", - " :return: The current time in the specified timezone.\"\"\"\n", - " now = datetime.now(ZoneInfo(timezone))\n", - " return now.strftime(\"%H:%M\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ + }, { - "data": { - "text/plain": [ - "'12:11'" + "cell_type": "markdown", + "metadata": { + "id": "_4JgNeX4ur0v" + }, + "source": [ + "In semantic-router there are two types of routes that can be chosen. Both routes belong to the `Route` object, the only difference between them is that _static_ routes return a `Route.name` when chosen, whereas _dynamic_ routes use an LLM call to produce parameter input values.\n", + "\n", + "For example, a _static_ route will tell us if a query is talking about mathematics by returning the route name (which could be `\"math\"` for example). A _dynamic_ route can generate additional values, so it may decide a query is talking about maths, but it can also generate Python code that we can later execute to answer the user's query, this output may look like `\"math\", \"import math; output = math.sqrt(64)`." ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "get_time(\"America/New_York\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To get the function schema we can use the `get_schema` function from the `function_call` module." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ + }, { - "data": { - "text/plain": [ - "{'name': 'get_time',\n", - " 'description': 'Finds the current time in a specific timezone.\\n\\n:param timezone: The timezone to find the current time in, should\\n be a valid timezone from the IANA Time Zone Database like\\n \"America/New_York\" or \"Europe/London\".\\n:type timezone: str\\n:return: The current time in the specified timezone.',\n", - " 'signature': '(timezone: str) -> str',\n", - " 'output': \"\"}" + "cell_type": "markdown", + "metadata": { + "id": "bbmw8CO4ur0v" + }, + "source": [ + "## Installing the Library" ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from semantic_router.utils.function_call import get_schema\n", - "\n", - "schema = get_schema(get_time)\n", - "schema" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We use this to define our dynamic route:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "time_route = Route(\n", - " name=\"get_time\",\n", - " utterances=[\n", - " \"what is the time in new york city?\",\n", - " \"what is the time in london?\",\n", - " \"I live in Rome, what time is it?\",\n", - " ],\n", - " function_schema=schema,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Add the new route to our `layer`:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ + }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m2024-01-07 18:11:20 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n" - ] - } - ], - "source": [ - "rl.add(time_route)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can ask our layer a time related question to trigger our new dynamic route." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "dLElfRhgur0v" + }, + "outputs": [], + "source": [ + "!pip install -qU semantic-router==0.0.15" + ] + }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[33m2024-01-07 18:11:23 WARNING semantic_router.utils.logger No LLM provided for dynamic route, will use OpenAI LLM default. Ensure API key is set in OPENAI_API_KEY environment variable.\u001b[0m\n", - "\u001b[32m2024-01-07 18:11:23 INFO semantic_router.utils.logger Extracting function input...\u001b[0m\n" - ] + "cell_type": "markdown", + "metadata": { + "id": "BixZd6Eour0w" + }, + "source": [ + "## Initializing Routes and RouteLayer" + ] }, { - "data": { - "text/plain": [ - "RouteChoice(name='get_time', function_call={'timezone': 'new york city'})" + "cell_type": "markdown", + "metadata": { + "id": "PxnW9qBvur0x" + }, + "source": [ + "Dynamic routes are treated in the same way as static routes, let's begin by initializing a `RouteLayer` consisting of static routes." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "kc9Ty6Lgur0x" + }, + "outputs": [], + "source": [ + "from semantic_router import Route\n", + "\n", + "politics = Route(\n", + " name=\"politics\",\n", + " utterances=[\n", + " \"isn't politics the best thing ever\",\n", + " \"why don't you tell me about your political opinions\",\n", + " \"don't you just love the president\" \"don't you just hate the president\",\n", + " \"they're going to destroy this country!\",\n", + " \"they will save the country!\",\n", + " ],\n", + ")\n", + "chitchat = Route(\n", + " name=\"chitchat\",\n", + " utterances=[\n", + " \"how's the weather today?\",\n", + " \"how are things going?\",\n", + " \"lovely weather today\",\n", + " \"the weather is horrendous\",\n", + " \"let's go to the chippy\",\n", + " ],\n", + ")\n", + "\n", + "routes = [politics, chitchat]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "voWyqmffur0x" + }, + "source": [ + "We initialize our `RouteLayer` with our `encoder` and `routes`. We can use popular encoder APIs like `CohereEncoder` and `OpenAIEncoder`, or local alternatives like `FastEmbedEncoder`." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "BI9AiDspur0y", + "outputId": "27329a54-3f16-44a5-ac20-13a6b26afb97", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\u001b[32m2024-01-08 11:12:24 INFO semantic_router.utils.logger Initializing RouteLayer\u001b[0m\n" + ] + } + ], + "source": [ + "import os\n", + "from getpass import getpass\n", + "from semantic_router import RouteLayer\n", + "from semantic_router.encoders import CohereEncoder, OpenAIEncoder\n", + "\n", + "# dashboard.cohere.ai\n", + "# os.environ[\"COHERE_API_KEY\"] = os.getenv(\"COHERE_API_KEY\") or getpass(\n", + "# \"Enter Cohere API Key: \"\n", + "# )\n", + "# platform.openai.com\n", + "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") or getpass(\n", + " \"Enter OpenAI API Key: \"\n", + ")\n", + "\n", + "# encoder = CohereEncoder()\n", + "encoder = OpenAIEncoder()\n", + "\n", + "rl = RouteLayer(encoder=encoder, routes=routes)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "GuLCeIS5ur0y" + }, + "source": [ + "We run the solely static routes layer:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "_rNREh7gur0y", + "outputId": "f3a1dc0b-d760-4efb-b634-d3547011dcb7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "RouteChoice(name='chitchat', function_call=None)" + ] + }, + "metadata": {}, + "execution_count": 4 + } + ], + "source": [ + "rl(\"how's the weather today?\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "McbLKO26ur0y" + }, + "source": [ + "## Creating a Dynamic Route" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ANAoEjxYur0y" + }, + "source": [ + "As with static routes, we must create a dynamic route before adding it to our route layer. To make a route dynamic, we need to provide a `function_schema`. The function schema provides instructions on what a function is, so that an LLM can decide how to use it correctly." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "5jaF1Xa5ur0y" + }, + "outputs": [], + "source": [ + "from datetime import datetime\n", + "from zoneinfo import ZoneInfo\n", + "\n", + "\n", + "def get_time(timezone: str) -> str:\n", + " \"\"\"Finds the current time in a specific timezone.\n", + "\n", + " :param timezone: The timezone to find the current time in, should\n", + " be a valid timezone from the IANA Time Zone Database like\n", + " \"America/New_York\" or \"Europe/London\". Do NOT put the place\n", + " name itself like \"rome\", or \"new york\", you must provide\n", + " the IANA format.\n", + " :type timezone: str\n", + " :return: The current time in the specified timezone.\"\"\"\n", + " now = datetime.now(ZoneInfo(timezone))\n", + " return now.strftime(\"%H:%M\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "YyFKV8jMur0z", + "outputId": "29cf80f4-552c-47bb-fbf9-019f5dfdf00a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + } + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'06:13'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 6 + } + ], + "source": [ + "get_time(\"America/New_York\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4qyaRuNXur0z" + }, + "source": [ + "To get the function schema we can use the `get_schema` function from the `function_call` module." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "tOjuhp5Xur0z", + "outputId": "ca88a3ea-d70a-4950-be9a-63fab699de3b", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'name': 'get_time',\n", + " 'description': 'Finds the current time in a specific timezone.\\n\\n:param timezone: The timezone to find the current time in, should\\n be a valid timezone from the IANA Time Zone Database like\\n \"America/New_York\" or \"Europe/London\". Do NOT put the place\\n name itself like \"rome\", or \"new york\", you must provide\\n the IANA format.\\n:type timezone: str\\n:return: The current time in the specified timezone.',\n", + " 'signature': '(timezone: str) -> str',\n", + " 'output': \"\"}" + ] + }, + "metadata": {}, + "execution_count": 7 + } + ], + "source": [ + "from semantic_router.utils.function_call import get_schema\n", + "\n", + "schema = get_schema(get_time)\n", + "schema" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HcF7jGjAur0z" + }, + "source": [ + "We use this to define our dynamic route:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "iesBG9P3ur0z" + }, + "outputs": [], + "source": [ + "time_route = Route(\n", + " name=\"get_time\",\n", + " utterances=[\n", + " \"what is the time in new york city?\",\n", + " \"what is the time in london?\",\n", + " \"I live in Rome, what time is it?\",\n", + " ],\n", + " function_schema=schema,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZiUs3ovpur0z" + }, + "source": [ + "Add the new route to our `layer`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "-0vY8PRXur0z", + "outputId": "db01e14c-eab3-4f93-f4c2-e30f508c8b5d", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\u001b[32m2024-01-08 11:15:26 INFO semantic_router.utils.logger Adding `get_time` route\u001b[0m\n" + ] + } + ], + "source": [ + "rl.add(time_route)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7yoE0IrNur0z" + }, + "source": [ + "Now we can ask our layer a time related question to trigger our new dynamic route." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "id": "Wfb68M0-ur0z", + "outputId": "79923883-2a4d-4744-f8ce-e818cb5f14c3", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 53 + } + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\u001b[32m2024-01-08 11:16:24 INFO semantic_router.utils.logger Extracting function input...\u001b[0m\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "'06:16'" + ], + "application/vnd.google.colaboratory.intrinsic+json": { + "type": "string" + } + }, + "metadata": {}, + "execution_count": 11 + } + ], + "source": [ + "out = rl(\"what is the time in new york city?\")\n", + "get_time(**out.function_call)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Qt0vkq2Xur00" + }, + "source": [ + "Our dynamic route provides both the route itself _and_ the input parameters required to use the route." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J0oD1dxIur00" + }, + "source": [ + "---" ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" } - ], - "source": [ - "# https://platform.openai.com/\n", - "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\") or getpass(\n", - " \"Enter OpenAI API Key: \"\n", - ")\n", - "\n", - "rl(\"what is the time in new york city?\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Our dynamic route provides both the route itself _and_ the input parameters required to use the route." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "decision-layer", - "language": "python", - "name": "python3" + ], + "metadata": { + "kernelspec": { + "display_name": "decision-layer", + "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.5" + }, + "colab": { + "provenance": [] + } }, - "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.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/03-basic-langchain-agent.ipynb b/docs/03-basic-langchain-agent.ipynb index c8c48b3d..dc728495 100644 --- a/docs/03-basic-langchain-agent.ipynb +++ b/docs/03-basic-langchain-agent.ipynb @@ -83,15 +83,6 @@ " openai==1.6.1" ] }, - { - "cell_type": "markdown", - "metadata": { - "id": "cHtVnoJPA04x" - }, - "source": [ - "_**⚠️ If using Google Colab, install the prerequisites and then restart the notebook before continuing**_" - ] - }, { "cell_type": "markdown", "metadata": { diff --git a/docs/04-chat-history.ipynb b/docs/04-chat-history.ipynb new file mode 100644 index 00000000..4ac533b1 --- /dev/null +++ b/docs/04-chat-history.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/aurelio-labs/semantic-router/blob/main/docs/00-introduction.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/aurelio-labs/semantic-router/blob/main/docs/00-introduction.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Considering Chat History" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Applying semantic-router to the most recent interaction in a conversation can work for many cases but it misses scenarios where information provided in the latest interaction." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/jamesbriggs/opt/anaconda3/envs/decision-layer/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n", + "100%|██████████| 83.2M/83.2M [00:09<00:00, 8.45MiB/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "{'split 1': ['User: Hello! Can you tell me the latest news headlines?',\n", + " 'Bot: Hi! Sure, here are the top news headlines for today...'],\n", + " 'split 2': [\"User: That's quite interesting. I'm also looking for some new music to listen to.\",\n", + " 'Bot: What genre do you prefer?',\n", + " 'User: I like pop music.',\n", + " 'Bot: You might enjoy the latest album by Dua Lipa.',\n", + " \"User: I'll give it a listen. Also, I'm planning a trip and need some travel tips.\",\n", + " 'Bot: Sure, where are you planning to go?'],\n", + " 'split 3': [\"User: I'm thinking of visiting Italy.\",\n", + " 'Bot: Italy is a beautiful country. Make sure to visit the Colosseum in Rome and the canals in Venice.'],\n", + " 'split 4': ['User: Those sound like great suggestions. I also need some help with my diet.',\n", + " 'Bot: What kind of diet are you following?',\n", + " \"User: I'm trying to eat more protein.\",\n", + " 'Bot: Include lean meats, eggs, and legumes in your diet for a protein boost.',\n", + " \"User: Thanks for the tips! I'll talk to you later.\",\n", + " \"Bot: You're welcome! Don't hesitate to reach out if you need more help.\",\n", + " 'User: I appreciate it. Goodbye!',\n", + " 'Bot: Goodbye! Take care!']}" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from semantic_router.schema import Conversation, Message\n", + "from semantic_router.encoders import FastEmbedEncoder\n", + "\n", + "\n", + "messages = [\n", + " \"User: Hello! Can you tell me the latest news headlines?\",\n", + " \"Bot: Hi! Sure, here are the top news headlines for today...\",\n", + " \"User: That's quite interesting. I'm also looking for some new music to listen to.\",\n", + " \"Bot: What genre do you prefer?\",\n", + " \"User: I like pop music.\",\n", + " \"Bot: You might enjoy the latest album by Dua Lipa.\",\n", + " \"User: I'll give it a listen. Also, I'm planning a trip and need some travel tips.\",\n", + " \"Bot: Sure, where are you planning to go?\",\n", + " \"User: I'm thinking of visiting Italy.\",\n", + " \"Bot: Italy is a beautiful country. Make sure to visit the Colosseum in Rome and the canals in Venice.\",\n", + " \"User: Those sound like great suggestions. I also need some help with my diet.\",\n", + " \"Bot: What kind of diet are you following?\",\n", + " \"User: I'm trying to eat more protein.\",\n", + " \"Bot: Include lean meats, eggs, and legumes in your diet for a protein boost.\",\n", + " \"User: Thanks for the tips! I'll talk to you later.\",\n", + " \"Bot: You're welcome! Don't hesitate to reach out if you need more help.\",\n", + " \"User: I appreciate it. Goodbye!\",\n", + " \"Bot: Goodbye! Take care!\",\n", + "]\n", + "\n", + "encoder = FastEmbedEncoder(model_name=\"sentence-transformers/all-MiniLM-L6-v2\")\n", + "\n", + "convo = Conversation(\n", + " messages=[\n", + " Message(role=m.split(\": \")[0], content=m.split(\": \")[1]) for m in messages\n", + " ]\n", + ")\n", + "\n", + "convo.split_by_topic(\n", + " encoder=encoder, threshold=0.72, split_method=\"cumulative_similarity_drop\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "ml", + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}